2. 盘口数据基础
要验证“价格优先、时间优先”规则,第一步不是写判断逻辑,而是把盘口数据本身弄明白。盘口数据通常由两类互补的数据构成:盘口快照(Snapshot)和逐笔委托/逐笔成交(Tick-by-Tick)。快照回答“某一时刻盘口长什么样”,逐笔回答“盘口是怎么一步步变成这样的”。只有两者对齐,才能还原出委托进入撮合系统的先后顺序,进而检验同一价格上先到者是否先成交。
一、盘口快照的数据结构
快照是交易所在固定时间间隔(如沪深 Level-1 每 3 秒、Level-2 每 3 秒或更快)推送的市场状态切片。一条典型快照包含:时间戳、证券代码、最新价、成交量、成交额、买一至买N的价格与数量、卖一至卖N的价格与数量。以十档快照为例,字段可抽象为:
{
"timestamp": "2024-06-03 09:30:03.000",
"symbol": "600000",
"last_price": 10.52,
"volume": 128400,
"bid": [[10.51, 3200], [10.50, 8700], ...], // 买一..买十
"ask": [[10.52, 1500], [10.53, 6400], ...] // 卖一..卖十
}
字段含义上有几个易错点必须明确:买一价是当前最高买价,卖一价是当前最低卖价,二者之差为价差;买一量是“挂在该价位上尚未成交的委托总量”,不是单笔委托量。快照中的数量是聚合结果,无法区分同一价位上多笔委托的先后,这正是快照的天然局限——它只能看到“结果”,看不到“过程”。
二、逐笔委托与逐笔成交的数据结构
逐笔数据记录每一笔委托的进入、撤单与成交事件。逐笔委托字段通常包括:委托序号(交易所撮合序号,是判断时间先后的关键)、时间戳、证券代码、买卖方向、委托价格、委托数量、订单类型。逐笔成交则包括:成交序号、时间戳、成交价格、成交数量、买卖双方委托序号(部分市场提供)。
逐笔委托: {seq: 100231, time: 09:30:01.120, side: "B", price: 10.52, qty: 800}
逐笔成交: {seq: 100245, time: 09:30:01.135, price: 10.52, qty: 500, bid_seq: 100231, ask_seq: 100198}
这里最关键的是委托序号 seq。交易所撮合系统按序号递增处理委托,序号小者先进入。验证时间优先时,不能只看时间戳(毫秒精度可能相同或存在时钟偏差),而应以 seq 作为“到达顺序”的权威依据;时间戳用于辅助校验。若逐笔成交能关联买卖双方委托序号,就能直接判断同一价位上哪笔委托先成交,从而验证规则。
三、数据采集方式
常见采集路径有三类:一是行情网关订阅,通过券商或行情商的 TCP/UDP 接口实时接收快照与逐笔流,需处理断线重连与序号补缺;二是文件回放,用历史逐笔文件按时间顺序回放,适合离线验证;三是交易所直连或托管机房,延迟最低但门槛高。采集时必须同时落盘原始报文与接收时间,便于事后核对。下面这张图展示了从行情源到验证数据集的完整链路与关键字段的对应关系:
四、常见数据质量问题与处理
实际拿到的数据往往不干净,直接影响规则验证结论。典型问题有四类:时间戳重复或乱序,同一毫秒内多笔事件无法靠时间区分,必须改用 seq;seq 跳号或缺失,说明采集丢包,缺失区间内的委托顺序不可知,应剔除该时段样本而非强行推断;快照与逐笔不一致,例如快照显示买一量 3200,但逐笔累计挂单与撤单对不上,可能是快照聚合口径或采集时点差异;重复推送与丢包,需按 seq 去重、按序号连续性检测缺口。
处理原则是:先做完整性校验(seq 是否连续、快照档位是否完整、成交能否关联双方序号),再做一致性校验(用逐笔重建盘口,与快照比对买一卖一价格和数量),最后才进入规则验证。对于无法对齐的样本,应明确标记为“不可验证”,而不是用猜测填补。
把数据结构、字段语义和采集链路理清之后,后续验证“价格优先、时间优先”才有可靠基础:价格优先看同一时刻最优价是否被优先撮合,时间优先则依赖 seq 还原同一价位上的到达次序。数据质量不过关,任何规则验证结论都站不住脚。