Broker Health

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_apiget_order_list() responds.
  • position_apiget_positions() responds.
  • margin_apiget_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:

StatusTriggered whenAllowed modeNew entries
HEALTHYAll components ok, latencies under gates.LIVE_ALLOWEDallowed
DEGRADEDOne component failed, or a latency gate tripped.DRY_RUN_ONLYallowed
UNSTABLETwo or more components failed.DRY_RUN_ONLYallowed
DOWN4+ components failed, or token failed with 2+ failures.NO_TRADEblocked

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 (default 2500) — option-chain fetch at or above this adds option_chain_latency.
  • BROKER_HEALTH_API_LATENCY_MS (default 1500) — any of order/position/margin API at or above this adds broker_api_latency.
  • BROKER_HEALTH_RECENT_LIMIT (default 20) — number of recent samples the API returns.
  • BROKER_HEALTH_ENABLED (default True) — master switch for sampling.

No-trade gate

When status is DOWN, new_entries_allowed is False and allowed_mode is NO_TRADE. The bot treats this as a hard block on new live entries — it will not open a new position until a subsequent sample returns HEALTHY, DEGRADED, or UNSTABLE. 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 }, where recent is the last BROKER_HEALTH_RECENT_LIMIT samples. Requires an authenticated session.
  • GET /api/token/health — powers the Dashboard "Dhan Token" card. It prefers the active Dhan trading connection in brokers.broker_connections and falls back to legacy dhan_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).