ibcore
Standalone Rust crate for integrating with Interactive Brokers TWS and IB Gateway.
Wraps ibapi v3.0 with a clean async API, typed errors, market data
snapshots, option chain resolution, and diagnostic event broadcasting.
Why ibcore?
The IB API has quirks. ibcore smooths them over:
| Raw ibapi | ibcore |
|---|---|
| Numeric error codes with inconsistent docs | Typed IbError::FarmDisconnect |
| Error codes in notice stream | tokio::sync::broadcast of DiagnosticEvent |
| Manual contract construction | build_option_contract, get_primary_exchange |
| No structured disconnect detection | is_connection_dead() for reconnect logic |
Raw TickType decoding |
StockSnapshot / OptionSnapshot with Greeks |
ibcore is built from production experience running automated options trading against IBKR. Every reconnect edge case, every data farm quirk, every undocumented behavior discovered in live trading is handled here.
Quick Start
Rust
Prerequisites
- Rust 1.85+ (edition 2024)
- IB Gateway or TWS running with API enabled
Installation
Connect and get a stock snapshot
use ;
async
Get an option chain
use IbClient;
let chain = ib.fetch_option_chain.await?;
println!;
println!;
Get an option snapshot with Greeks
use IbClient;
let snap = ib.option_snapshot.await?;
println!;
Subscribe to live market data ticks
use StreamExt;
let contract = stock.build;
let mut stream = ib.tick_stream.await?;
while let Some = stream.next.await
Fetch historical OHLCV bars
let contract = stock.build;
let data = ib.historical_data.await?;
println!;
for bar in &data.bars
Monitor diagnostic events
use task;
let mut rx = ib.diagnostic_events;
let watcher = spawn;
Python
ibcore is also available as a Python package via PyO3 bindings.
Prerequisites
- Python 3.9+
- Rust toolchain (for maturin build)
Installation
Connect and get a stock snapshot
=
=
Get an option snapshot with Greeks
=
Place an order
=
Build from source
&& &&
CLI Tool
ibcore ships a diagnostic CLI tool for Gateway health checks:
# Build from source
# Check versions
# Run a 10-second diagnostic against local Gateway
# JSON output for scripting
|
API Overview
IbClient
| Method | Returns | Description |
|---|---|---|
connect(host, port, client_id, market_data_type, account_type) |
Result<IbClient, IbError> |
Connect to IB Gateway with typed config |
disconnect() |
() |
Graceful disconnect |
stock_snapshot(symbol) |
Result<StockSnapshot, IbError> |
One-shot bid/ask/last/volume |
option_snapshot(symbol, expiry, strike, right) |
Result<OptionSnapshot, IbError> |
Bid/ask/last + Greeks (delta, gamma, theta, vega, iv) |
fetch_option_chain(symbol) |
Result<OptionChainData, IbError> |
All expirations + all strikes |
positions() |
Result<Vec<Position>, IbError> |
Current positions |
account_summary(tag, currency) |
Result<Vec<AccountSummaryResult>, IbError> |
NetLiq, GrossPosValue, etc. |
pnl(account_id, model_code) |
Result<PnL, IbError> |
Realized + unrealized P&L |
net_liquidation(account_id, currency) |
Result<f64, IbError> |
Single net liquidation value |
diagnostic_events() |
broadcast::Receiver<DiagnosticEvent> |
Subscribe to structured diagnostic events |
server_version() |
i32 |
Gateway server version |
tick_stream(contract) |
Result<TickStream, IbError> |
Subscribe to live market data ticks |
historical_data(contract, bar_size, duration, what_to_show, trading_hours) |
Result<HistoricalData, IbError> |
One-shot historical OHLCV bars |
DiagnosticEvent
Emitted on every IB error/warning notice:
Subscribe with ib.diagnostic_events() and process asynchronously.
Buffer size is 256 events; slow subscribers will miss old events.
IbError
Typed error variants — no raw error codes in your business logic:
| Variant | Trigger | Typical IB codes |
|---|---|---|
ConnectionFailed |
Can't connect | 502, 504, 506 |
ConnectionReset |
TCP reset | 507, 100 |
Timeout |
IO timeout | — |
MarketData |
Data subscription error | 10000–10999 |
FarmDisconnect |
Data farm offline | 2107 |
CompetingSession |
Live session blocks paper | 10197 |
OrderRejected |
Order invalid | 200–299 |
ContractResolution |
Contract not found | — |
Other |
Unclassified | everything else |
Helper functions
| Function | Description |
|---|---|
build_option_contract(symbol, expiry, strike, right) |
Construct IB Contract for options |
get_primary_exchange(symbol) |
Map symbol to exchange (SPY→CBOE, TLT→SMART) |
parse_expiry(date_str) |
Parse "20260717" to NaiveDate |
is_connection_dead(&IbError) |
Check if error means the connection is gone |
classify_farm(error_code) |
Map IB error code to FarmState |
Reconnection
ibcore does NOT auto-reconnect. It gives you the tools to decide:
loop
This is deliberate. Your reconnect strategy depends on your trading logic. ibcore tells you WHAT went wrong; you decide HOW to recover.
Setup
IB Gateway (Docker)
IB Gateway (manual)
- Download IB Gateway from IBKR
- Configure: API → Enable ActiveX and Socket Clients → Port 4002
- Check "Download open orders on connection"
- Start Gateway and log in
Verify connectivity
# Check Gateway is listening
# Run ibcore tests (requires Gateway)
Design Philosophy
- Wrap, don't re-implement. ibcore wraps
ibapiv3.0, adding ergonomics and safety on top. All wire-protocol details stay inibapi. - Type errors, don't propagate codes.
IbErroris exhaustive. If you match on it, you handle every failure mode the Gateway can produce. - Observe, don't guess. The
DiagnosticEventbroadcast channel lets you monitor Gateway health without polling. Multiple consumers can subscribe independently. - No business logic. ibcore knows about IBKR, not about trading strategies. Position tracking, portfolio allocation, risk management — those belong in your application layer.
Python Bindings
ibcore ships PyO3 Python bindings in the python/ workspace crate (ibcore-python).
Build the shared library with:
# Requires Python 3.7+ and Rust 1.85+
PYO3_PYTHON=
The resulting .so file is at target/release/libibcore_python.so.
Usage
# Connect to paper trading Gateway
= await
# Stock snapshot
= await
# Option snapshot
= await
# Account data
= await
# Positions
= await
# Diagnostics
=
await
Async context manager
= await
Deferred types (Phase 2)
Order management (OpenOrder, OrderStatusEvent) is deferred to a
follow-up release.
Related
- ibquirk — AI bot that diagnoses IBKR API problems using ibcore's DiagnosticEvents (launching soon)
License
MIT — see LICENSE.
ibcore is not affiliated with Interactive Brokers Group, Inc.