Broker Health
arb_bot/broker_health.py samples the live Dhan API surface every
cycle and classifies it into a single trading-mode decision. The bot consults
that decision before every entry so it never places a real order while the
broker path is degraded. It is read-only by construction: it pings Dhan
endpoints and records samples but never places, modifies, or recovers orders.
Components sampled
BrokerHealthMonitor.sample() times six component probes and
records each with an ok flag, latency_ms, and
error:
token— Dhan access token present on the legacy token manager or active broker adapter.market_feed— LTP quote returns a value.option_chain— expiry list + first chain fetch succeed.order_api—get_order_list()responds.position_api—get_positions()responds.margin_api—get_fund_limits()responds.
Status & allowed trading mode
classify_broker_health() aggregates the six components and two
latency gates into a BrokerHealthStatus and an
allowed_mode:
| Status | Triggered when | Allowed mode | New entries |
|---|---|---|---|
HEALTHY | All components ok, latencies under gates. | LIVE_ALLOWED | allowed |
DEGRADED | One component failed, or a latency gate tripped. | DRY_RUN_ONLY | allowed |
UNSTABLE | Two or more components failed. | DRY_RUN_ONLY | allowed |
DOWN | 4+ components failed, or token failed with 2+ failures. | NO_TRADE | blocked |
Latency gates
Slow responses degrade health even when the call succeeds. Two gates are read
live from arb_bot/config.py:
BROKER_HEALTH_OPTION_CHAIN_LATENCY_MS(default2500) — option-chain fetch at or above this addsoption_chain_latency.BROKER_HEALTH_API_LATENCY_MS(default1500) — any of order/position/margin API at or above this addsbroker_api_latency.BROKER_HEALTH_RECENT_LIMIT(default20) — number of recent samples the API returns.BROKER_HEALTH_ENABLED(defaultTrue) — master switch for sampling.
No-trade gate
When status isDOWN,new_entries_allowedisFalseandallowed_modeisNO_TRADE. The bot treats this as a hard block on new live entries — it will not open a new position until a subsequent sample returnsHEALTHY,DEGRADED, orUNSTABLE. Existing positions continue to be monitored for exits.
Persistence & API
Each sample is appended to the SQLite store via
store.append_broker_health_sample() and surfaced through:
GET /api/broker/health— returns{ latest, recent }, whererecentis the lastBROKER_HEALTH_RECENT_LIMITsamples. Requires an authenticated session.GET /api/token/health— powers the Dashboard "Dhan Token" card. It prefers the active Dhan trading connection inbrokers.broker_connectionsand falls back to legacydhan_token_state, so the card reflects the token source used by the live API client.format_broker_health_summary()— renders the latest sample for Telegram (/broker_health).