# AI Trader Official Realtime Data Design

## Goal

Add two official Binance Spot data sources to the AI trader context: recent REST aggregate trades and short-lived WebSocket market sampling. The feature should improve model input quality without adding a permanent background service or blocking trading when realtime collection fails.

## Scope

Implement only Binance official Spot sources:

- REST `/api/v3/aggTrades`
- WebSocket `bookTicker`, partial `depth20@100ms`, and `aggTrade` streams

Do not add third-party providers, futures data, or a persistent cache in this change.

## Configuration

Add conservative settings:

- `BINANCE_AI_TRADER_AGG_TRADES_LIMIT=500`
- `BINANCE_AI_TRADER_WS_ENABLED=true`
- `BINANCE_AI_TRADER_WS_SAMPLE_SECONDS=15`

The REST aggregate trade limit bounds API weight and prompt size. WebSocket sampling is best-effort; failures should produce an unavailable status in the context, not abort the live command.

## Aggregate Trade Features

For each configured AI symbol, fetch recent aggregate trades and include a compact `aggregate_trades` object:

- `trade_count`
- `first_trade_id`
- `last_trade_id`
- `first_trade_time`
- `last_trade_time`
- `last_trade_age_ms`
- `base_volume`
- `quote_volume`
- `buy_base_volume`
- `buy_quote_volume`
- `sell_base_volume`
- `sell_quote_volume`
- `taker_buy_sell_ratio`
- `vwap`
- `large_trade_count`
- `large_trade_quote_sum`
- `largest_trade_quote`

Binance aggregate trade field `m` means the buyer was the market maker. Treat `m=true` as taker sell volume and `m=false` as taker buy volume.

## WebSocket Sampling Features

For each batch run, sample configured symbols for the configured number of seconds. Include a compact `realtime` object per symbol:

- `status`: `ok`, `disabled`, or `unavailable`
- `sample_seconds`
- `bookticker_updates`
- `depth_updates`
- `agg_trade_updates`
- `spread_min_bps`
- `spread_max_bps`
- `spread_avg_bps`
- `best_bid_qty_avg`
- `best_ask_qty_avg`
- `depth_bid_notional_avg`
- `depth_ask_notional_avg`
- `book_imbalance_avg`
- `agg_trade_buy_quote_volume`
- `agg_trade_sell_quote_volume`
- `agg_trade_buy_sell_ratio`
- `large_trade_count`
- `large_trade_quote_sum`

Use REST data when WebSocket data is absent. Do not send raw WebSocket messages to the model.

## Architecture

Keep synchronous live runners as they are. Add small async helpers in `market_data.py` for one-shot WebSocket sampling, and call them from the synchronous AI runner with `asyncio.run`. Add public REST aggregate trade access to `BinanceSpotClient`.

Feature calculation stays local and deterministic in `ai_trader.py`. The model receives only compact, serialized feature objects.

## Error Handling

REST aggregate trade failures should use an empty feature object for that symbol and continue, matching the current best-effort market-context behavior. WebSocket failures should set `realtime.status` to `unavailable` with no stack trace or exception text in the prompt.

## Testing

Add tests for:

- `BinanceSpotClient.aggregate_trades` URL and params.
- Aggregate trade feature calculations including taker buy/sell split.
- WebSocket sampler parsing bookTicker, depth, and aggTrade messages.
- AI context includes both `aggregate_trades` and `realtime`.
- WebSocket disabled/unavailable cases do not fail a live AI run.
