Ports & AdaptersIBKR · IC Markets · BinancePaper Fallback

Execution & Broker Integration

Ports & Adapters pattern — ExecutionService operates against abstract broker interface ports. Concrete adapters implement each broker's specific protocol. No order is ever silently dropped: it routes to a live broker or to the paper adapter.

Execution Architecture

ExecutionService (core)
BrokerRouter (deterministic asset-class rules)
CompositeBrokerAdapter
├─── IBKRAdapter (ib-insync) → Interactive Brokers
├─── MT4Adapter (REST) → IC Markets MT4
├─── BinanceAdapter (CCXT) → Binance
└─── PaperAdapter (mock fallback)

Order Routing Rules

Routing is deterministic rule-based — asset class determines broker. No ML or probabilistic decisions in the router.
Asset ClassBrokerAdapter
EQUITYInteractive Brokers (IBKR)IBKRAdapter via ib-insync
OPTIONInteractive Brokers (IBKR)IBKRAdapter via ib-insync
FUTUREInteractive Brokers (IBKR)IBKRAdapter via ib-insync
FX (Forex)IC Markets via MT4MT4Adapter REST bridge
CRYPTOBinanceBinanceAdapter via CCXT
FALLBACK (any)Paper TradingPaperAdapter (mock, no real fills)

Execution Routing Diagram

Signal → BrokerRouter → adapter → exchange

SuperIntel execution routing diagram

8-Step Order Lifecycle

1
create_order()

Order object created — state: PENDING

2
persist(order)

Written to TimescaleDB orders table

3
connect_gateway()

Broker adapter connection verified / reconnected. Failure → rerouted to PaperAdapter.

4
place_order(order)

Sent to broker API. Failure → logged as REJECTED, failure counter incremented (circuit breaker).

5
await_fill()

Poll or callback for fill confirmation. IBKR: event-driven. Binance/MT4: polling-based.

6
persist(FILLED)

Order updated with fill price and timestamp

7
update_positions()

Portfolio positions updated in real-time

8
publish_fill_event()

Redis pub/sub: fill event for downstream consumers

Interactive Brokers (IBKR)

Connection

library: ib-insync
host: 127.0.0.1:4002
container: ibkr-gateway (IBC headless)
mode: paper (IBC_TradingMode: paper)
auto_restart: 11:59 PM daily

Fill Handling

Event-driven via ib-insync asyncio events — no polling required:

orderStatusEvent # order state changes
execDetailsEvent # execution fill details

Supported Order Types

MarketLimitStop-lossBracket (entry + stop + take-profit)

Asset Classes (IBKR)

US Equities (STK)Options (OPT)Futures (FUT)Forex (secondary — primary FX is MT4)

IC Markets MT4 (Forex)

REST bridge running as a Docker container (superintel-mt4-bridge) at 127.0.0.1:8005:8000. Translates REST API calls into MT4 Expert Advisor commands connected to IC Markets MT4 terminal. Fill confirmation via polling GET /order/{id} with retry-backoff.

MethodEndpointPurpose
POST/order/placePlace a Forex market or limit order
POST/order/modifyModify stop-loss or take-profit on open order
POST/order/closeClose an open position
GET/order/{id}Poll order status for fill confirmation
GET/accountAccount balance and margin info

Binance (Crypto)

Singleton CCXT ccxt.async_support.binance with enableRateLimit=True. API key + secret from environment variables. Fill confirmation via fetch_order() polling every 3 seconds.

Execution Operations

create_market_order(symbol, side, amount)
create_limit_order(symbol, side, amount, price)
cancel_order(order_id, symbol)
fetch_order(order_id, symbol) # fill confirmation
fetch_open_orders(symbol)

Data Operations (dual-use)

fetch_ohlcv(symbol, timeframe)
fetch_ticker(symbol) # live bid/ask/last
fetch_order_book(symbol, limit) # L1 depth
For Level 2 microstructure data, Databento is used separately — not CCXT/Binance.

Paper Trading Adapter (Fallback)

mock_adapter.pyAuto-activated on broker failure

Null-implementation of the broker interface. Simulates fills with configurable slippage model (±0.1% of mid-price). Tracks paper positions in TimescaleDB paper_positions table. Activates automatically when:

  • No live broker adapter available for the asset class
  • Environment variable FORCE_PAPER_TRADING=true
  • Live adapter fails health_check()

NAV Arbitrage — Dual-Leg Execution

NavArbitrageDetector targets trust/spot premium arbitrage (GBTC/BTC style). Entry on Z-score extremes, exit on mean reversion. Two-leg orders submitted via asyncio.gather.

SignalConditionTrade
LONG_TRUST_SHORT_SPOTZ-score < −2.0 AND Spread < −2%Trust trades at >2% discount to NAV — buy trust, short spot
SHORT_TRUST_LONG_SPOTZ-score > +2.0 AND Spread > +2%Trust trades at >2% premium to NAV — short trust, long spot
Spread = Trust_Price / NAV − 1
Z-score = (Spread − mean(Spread)) / std(Spread)
# Exit condition
Exit when Z-score returns to within ±0.3 of mean

Exchange Mapper — Ticker Routing

TickerAsset ClassRoutes To
BTC-USDTCRYPTOBinance
GBTCEQUITYIBKR (ETF, not crypto route)
SPYEQUITYIBKR
EURUSDFXIC Markets MT4