2. 实时行情基础

在动手写 WebSocket 订阅代码之前,必须先理解“行情数据”本身长什么样。很多断线恢复的坑,其实不是连接层的问题,而是对行情数据的结构、频率和语义理解不到位:重连后该补哪些数据、快照和增量如何拼接、时间戳以谁为准,都取决于行情数据的特性。本节先把这些基础打牢,后续的订阅与恢复逻辑才有依据。

一、行情数据的四个核心特点

行情数据与普通业务数据最大的区别,在于它同时具备高频、时序、易变、可丢失四个属性。理解这四点,才能设计出合理的推送与恢复策略。

  • 高频性:热门标的的逐笔成交每秒可达数十到数百条,盘口变化在活跃时段几乎连续不断。若不做节流或合并,客户端渲染会被压垮。
  • 时序性:每条数据都带有时间维度,且顺序敏感。盘口的最新状态由“上一状态 + 增量”推导而来,乱序或丢包会导致状态错误。
  • 易变性:同一标的的价格、量、盘口在极短时间内反复变化,只有“最新值”才有意义,历史中间态大多可丢弃。
  • 可丢失性(相对):对普通展示场景,丢失个别中间 tick 通常可接受;但对撮合、风控、套利场景,丢失即错误,必须能补齐。
判断你的业务属于“可容忍丢失”还是“必须精确”,直接决定了断线恢复时是只拉最新快照,还是必须按序列号补增量。

二、推送频率与数据粒度的关系

推送频率不是越高越好,而是要与数据粒度、业务需求匹配。常见有三档:

粒度 典型频率 数据内容 适用场景
快照(Snapshot) 1~3 秒/次 最新价、买卖五档、成交量 行情列表、看板、普通展示
盘口增量(Depth) 10~100 次/秒 单档挂单的增删改 盘口深度、下单辅助
逐笔成交(Tick/Trade) 数十~数百次/秒 每笔成交价、量、方向 分时图、量化、风控

频率越高,对连接稳定性和恢复能力的要求越高。逐笔数据一旦断线,中间缺失的成交无法凭最新快照还原,必须依赖服务端补发或序列号机制。

三、常见数据格式与字段语义

WebSocket 行情推送主流使用 JSON 或二进制(Protobuf、自定义二进制)。JSON 可读性好、调试方便,但体积大、解析慢;二进制体积小、性能高,但需要协议定义。下面是一个典型的 JSON 盘口增量消息:

{
  "type": "depth.update",
  "symbol": "BTC-USDT",
  "seq": 102457,
  "ts": 1718000000123,
  "bids": [["65000.5", "1.2"], ["65000.0", "0.8"]],
  "asks": [["65001.0", "0.5"]],
  "action": "update"
}

关键字段需要特别关注:

  • seq(序列号):判断是否丢包、是否乱序的核心依据,断线恢复时用它对齐增量。
  • ts(时间戳):区分交易所时间与本地接收时间,做延迟统计和排序时不能混用。
  • action:区分 update / insert / delete,盘口增量必须按动作语义应用。
  • symbol:订阅与恢复的粒度单位,通常按标的独立维护状态。
不要假设 seq 一定连续递增。部分交易所按通道或按标的独立编号,跨标的比较 seq 没有意义,恢复逻辑必须按订阅粒度处理。

四、常见市场数据类型与业务场景

不同市场类型的数据特征差异很大,直接影响订阅与恢复设计:

  • 股票:有开盘/收盘、集合竞价、涨跌停,盘中频率相对平稳,盘后无推送。恢复时需注意交易时段判断。
  • 期货/期权:有夜盘、主力合约切换,合约到期后停止推送,订阅需动态调整。
  • 加密货币:7×24 小时不间断,频率极高,交易所众多且协议各异,是断线恢复最典型的战场。
  • 外汇:周末休市,报价来自多家流动性提供商,需处理多源合并与去重。

业务场景上,行情看板只需最新快照,断线后拉一次全量即可;而量化交易、风控系统要求状态精确,必须实现“快照 + 增量 + 序列号校验”的完整恢复链路。同一套 WebSocket 客户端,面对不同场景,恢复策略应当可配置。

交易所行情源 快照 / 增量 / 逐笔 带 seq 与 ts 行情网关 协议转换 / 合并 按标的维护 seq WebSocket 推送 JSON / 二进制 高频、可丢失 客户端状态机 快照 + 增量应用 seq 校验 / 去重 断线检测 心跳超时 / 关闭码 seq 跳变告警 恢复动作 重订阅 + 拉快照 按 seq 补增量 行情推送链路与断线恢复闭环:推送 → 检测 → 恢复 → 重新对齐状态

五、常见误区与复盘要点

初学者在行情订阅上最容易踩的坑,往往集中在以下几点:

  1. 把快照当增量用:重连后只拉一次快照就继续接收增量,若快照与增量之间存在时间缝隙,状态会永久错位。正确做法是记录快照对应的 seq,再从此 seq 之后补增量。
  2. 忽略时间戳来源:用本地时间排序交易所数据,网络抖动会导致乱序。应以交易所 ts 为准,本地时间仅用于延迟统计。
  3. 不做去重:重连后可能收到重复的增量,若直接累加成交量,数据会翻倍。必须按 seq 去重。
  4. 订阅粒度过粗:一个连接订阅上百个标的,单个标的断流难以定位。建议按标的或按通道拆分状态与恢复逻辑。
复盘时建议记录三个指标:断线次数、每次恢复耗时、恢复后 seq 是否连续。这三个指标能直接反映你的行情订阅链路是否健康。

理解了行情数据的特点、频率、格式与场景差异,你就有了设计订阅与恢复策略的判断依据。接下来进入 WebSocket 协议本身,看它如何承载这些高频、时序敏感的数据流。