Two-layer IBKR connectivity validation: direct ibapi handshake + broker-gateway gRPC health check. Pure-client architecture using ibapi as optional dep on fxt (not trading_engine). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.5 KiB
Design: fxt broker check — IBKR Connectivity Validation
Problem
No CLI command exists to validate IBKR TWS/Gateway connectivity. The only option is running #[ignore] integration tests manually with cargo test. Operators need a quick, production-friendly way to verify the broker connection chain.
Solution
Add fxt broker check — a two-layer connectivity validation command:
- Direct IB Gateway check: TCP connect → ibapi handshake → account summary → disconnect
- Broker Gateway gRPC check:
HealthCheck+GetSessionStatusRPCs viabroker_gateway_service
Command Interface
fxt broker check [OPTIONS]
Options:
--host <HOST> IB Gateway host (env: IBKR_HOST, config: broker.ibkr.host, default: 127.0.0.1)
--port <PORT> IB Gateway port (env: IBKR_PORT, config: broker.ibkr.port, default: 4002)
--client-id <ID> TWS client ID (env: IBKR_CLIENT_ID, default: 99)
--gateway-url <URL> Broker Gateway gRPC URL (env: BROKER_GATEWAY_URL, config: broker.gateway_url, default: http://localhost:50060)
--skip-gateway Skip broker-gateway gRPC check
--skip-ibkr Skip direct IB Gateway check
Config precedence: CLI flags > env vars > ~/.foxhunt/config.toml > defaults.
Output
Success:
Broker Connectivity Check
═══════════════════════════════════════
IB Gateway (direct)
TCP connect .............. ✓ 127.0.0.1:4002 (12ms)
ibapi handshake .......... ✓ client_id=99, server v10.19
Account summary .......... ✓ DU9600528 (paper)
Broker Gateway (gRPC)
Health check ............. ✓ broker-gateway:50060 (8ms)
Session status ........... ✓ ACTIVE (seq: 1042/1041, RTT: 2.3ms)
Result: All checks passed ✓
Failure:
IB Gateway (direct)
TCP connect .............. ✗ Connection refused (127.0.0.1:4002)
Broker Gateway (gRPC)
Health check ............. ✗ Unavailable (connection timeout)
Result: 2/2 checks failed ✗
Architecture
Pure-client constraint
fxt is a pure gRPC client — it must NOT depend on trading_engine. The direct IB check uses ibapi as an optional dependency on fxt itself, behind a broker-check feature flag. When compiled without the feature, fxt broker check still works for the gRPC layer but skips the direct ibapi check.
Files to create/modify
| File | Action | Purpose |
|---|---|---|
bin/fxt/src/commands/broker.rs |
Create | BrokerCommand::Check implementation |
bin/fxt/src/commands/mod.rs |
Modify | Add pub mod broker + re-export |
bin/fxt/src/main.rs |
Modify | Add Broker variant to Commands enum |
bin/fxt/src/config.rs |
Modify | Add BrokerConfig section to TliConfig |
bin/fxt/Cargo.toml |
Modify | Add ibapi optional dep, broker-check feature |
bin/fxt/build.rs |
Modify | Compile broker_gateway.proto |
bin/fxt/proto/broker_gateway.proto |
Create | Copy/symlink from services/broker_gateway_service/proto/ |
Proto strategy
The broker_gateway.proto lives in services/broker_gateway_service/proto/. fxt needs to compile it for client stubs. Options:
- Copy the proto into
bin/fxt/proto/(matches existing pattern — fxt has its own proto dir) - Symlink (fragile across platforms)
Recommend: copy the proto file. fxt already has its own proto directory with 6 protos. This is consistent.
Config file addition
# ~/.foxhunt/config.toml
[broker]
gateway_url = "http://localhost:50060"
[broker.ibkr]
host = "127.0.0.1"
port = 4002
client_id = 99
ibapi usage in fxt
The ibapi crate's Client::connect() is synchronous/blocking. Wrap in tokio::task::spawn_blocking (same pattern as trading_engine). The check sequence:
- TCP probe via
tokio::net::TcpStream::connect()with timeout (fail-fast) ibapi::Client::connect(host, port, client_id)on blocking thread- Request account summary (proves authenticated session)
- Disconnect
Feature flag
[features]
default = ["broker-check"]
broker-check = ["dep:ibapi"]
Default-enabled so fxt broker check works out of the box. Can be disabled for minimal builds.
Exit codes
0— all checks passed1— one or more checks failed2— configuration error (bad host/port/URL)
Testing
- Unit tests: config parsing, output formatting
- Integration test (
#[ignore]): requires running IB Gateway, tests full flow - CLI test:
assert_cmdfor arg parsing and--skip-*flags