Files
foxhunt/docs/plans/2026-03-02-fxt-broker-check-design.md
jgrusewski 50d1aff97c docs: add design for fxt broker check CLI command
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>
2026-03-02 13:26:17 +01:00

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:

  1. Direct IB Gateway check: TCP connect → ibapi handshake → account summary → disconnect
  2. Broker Gateway gRPC check: HealthCheck + GetSessionStatus RPCs via broker_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:

  1. TCP probe via tokio::net::TcpStream::connect() with timeout (fail-fast)
  2. ibapi::Client::connect(host, port, client_id) on blocking thread
  3. Request account summary (proves authenticated session)
  4. 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 passed
  • 1 — one or more checks failed
  • 2 — 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_cmd for arg parsing and --skip-* flags