ib_async

repository·main·Indexed 23 days ago

https://github.com/ib-api-reloaded/ib_async

A modern Python sync/async framework for the Interactive Brokers API (version 2.1.0). It provides an asynchronous interface to TWS and IB Gateway using asyncio, implementing the full IBKR API binary protocol internally. The library supports trading automation, market data analysis, and portfolio management with features for historical data retrieval, live market data subscriptions, order placement (including bracket orders), and P&L monitoring.

Tokens
23.9K
Snippets
48
Records
136
Agent score
82%

What's inside ib_async

  1. Connect to IBKR in different environments

    main

    Depending on your execution environment, use the appropriate connection pattern:

    Basic Script

    Standard synchronous-style usage for scripts.

    Jupyter Notebook

    Requires calling util.startLoop() to handle the event loop in an interactive environment.

    Async Application

    Use await ib.connectAsync(...) within an asyncio event loop for high-performance asynchronous applications.

    # Basic Script
    from ib_async import *
    
    ib = IB()
    ib.connect('127.0.0.1', 7497, clientId=1)
    # ... code ...
    ib.disconnect()
    
    # Jupyter Notebook
    from ib_async import *
    util.startLoop()
    
    ib = IB()
    ib.connect('127.0.0.1', 7497, clientId=1)
    
    # Async Application
    import asyncio
    from ib_async import *
    
    async def main():
        ib = IB()
        await ib.connectAsync('127.0.0.1', 7497, clientId=1)
        # ... code ...
        ib.disconnect()
    
    asyncio.run(main())
  2. Handle events with callbacks in ib_async

    main

    You can subscribe to events to react to order updates or market data changes. The library supports both standard function callbacks and asynchronous callbacks.

    Standard Callback Example:

    def onOrderUpdate(trade):
        print(f"Order update: {trade.orderStatus.status}")
    
    ib.orderStatusEvent += onOrderUpdate

    Asynchronous Callback Example:

    async def onTicker(ticker):
        print(f"Price update: {ticker.last}")
    
    ticker.updateEvent += onTicker
    # Subscribe to events
    def onOrderUpdate(trade):
        print(f"Order update: {trade.orderStatus.status}")
    
    ib.orderStatusEvent += onOrderUpdate
    
    # Or with async
    async def onTicker(ticker):
        print(f"Price update: {ticker.last}")
    
    ticker.updateEvent += onTicker
  3. Manage orders and track execution with ib_async.order

    main

    The ib_async.order module provides classes for defining order parameters and tracking their lifecycle.

    Key Components:

    • Order Types: MarketOrder, LimitOrder, StopOrder, and StopLimitOrder.
    • Tracking: Use Order (base class) for parameters, OrderStatus and OrderState for execution tracking, and Trade to track the complete order lifecycle.
  4. Define financial instruments using ib_async.contract

    main

    All financial instruments in ib_async are derived from the Contract base class. Use the specific subclasses to define the assets you wish to trade or monitor.

    Supported Instrument Types:

    • Stock
    • Option
    • Future
    • Forex
    • Index
    • Bond
    • ComboLeg and DeltaNeutralContract for complex/multi-leg instruments.
  5. Use Synchronous vs Asynchronous patterns in ib_async

    main

    The library supports both blocking (synchronous) and non-blocking (asynchronous) patterns. Use the Async suffix on methods when you want to yield to the event loop.

    Synchronous (blocks until complete):

    # Synchronous
    bars = ib.reqHistoricalData(contract, ...)

    Asynchronous (yields to event loop):

    # Asynchronous
    bars = await ib.reqHistoricalDataAsync(contract, ...)
    # Synchronous (blocks until complete)
    bars = ib.reqHistoricalData(contract, ...)
    
    # Asynchronous (yields to event loop)
    bars = await ib.reqHistoricalDataAsync(contract, ...)
  6. Install ib_async via pip

    main

    To install the ib_async library, use the following command. This library implements the full IBKR API binary protocol internally, so the official ibapi package is not required.

    Requirements:

    • Python 3.10 or higher
    • A running IB Gateway or TWS application with API enabled.
    • API port enabled and 'Download open orders on connection' checked in TWS/Gateway settings.
    pip install ib_async
  7. Configure Interactive Brokers for API access

    main

    Before using ib_async, you must configure your IB Gateway or TWS instance:

    1. Enable API: Navigate to Configure → API → Settings and check "Enable ActiveX and Socket Clients".
    2. Set Port: Note the port (Default: 7497 for TWS, 4001 for Gateway).
    3. Allow Connections: Add 127.0.0.1 to "Trusted IPs" for local connections.
    4. Download Orders: Check "Download open orders on connection".
    5. Memory Allocation: For bulk data, go to Configure → Settings → Memory Allocation and set to at least 4096 MB to prevent crashes.
  8. Use ib_async in Jupyter Notebooks

    main
    You can use ib_async in a fully interactive and exploratory manner using Jupyter notebooks to work with live market data. The project provides several recipe notebooks covering common use cases such as basics, contract details, option chains, bar data, tick data, market depth, ordering, and scanners.
  9. Handle short-lived connections correctly

    main

    The IB socket protocol is designed for long-lived connections. If you are using the API for short-lived tasks (e.g., firing a few orders and exiting), add a small delay (e.g., ib.sleep(1)) before calling ib.disconnect(). This ensures that any pending data in the buffer is flushed and sent to the server before the connection closes.

    ib = IB()
    ib.connect()
    
    ...  # create and submit some orders
    
    ib.sleep(1)  # added delay
    ib.disconnect()
  10. Handle connection errors in ib_async

    main

    When connecting to TWS or IB Gateway, wrap your connection logic in a try-except block to handle common issues like the API not being enabled or the service not running.

    try:
        ib.connect('127.0.0.1', 7497, clientId=1)
    except ConnectionRefusedError:
        print("TWS/Gateway not running or API not enabled")
    except Exception as e:
        print(f"Connection error: {e}")
  11. Work with tick data and market depth

    main

    The library provides several NamedTuple structures for high-frequency data:

    • TickData: Basic time, tickType, price, and size.
    • HistoricalTick: Historical time, price, and size.
    • HistoricalTickBidAsk: Historical bid/ask data including priceBid, priceAsk, sizeBid, sizeAsk, and tickAttribBidAsk.
    • TickByTickBidAsk: Real-time bid/ask data including bidPrice, askPrice, bidSize, askSize, and tickAttribBidAsk.
    • MktDepthData: Market depth information including time, position, marketMaker, operation, side, price, and size.
    • DOMLevel: A single level of the Depth of Market (DOM) with price, size, and marketMaker.