trading_agent.scheduling.market_watcher
¶
Watches the market for the desks, with no model: fills, price alerts and the account's loss limits.
While NSE equities or MCX trade, every cycle (15 seconds by default) it:
- reads UBI's order book once and finds the finished broker orders (complete, cancelled, rejected or expired) that belong to a desk's own orders in the desk order book, matched by parent_id or order_id; each desk gets one message listing its updates;
- reads the last price of every instrument a desk has an alert on, once each, and wakes the desk for each alert crossed, removing the alert;
- once a minute, asks the risk engine to check the account, so the kill switch fires at the daily or weekly loss limit, and a desk is halted at its own daily loss limit, even when no desk is placing orders; the account's and each desk's profit and loss are then published as an account_status event.
The ids of orders already reported are kept in a small file, so a restart neither repeats a fill nor forgets one that finished while the gateway was down. Dry-run orders reach no broker, so they never appear in the order book and are skipped.
Typical usage example:
watcher = MarketWatcher(desks, alert_stores, order_book, reader, risk_engine, hours, event_bus, state_file) task = asyncio.create_task(watcher.run())
MarketWatcher
¶
MarketWatcher(desks, alert_stores, order_book, reader, risk_engine, hours, event_bus, state_file, interval_seconds=15.0, account_check_seconds=60.0, clock=None)
The model-free loop that wakes desks when something happens in the market.
Creates the watcher.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
desks
|
Mapping[str, DeskRuntime]
|
The running desks, keyed by name. |
required |
alert_stores
|
Mapping[str, PriceAlertStore]
|
Each desk's alerts. |
required |
order_book
|
DeskOrderBook
|
Which desk placed which order. |
required |
reader
|
BrokerReader
|
The shared UBI reader. |
required |
risk_engine
|
RiskEngine
|
Checks the account's loss limits. |
required |
hours
|
ExchangeHours
|
Decides when the market is open. |
required |
event_bus
|
EventBus
|
Where fills and alerts are published. |
required |
state_file
|
Path
|
Where the ids of reported orders are kept. |
required |
interval_seconds
|
float
|
The time between cycles while the market is open. |
15.0
|
account_check_seconds
|
float
|
The time between account checks. |
60.0
|
clock
|
Callable[[], datetime] | None
|
Returns the current time; None uses the system clock. |
None
|
Source code in src/trading_agent/scheduling/market_watcher.py
run
async
¶
Runs a cycle whenever the market is open, until cancelled.
Source code in src/trading_agent/scheduling/market_watcher.py
market_open
¶
Says whether NSE equities or MCX trade at a moment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
moment
|
datetime
|
The moment. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True when either is open. |
Source code in src/trading_agent/scheduling/market_watcher.py
cycle
async
¶
Checks fills, alerts and, when due, the account.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
now
|
datetime
|
The current time. |
required |
Source code in src/trading_agent/scheduling/market_watcher.py
check_fills
async
¶
Reports newly finished broker orders to the desks that placed them.
Returns:
| Type | Description |
|---|---|
int
|
How many order updates were reported. |
Source code in src/trading_agent/scheduling/market_watcher.py
check_alerts
async
¶
Wakes desks whose price alerts were crossed, and removes those alerts.
Returns:
| Type | Description |
|---|---|
int
|
How many alerts fired. |