ib_insync
repository·master·Indexed 25 days ago
https://github.com/erdewit/ib_insyncA Python library designed to simplify working with the Interactive Brokers Trader Workstation (TWS) API. It provides a linear programming style and an asynchronous framework based on asyncio to keep data in sync with TWS or IB Gateway. The library supports interactive development in Jupyter notebooks and includes functionality for downloading historical data, requesting scanner data, calculating option implied volatility, accessing market depth, and managing orders.
What's inside ib_insync
- IB-insync supports fully interactive and exploratory development using live data within Jupyter notebooks. You can use various recipe notebooks to learn how to handle specific tasks such as contract details, option chains, market data, and ordering.
Fetch consecutive historical data
masterTo fetch a continuous stream of historical data (e.g., 1-minute bars) from a specific point in time back to the beginning, use a
whileloop. Start with the current time and use theendDateTimeparameter inreqHistoricalDatato request data in chunks, updating theendDateTimewith the date of the earliest bar received in the previous request until no more data is returned.import datetime from ib_insync import * ib = IB() ib.connect('127.0.0.1', 7497, clientId=1) contract = Stock('TSLA', 'SMART', 'USD') dt = '' barsList = [] while True: bars = ib.reqHistoricalData( contract, endDateTime=dt, durationStr='10 D', barSizeSetting='1 min', whatToShow='MIDPOINT', useRTH=True, formatDate=1) if not bars: break barsList.append(bars) dt = bars[0].date print(dt) # save to CSV file allBars = [b for bars in reversed(barsList) for b in bars] df = util.df(allBars) df.to_csv(contract.symbol + '.csv', index=False)Handle short-lived connections gracefully
masterThe IB socket protocol is designed for long-lived connections. If you are using the library for short-lived tasks (e.g., firing a few orders and exiting), add a small delay (e.g.,
ib.sleep(1)) before callingib.disconnect(). This ensures that any pending data in the buffer is flushed to the server.ib = IB() ib.connect() ... # create and submit some orders ib.sleep(1) # added delay ib.disconnect()Use ib_insync in Jupyter Notebooks
masterWhen runningib_insynccode within a Jupyter notebook, you must callutil.startLoop()to ensure the asynchronous event loop is running correctly within the notebook environment.Install ib_insync
masterInstall the library using pip:
pip install ib_insyncRequirements
- Python 3.6 or higher
- A running TWS (Trader Workstation) or IB Gateway application (version 1023 or higher).
- The API port must be enabled in your TWS/IB Gateway settings.
- 'Download open orders on connection' must be checked in your TWS/IB Gateway settings.
Note: The official
ibapipackage from Interactive Brokers is not required.Prefer current state methods over requests
masterTo improve performance, use 'current state' methods instead of 'request' methods. Request methods (prefixed with
req) involve network round-trips and are slower, whereas current state methods (e.g.,ib.positions()) access data already synchronized in memory and are available immediately.Examples:
- Use
ib.positions()instead ofib.reqPositions() - Use
ib.openOrders()instead ofib.reqOpenOrders()
- Use
Setup ib_insync in Jupyter Notebooks
masterTo use
ib_insyncin a Jupyter Notebook, import all members and start the event loop usingutil.startLoop(). This ensures the notebook remains live-updated with data from the IB API.Note:
util.startLoop()is designed specifically for notebooks and will not work in regular Python scripts.from ib_insync import * util.startLoop()Get live updates for historical bars
masterTo receive live updates for a historical data subscription, call
ib.reqHistoricalDatawithendDateTime=''andkeepUpToDate=True.You can subscribe to updates by attaching a callback function to the
updateEventof the returned bars object. The callback receives(bars, hasNewBar).Warning: Using
keepUpToDate=Truemay cause the API to become inoperable if a network interruption occurs.contract = Forex('EURUSD') # Request bars with keepUpToDate enabled bars = ib.reqHistoricalData( contract, endDateTime='', durationStr='900 S', barSizeSetting='10 secs', whatToShow='MIDPOINT', useRTH=True, formatDate=1, keepUpToDate=True) def onBarUpdate(bars, hasNewBar): print(f"New bar: {bars[-1]}") # Subscribe to updates bars.updateEvent += onBarUpdate # To stop the subscription ib.cancelHistoricalData(bars)Connect to TWS or IB Gateway
masterUse the
IBclass to establish a connection to a running Trader Workstation (TWS) or IB Gateway application.Troubleshooting Connection Failures:
- Verify that the API port is enabled in your TWS/IBG settings.
- Double-check the hostname and port.
- For IB Gateway, the default port is typically
4002. - Ensure the
clientIdprovided is not already in use by another session.
ib = IB() ib.connect('127.0.0.1', 7497, clientId=10)Construct and qualify multiple option contracts
masterOnce you have an option chain, you can programmatically build a list of
Optioncontracts based on specific criteria like strike price increments, expiration dates, and rights ('P' for Put, 'C' for Call). After creating the list ofOptionobjects, useib.qualifyContracts(*contracts)to fill in missing details likeconIdand ensure they are valid for trading.# Example: Building contracts based on filtered strikes and expirations strikes = [strike for strike in chain.strikes if strike % 5 == 0] expirations = sorted(chain.expirations)[:3] rights = ['P', 'C'] contracts = [Option('SPX', expiration, strike, right, 'SMART', tradingClass='SPX') for right in rights for expiration in expirations for strike in strikes] # Qualify the contracts contracts = ib.qualifyContracts(*contracts)Configure ib_insync requirements
masterTo use
ib_insync, ensure you meet the following requirements:- Python: Version 3.6 or higher.
- TWS or IB Gateway: A running instance of Trader Workstation (TWS) or IB Gateway (version 1023 or higher).
- API Settings:
- The API port must be enabled in your TWS/Gateway settings.
- The option 'Download open orders on connection' must be checked.
Note: The official
ibapipackage from Interactive Brokers is not required.Connect to IB via ib_insync
masterTo start using
ib_insync, initialize theIBobject, start the event loop usingutil.startLoop(), and connect to your IB gateway or TWS instance.Warning: Using live accounts will place real orders. It is recommended to use a paper trading account during testing.
from ib_insync import * util.startLoop() ib = IB() ib.connect('127.0.0.1', 7497, clientId=13)