2. 行情数据基础

做行情回放引擎,第一件事不是写回放循环,而是把“回放什么”定义清楚。行情数据并不是一种统一格式,而是由多个粒度、多个通道、多个时间语义叠加而成的数据族。如果数据结构没吃透,速度控制再精细也会出现“回放顺序错乱”“时间戳对不齐”“逐笔和快照互相打架”的问题。本节把六类核心数据对象拆开讲清楚,并给出统一的时间戳规范。

一、六类行情对象的定位与结构

从市场数据生产链路看,交易所先产生逐笔委托和逐笔成交,再聚合成快照,快照再被压缩成 Level-1 或 Level-2 行情,最后按周期聚合成 K 线。Tick 是一个宽泛概念,通常指“带时间戳的最小变动记录”,在不同市场可能指逐笔成交、最优报价变动或快照切片。理解它们的关键是分清三件事:是否全量、是否带档位、是否可还原订单簿。

数据对象典型字段粒度能否还原订单簿回放用途
Tick(成交类)时间、价格、数量、方向逐笔否成交驱动策略
Level-1最新价、买卖一档、成交量切片/快照否轻量行情展示
Level-2十档/多档委托、逐笔委托、逐笔成交逐笔+快照是(近似)盘口与微观结构
K线OHLC、成交量、周期聚合否趋势与回测
快照时间、档位数组、总量定时切片部分状态重建
逐笔委托委托号、方向、价格、数量、类型逐笔是订单簿重建

逐笔委托是还原订单簿的核心。它通常包含委托编号、买卖方向、价格、数量和委托类型(限价、市价、撤单)。逐笔成交则包含成交编号、价格、数量以及主动方方向。快照是某一时刻订单簿的切片,包含若干档位的价格与数量。K 线是时间聚合结果,必须记录周期起点时间,而不是“生成时间”。

二、时间戳规范:三种时间必须分清

行情回放中最容易出错的就是时间戳。至少要区分三类时间:交易所时间(Exchange Time)、本地接收时间(Local Receive Time)、回放逻辑时间(Replay Time)。交易所时间是数据自带的业务时间,通常精确到毫秒或微秒;本地接收时间是网关落库时间,受网络抖动影响;回放逻辑时间是引擎内部推进的虚拟时钟,用于速度控制。

回放引擎应以交易所时间为主排序键,本地接收时间仅作为辅助诊断字段。若同一毫秒内存在多条记录,必须使用序列号或委托编号做稳定排序,否则回放结果不可复现。

时间戳字段建议统一为 64 位整数纳秒或微秒,避免浮点误差。跨市场数据要标注时区,A 股使用 Asia/Shanghai,期货夜盘要注意交易日与自然日的区别。K 线的时间戳应表示周期开始时间,例如 1 分钟 K 线标记为 09:30:00,而不是 09:30:59。

{
  "symbol": "600519.SH",
  "exchange_time": 1717032600123456789,
  "local_time":    1717032600125000000,
  "seq": 88213,
  "type": "order",
  "side": "bid",
  "price": 1680.00,
  "qty": 300,
  "order_type": "limit"
}

三、回放场景:从逐笔委托重建盘口

假设我们要回放某只股票 09:30 到 09:31 的 Level-2 行情。数据源同时提供逐笔委托、逐笔成交和快照。正确流程是:先按交易所时间排序所有记录,再按类型分发处理。逐笔委托进入订单簿模型,逐笔成交扣减对应档位,快照用于定期校准。回放速度控制模块根据逻辑时间推进,决定每条记录之间的等待间隔。

  1. 加载数据并按 exchange_time + seq 排序。
  2. 初始化订单簿,设置初始快照作为基准。
  3. 逐条处理:委托入簿、成交撮合、撤单移除。
  4. 每收到快照,与本地订单簿比对并修正偏差。
  5. 按回放倍速计算 sleep 或事件驱动推进。
若数据源只提供快照而无逐笔委托,则无法精确还原订单簿中间状态,只能做“快照插值”回放。此时应在引擎中明确标注为近似模式,避免策略误判。

四、常见误区与复盘要点

第一个误区是把 K 线当作回放主数据。K 线是聚合结果,丢失了盘中路径,用它回放会掩盖滑点和排队细节。第二个误区是忽略逐笔委托的撤单记录,导致订单簿越回放越厚。第三个误区是直接用本地接收时间排序,网络乱序会让成交出现在委托之前。第四个误区是时间戳单位混用,毫秒和微秒混在一起会造成速度控制数量级错误。

复盘时若发现回放结果与实盘盘口不一致,优先检查三处:排序键是否稳定、撤单是否处理、快照校准是否生效。多数偏差来自这三处,而非速度控制算法本身。
行情数据族与回放时间轴 逐笔委托 order / cancel 逐笔成交 trade / side 快照 snapshot / depth K线 OHLC / period 排序键:exchange_time → seq 本地接收时间仅作诊断,不参与主排序 交易所时间 业务时间,主排序键 微秒/纳秒整数 本地接收时间 网关落库时间 用于延迟诊断 回放逻辑时间 虚拟时钟 驱动速度控制