Skip to content
yemelgenPublic

About

A gRPC-based service that provides a modern RPC interface to Interactive Brokers TWS/Gateway API

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

TWS Agent -- gRPC Service for Interactive Brokers TWS API

A gRPC-based service that provides a modern RPC interface to Interactive Brokers TWS/Gateway API.

Features

  • gRPC interface with protobuf serialization
  • Timezone-aware datetime formatting utilities
  • Connection management to TWS/Gateway
  • Contract details lookup with full security identifiers
  • Historical data retrieval with ISO 8601 formatted timestamps
  • Historical tick data (TRADES, BID_ASK, MIDPOINT)
  • Option chain retrieval (expirations and strikes)
  • Wall Street Horizon corporate events (earnings, dividends, splits, etc.)
  • Watchlist export parsing (read TWS watchlist from export.csv)
  • Portfolio positions, open orders, executions, and completed orders
  • Market scanner functionality
  • Built-in IB API rate limiting (pacing) at the service level

Architecture

Client Apps -> gRPC -> IBAgent Service -> ibapi -> TWS/Gateway

Quick Start

1. Install

The install script creates a virtualenv, downloads the IB API, and installs dependencies:

python install.py

For development, you can install manually:

# Copy IB API Python source to project root
cp -r /path/to/TWS-API/source/pythonclient/ibapi ./ibapi

# Install in editable mode
pip install -e .

2. Start TWS or IB Gateway

Make sure TWS or IB Gateway is running and API connections are enabled:

  • TWS Paper Trading: Port 7497
  • TWS Live Trading: Port 7496
  • Gateway Paper Trading: Port 4002
  • Gateway Live Trading: Port 4001

Read-Only API mode

Global Configuration > API > Settings has a 'Read-Only API' checkbox. Leaving it checked is recommended: every RPC in this service is a read, and read-only mode makes it impossible for a bug to place or cancel an order.

One request is affected. TWS rejects reqCompletedOrders in read-only mode with error 321 and pops a dialog, so GetCompletedOrders only works with the checkbox cleared. Use GetOpenOrders and GetExecutions instead -- both are served in read-only mode and together cover working orders and fills.

3. Start the gRPC Server

./start.sh

4. Run Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=app --cov-report=html

5. Use from Client Applications

See the examples/ directory for Python client examples.

Configuration

Set environment variables to customize the service:

# gRPC server settings
export GRPC_HOST=0.0.0.0
export GRPC_PORT=5005
export GRPC_MAX_WORKERS=10

# TWS/Gateway connection defaults
export TWS_HOST=127.0.0.1
export TWS_PORT=7497
export TWS_CLIENT_ID=1

# Logging configuration
export IBAPI_LOG_LEVEL=WARNING  # Options: DEBUG, INFO, WARNING, ERROR (default: WARNING)

Alternatively, edit settings.ini:

[grpc]
host = 127.0.0.1
port = 5005
max_workers = 10

[tws]
host = 127.0.0.1
port = 7497
client_id = 1

[logging]
path = {home}/logs
filename = twsagent.log

[watchlist]
export_path = {home}/Jts/export.csv

[pacing]
historical_max_requests = 50
historical_window_seconds = 600
identical_gap_seconds = 15
general_min_interval_seconds = 1.0

Note: Setting IBAPI_LOG_LEVEL=WARNING (default) suppresses verbose debug messages from the IB API library.

Pacing (Rate Limiting)

The service enforces IB API pacing rules at the service level to prevent violations:

  • Historical data: Max 50 requests per 10-minute sliding window, plus a 15-second gap between identical requests
  • General requests: Minimum 1-second interval between any IB API calls

These limits are configurable via the [pacing] section in settings.ini or environment variables (PACING_HIST_MAX, PACING_HIST_WINDOW, PACING_IDENTICAL_GAP, PACING_GENERAL_INTERVAL).

Watchlist Export

The service can read TWS watchlist data from the exported CSV file:

  1. In TWS, export your watchlist using File > Export > Export Data
  2. The default export location is ~/Jts/export.csv
  3. Configure the path in settings.ini if you use a different location
  4. Call the GetWatchlist RPC method to retrieve the parsed watchlist

The parser supports all contract types: stocks (STK), options (OPT), futures (FUT), forex (CASH), crypto (CRYPTO), and indices (IND).

Examples

Download Bars (OHLCV)

python examples/download_bars.py TQQQ
python examples/download_bars.py TQQQ --bar-size 5s --days 2
python examples/download_bars.py TQQQ --bar-size 1d --years 2
python examples/download_bars.py TQQQ --extended -o bars.json

Download Ticks

python examples/download_trades.py TQQQ --ts 1772205420 --duration 60
python examples/download_trades.py TQQQ --ts 1772160000 --duration 86400
python examples/download_trades.py TQQQ --ts 1772160000 --duration 86400 --extended -o trades.json

Download Contract Details

python examples/download_contracts.py AAPL
python examples/download_contracts.py AAPL MSFT GOOGL
python examples/download_contracts.py --file symbols.txt -o securities.json

Download Option Chains

python examples/download_options.py AAPL
python examples/download_options.py AAPL TSLA SPY
python examples/download_options.py ES --sec-type FUT

Download Corporate Events (WSH)

Requires a Wall Street Horizon subscription.

python examples/download_events.py AAPL
python examples/download_events.py AAPL --filter Earnings
python examples/download_events.py AAPL --start 20240101 --end 20241231

Download Positions

python examples/download_positions.py
python examples/download_positions.py -o positions.json

Download Orders and Trades

# Working orders, including ones placed manually in TWS
python examples/download_orders.py open
python examples/download_orders.py open --client-only

# Trade fills. TWS serves the last 24 hours by default; --last-n-days and
# --date need TWS 10.30+, and neither reaches back more than a few days.
python examples/download_orders.py executions
python examples/download_orders.py executions --last-n-days 7 --format summary
python examples/download_orders.py executions --symbol AAPL -o fills.json

# Terminal-state orders. Requires 'Read-Only API' to be unchecked in TWS.
python examples/download_orders.py completed --api-only

Download Trade History (Flex)

Finished-order history, served from a file on disk the same way the watchlist is. Nothing here touches TWS, so it works with TWS closed and is unaffected by read-only mode.

Create an Activity Flex query in Client Portal (Performance & Reports > Flex Queries, not Statements) with the Trades section enabled, 'Level of Detail' set to Order, and format CSV. Run it, download the file, and save it to the path in settings.ini ([flex] statement_path, default ~/Jts/trades.csv). The date range lives in the query definition. Refresh the file for newer history.

python examples/download_trade_history.py -o trades.csv
python examples/download_trade_history.py --symbol AAPL --format summary
python examples/download_trade_history.py --statement-path ~/Downloads/flex.csv

Set [flex] timezone. IBKR omits the UTC offset from the export, so timestamps cannot be resolved without knowing the query's timezone. Left blank, the service returns naive timestamps rather than guessing; set it to match the query (Client Portal > Flex Queries > Date/Time), e.g. America/New_York.

GetTradeHistory and GetExecutions share field names, units, and vocabularies so historical and live rows can land in one table: account, con_id, symbol, sec_type, currency, exchange, side (BUY/SELL), quantity (positive), price, executed_at (ISO 8601), commission, commission_currency, realized_pnl.

At Order level IBKR leaves trade_id blank -- use ib_order_id as the dedup key.

Download Watchlist

python examples/download_watchlist.py
python examples/download_watchlist.py --export-path ~/Jts/export.csv
python examples/download_watchlist.py -o watchlist.json

Run Market Scanner

python examples/run_scanner.py --list-scans
python examples/run_scanner.py --scan TOP_PERC_GAIN --location STK.US.MAJOR --rows 20
python examples/run_scanner.py --scan MOST_ACTIVE --above-price 10

Development

Regenerate Protobuf Code

IMPORTANT: The files stubs/tws_pb2.py and stubs/tws_pb2_grpc.py are auto-generated. Never edit them manually.

When you modify proto/tws.proto, regenerate the Python code:

pip install grpcio-tools protobuf

mkdir -p stubs
touch stubs/__init__.py

python3 -m grpc_tools.protoc \
  --proto_path=./proto \
  --python_out=./stubs \
  --grpc_python_out=./stubs \
  proto/tws.proto

Restart your server to use the new generated code.

Documentation

License

MIT

About

A gRPC-based service that provides a modern RPC interface to Interactive Brokers TWS/Gateway API

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages