# 实时行情

## 订阅与读取

```python
quote = api.watch_quote(symbol)
while api.wait_update():
    if quote.is_changing(["last_price", "volume"]):
        q = quote.data()
        print(q.symbol, q.last_price, q.volume, q.open_interest)
```

期货和期权使用同一个方法。字段完整列表见 [Quote 数据字典](./data-reference.md#quote)。无需手动轮询请求行情；由 `wait_update()` 推进订阅。

## 初始值与缺失值

尚未收到行情时，`timestamp` 为 `0`、`trading_day` 为空字符串，价格及数值字段可能是 `math.nan`，盘口可能为空。不要用 `if q.last_price` 判断价格有效性，应使用 `math.isfinite()`。

```python
import math
import time

q = quote.data()
valid = q.timestamp > 0 and math.isfinite(q.last_price)
recent = valid and 0 <= time.time() * 1000 - q.timestamp <= 10_000
if recent:
    print("有效且在示例 10 秒时效范围内", q.last_price)
```

这里的 10 秒是示例策略阈值，不是 SDK 承诺。休市期间最新一笔行情本来就可能很旧；阈值应由实际场景决定。

## 盘口

`bids`、`asks` 是 `(价格, 数量)` 的列表，档位数由实际行情提供，不保证固定五档。读取第一档前检查长度：

```python
q = quote.data()
if q.bids:
    bid_price, bid_volume = q.bids[0]
    print("买一", bid_price, bid_volume)
if q.asks:
    ask_price, ask_volume = q.asks[0]
    print("卖一", ask_price, ask_volume)
```

## 时间与断线

行情 `timestamp` 为 Unix 毫秒，`trading_day` 为 `YYYYMMDD` 交易日。交易日可能与自然日不同。不要直接把毫秒当作 Python 时间戳秒。

断线重连保留最后一次快照，重连过程不等于获取到了新的数据。检查字段变化、时间戳及恢复后的可用数据再执行依赖行情的策略逻辑。
