Back to Ib Api Reloaded

ib_async

ib-underscore-async-readme.md

latest16.2 KB
Original Source

ib_async

Update

Introduction

ib_async is a Python library that provides a clean, modern interface to Interactive Brokers’ Trader Workstation (TWS) and IB Gateway. It handles the complexities of the IBKR API so you can focus on building trading applications, research tools, and market data analysis.

What You Can Build

  • Market Data Applications : Stream live quotes, historical data, and market depth

  • Trading Systems : Place, modify, and monitor orders programmatically

  • Portfolio Tools : Track positions, account balances, and P&L in real-time

  • Research Platforms : Analyze contract details, option chains, and fundamental data

  • Risk Management : Monitor exposures and implement automated controls

Key Features

  • Simple and Intuitive : Write straightforward Python code without dealing with callback complexity

  • Automatic Synchronization : The IB component stays in sync with TWS/Gateway automatically

  • Async-Ready : Built on asyncio and eventkit for high-performance applications

  • Jupyter-Friendly : Interactive development with live data in notebooks

  • Production-Ready : Robust error handling, reconnection logic, and comprehensive logging

Be sure to take a look at the notebooks, the recipes and the API docs.

Installation

pipinstallib\_async

Requirements:

  • Python 3.10 or higher

  • A running IB Gateway application (or TWS with API mode enabled)

  • Make sure the API port is enabled and ‘Download open orders on connection’ is checked.

  • You may also want to increase the Java memory usage under Configure->Settings->Memory Allocation to 4096 MB minimum to prevent gateway crashes when loading bulk data.

The ibapi package from IB is not needed. ib_async implements the full IBKR API binary protocol internally.

Build Manually

First, install poetry:

pipinstallpoetry-U

Installing Only Library

poetryinstall

Install Everything (enable docs + dev testing)

poetryinstall--with=docs,dev

Generate Docs

poetryinstall--with=docspoetryrunsphinx-build-bhtmldocshtml

Check Types

poetryrunmypyib\_async

Build Package

poetrybuild

Upload Package (if maintaining)

poetryinstallpoetryconfigpypi-token.pypiyour-api-tokenpoetrypublish--build

Setup Interactive Brokers

1. Download IB Gateway or TWS

2. Configure API Access

  1. Enable API : Go to Configure → API → Settings and check “Enable ActiveX and Socket Clients”

  2. Set Port : Default ports are 7497 (TWS) and 4001 (Gateway). You can change these if needed.

  3. Allow Connections : Add 127.0.0.1 to “Trusted IPs” if connecting locally

  4. Download Orders : Check “Download open orders on connection” to see existing orders

3. Performance Settings

  • Memory : Go to Configure → Settings → Memory Allocation and set to 4096 MB minimum to prevent crashes with bulk data

  • Timeouts : Increase API timeout settings if you experience disconnections during large data requests

4. Common Connection Issues

Connection Refused

# Make sure TWS/Gateway is running and API is enabled# Check that ports match (7497 for TWS, 4001 for Gateway)ib.connect('127.0.0.1',7497,clientId=1)# TWSib.connect('127.0.0.1',4001,clientId=1)# Gateway

Client ID Conflicts

# Each connection needs a unique client IDib.connect('127.0.0.1',7497,clientId=1)# Use different numbers for multiple connections

Market Data Issues

# For free delayed data (no subscription required)ib.reqMarketDataType(3)# Delayedib.reqMarketDataType(4)# Delayed frozen# For real-time data (requires subscription)ib.reqMarketDataType(1)# Real-time

Connection Patterns

Basic Script Usage

from ib\_async import\*ib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Your code hereib.disconnect()

Jupyter Notebook Usage

from ib\_async import\*util.startLoop()# Required for notebooksib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Your code here - no need to call ib.run()

Async Application

import asynciofrom ib\_async import\*asyncdef main():ib=IB()awaitib.connectAsync('127.0.0.1',7497,clientId=1)# Your async code hereib.disconnect()asyncio.run(main())

Quick Start

Basic Connection

from ib\_async import\*# Connect to TWS or IB Gatewayib=IB()ib.connect('127.0.0.1',7497,clientId=1)print("Connected")# Disconnect when doneib.disconnect()

Get Account Information

from ib\_async import\*ib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Get account summaryaccount=ib.managedAccounts()[0]summary=ib.accountSummary(account)foriteminsummary:print(f"{item.tag}: {item.value}")ib.disconnect()

Historical Data

from ib\_async import\*# util.startLoop() # uncomment this line when in a notebookib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Request historical datacontract=Forex('EURUSD')bars=ib.reqHistoricalData(contract,endDateTime='',durationStr='30 D',barSizeSetting='1 hour',whatToShow='MIDPOINT',useRTH=True)# Convert to pandas dataframe (pandas needs to be installed):df=util.df(bars)print(df.head())ib.disconnect()

Live Market Data

from ib\_async import\*import timeib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Subscribe to live market datacontract=Stock('AAPL','SMART','USD')ticker=ib.reqMktData(contract,'',False,False)# Print live quotes for 30 secondsforiinrange(30):ib.sleep(1)# Wait 1 secondifticker.last:print(f"AAPL: ${ticker.last} (bid: ${ticker.bid}, ask: ${ticker.ask})")ib.disconnect()

Place a Simple Order

from ib\_async import\*ib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Create a contract and ordercontract=Stock('AAPL','SMART','USD')order=MarketOrder('BUY',100)# Place the ordertrade=ib.placeOrder(contract,order)print(f"Order placed: {trade}")# Monitor order statuswhilenottrade.isDone():ib.sleep(1)print(f"Order status: {trade.orderStatus.status}")ib.disconnect()

More Complete Examples

Portfolio Monitoring

from ib\_async import\*ib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Get current positionspositions=ib.positions()print("Current Positions:")forposinpositions:print(f"{pos.contract.symbol}: {pos.position} @ {pos.avgCost}")# Get open ordersorders=ib.openTrades()print(f"\nOpen Orders: {len(orders)}")fortradeinorders:print(f"{trade.contract.symbol}: {trade.order.action} {trade.order.totalQuantity}")ib.disconnect()

Real-time P&L Tracking

from ib\_async import\*def onPnL(pnl):print(f"P&L Update: Unrealized: ${pnl.unrealizedPnL:.2f}, Realized: ${pnl.realizedPnL:.2f}")ib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Subscribe to P&L updatesaccount=ib.managedAccounts()[0]pnl=ib.reqPnL(account)pnl.updateEvent+=onPnL# Keep running to receive updatestry:ib.run()# Run until interruptedexceptKeyboardInterrupt:ib.disconnect()

Advanced Order Management

from ib\_async import\*ib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Create a bracket order (entry + stop loss + take profit)contract=Stock('TSLA','SMART','USD')# Parent orderparent=LimitOrder('BUY',100,250.00)parent.orderId=ib.client.getReqId()parent.transmit=False# Stop lossstopLoss=StopOrder('SELL',100,240.00)stopLoss.orderId=ib.client.getReqId()stopLoss.parentId=parent.orderIdstopLoss.transmit=False# Take profittakeProfit=LimitOrder('SELL',100,260.00)takeProfit.orderId=ib.client.getReqId()takeProfit.parentId=parent.orderIdtakeProfit.transmit=True# Place bracket ordertrades=[]trades.append(ib.placeOrder(contract,parent))trades.append(ib.placeOrder(contract,stopLoss))trades.append(ib.placeOrder(contract,takeProfit))print(f"Bracket order placed: {len(trades)} orders")ib.disconnect()

Historical Data Analysis

from ib\_async import\*import pandas as pdib=IB()ib.connect('127.0.0.1',7497,clientId=1)# Get multiple timeframescontract=Stock('SPY','SMART','USD')# Daily bars for 1 yeardaily\_bars=ib.reqHistoricalData(contract,endDateTime='',durationStr='1 Y',barSizeSetting='1 day',whatToShow='TRADES',useRTH=True)# 5-minute bars for last 5 daysintraday\_bars=ib.reqHistoricalData(contract,endDateTime='',durationStr='5 D',barSizeSetting='5 mins',whatToShow='TRADES',useRTH=True)# Convert to DataFramesdaily\_df=util.df(daily\_bars)intraday\_df=util.df(intraday\_bars)print(f"Daily bars: {len(daily\_df)} rows")print(f"Intraday bars: {len(intraday\_df)} rows")# Calculate simple moving averagedaily\_df['SMA\_20']=daily\_df['close'].rolling(20).mean()print(daily\_df[['date','close','SMA\_20']].tail())ib.disconnect()

Library Structure

Core Components

ib_async.ib.IB - Main interface class

  • Connection management (connect(), disconnect(), connectAsync())

  • Market data requests (reqMktData(), reqHistoricalData())

  • Order management (placeOrder(), cancelOrder())

  • Account data (positions(), accountSummary(), reqPnL())

ib_async.contract - Financial instruments

  • Stock, Option, Future, Forex, Index, Bond

  • Contract - Base class for all instruments

  • ComboLeg, DeltaNeutralContract - Complex instruments

ib_async.order - Order types and management

  • MarketOrder, LimitOrder, StopOrder, StopLimitOrder

  • Order - Base order class with all parameters

  • OrderStatus, OrderState - Order execution tracking

  • Trade - Complete order lifecycle tracking

ib_async.ticker - Real-time market data

  • Ticker - Live quotes, trades, and market data

  • Automatic field updates (bid, ask, last, volume, etc.)

  • Event-driven updates via updateEvent

ib_async.objects - Data structures

  • BarData - Historical price bars

  • Position - Portfolio positions

  • PortfolioItem - Portfolio details with P&L

  • AccountValue - Account metrics

Key Patterns

Synchronous vs Asynchronous

# Synchronous (blocks until complete)bars=ib.reqHistoricalData(contract,...)# Asynchronous (yields to event loop)bars=awaitib.reqHistoricalDataAsync(contract,...)

Event Handling

# Subscribe to eventsdef onOrderUpdate(trade):print(f"Order update: {trade.orderStatus.status}")ib.orderStatusEvent+=onOrderUpdate# Or with asyncasyncdef onTicker(ticker):print(f"Price update: {ticker.last}")ticker.updateEvent+=onTicker

Error Handling

try:ib.connect('127.0.0.1',7497,clientId=1)exceptConnectionRefusedError:print("TWS/Gateway not running or API not enabled")exceptExceptionase:print(f"Connection error: {e}")

Documentation

The complete API documentation.

Changelog.

Development

Running Tests

poetry install --with=dev
poetry run pytest

Type Checking

poetry run mypy ib_async

Code Formatting

poetry run ruff format
poetry run ruff check --fix

Local Development

  1. Clone the repository:
git clone https://github.com/ib-api-reloaded/ib_async.gitcd ib_async
  1. Install dependencies:
poetry install --with=dev,docs
  1. Make your changes and run tests:
poetry run pytest
poetry run mypy ib_async
  1. Submit a pull request with:

Contributing Guidelines

  • Follow existing code style (enforced by ruff)

  • Add tests for new features

  • Update documentation for user-facing changes

  • Keep commits focused and well-described

  • Be responsive to code review feedback

Community Resources

If you have other public work related to ib_async or ib_insync open an issue and we can keep an active list here.

Projects below are not endorsed by any entity and are purely for reference or entertainment purposes.

Disclaimer

The software is provided on the conditions of the simplified BSD license.

This project is not affiliated with Interactive Brokers Group, Inc.

Official Interactive Brokers API Docs

History

This library was originally created by Ewald de Wit as tws_async in early-2017 then became the more prominent ib_insync library in mid-2017. He maintained and improved the library for the world to use for free until his unexpected passing in early 2024. Afterward, we decided to rename the project to ib_async under a new github organization since we lost access to modify anything in the original repos and packaging and docs infrastructure.

The library is currently maintained by Matt Stancliff and we are open to adding more committers and org contributors if people show interest in helping out.