4. 订单簿快照与成交记录的匹配对齐

方向推断的标注数据集,本质上不是“成交表”本身,而是“成交 + 当时的最优报价环境”。同一笔主动买单,如果发生在买一价附近,说明买方愿意付出价差;如果发生在卖一价上方,说明买方更急。要判断这一点,必须把逐笔成交与订单簿快照在时间轴上对齐。本节围绕三个关键动作展开:时间戳对齐、快照频率选择、成交与最优报价的关联方法,最后给出可落地的标注数据集结构。

一、先统一时间语义,再谈对齐

成交记录与订单簿快照通常来自不同数据通道,时间戳含义并不一致。常见有三类:交易所撮合时间(事件发生时刻)、行情推送时间(服务端发出时刻)、本地接收时间(客户端收到时刻)。三者之间存在网络延迟与排队抖动,若混用,会把“成交发生在报价变化之后”误判为“成交发生在报价变化之前”。

工程上应遵循两条原则。第一,同一数据集内只使用一种时间基准,优先采用交易所时间戳;若成交与快照的交易所时间字段都存在,直接使用,不做本地时间补偿。第二,若只有本地接收时间,则必须做单向延迟校正:以快照的交易所时间为锚,估计本地接收相对交易所时间的偏移中位数,再统一平移到交易所时间轴。不要用成交时间去反推快照时间,否则会引入前视偏差。

对齐的判定规则建议写成“快照时间 ≤ 成交时间”的最近一条快照,即后向对齐(as-of join)。含义是:用成交发生前最后一版已知订单簿来解释这笔成交。这样标注出的方向特征在实盘中是可获得的,不会用到未来信息。若成交时间恰好等于某快照时间,需明确约定归属(通常归入该快照),并在全数据集保持一致。

二、快照频率的选择:精度与可得性的权衡

快照频率决定了“报价环境”的分辨率。频率过高,数据量大且大量快照无成交,标注成本上升;频率过低,成交发生时引用的报价可能已经过期,方向特征失真。选择时应结合标的流动性与成交间隔分布。

一个实用的判断方法是统计相邻成交的时间间隔分位数。若某标的成交间隔中位数约为 200 ms,则 100 ms 快照能保证多数成交落在相邻两版快照之间,报价漂移有限;若用 1 s 快照,则一笔成交可能对应已变化数档的报价,关联误差显著。反之,对成交稀疏的标的,1 s 甚至更粗的快照已足够,过密快照只会增加存储与匹配开销。

还需注意快照的深度。方向推断主要依赖买一、卖一及前几档,但价差扩大或一档被瞬时抽空时,需要二档、三档来还原真实最优报价。建议快照至少保留前 5 档,并在数据集中记录快照的档位深度,便于后续按深度分层评估标注质量。

成交与快照的后向对齐(as-of join) 时间轴向右递增;每笔成交引用其左侧最近一版快照的买一/卖一 t 快照 S1 t=100ms 快照 S2 t=200ms 快照 S3 t=300ms 成交 T1 t=160ms 成交 T2 t=255ms T1 ← S1 T2 ← S2 对齐规则 取 t_snap ≤ t_trade 的最近一版快照 不使用未来快照

三、成交与最优报价的关联方法

对齐完成后,需要把每笔成交映射到具体的报价关系上。核心是判断成交价与快照中买一价(bid1)、卖一价(ask1)的相对位置。这里先明确方向约定:主动买 = 买方吃掉卖一挂单,成交价 ≥ ask1;主动卖 = 卖方砸向买一挂单,成交价 ≤ bid1。全文与图示均采用这一约定。

关联时按以下顺序判定,可覆盖绝大多数情形:

  1. 价格高于 ask1:成交价 > ask1,属于扫单或多档成交,标记为主动买,并记录穿透档数。
  2. 价格等于 ask1:标记为主动买;若同时等于 bid1(价差为零的极端情形),需结合成交方向字段或前后成交序列辅助判断。
  3. 价格等于 bid1:标记为主动卖。
  4. 价格低于 bid1:标记为主动卖,记录穿透档数。
  5. 价格落在 bid1 与 ask1 之间:说明快照已过期或存在隐藏流动性,标记为“不确定”,不强行赋值,留待人工复核或按规则剔除。

对于一笔成交对应多个价位的撮合(如一次大单吃掉多档),应按成交明细逐条关联,而不是把整笔大单当作一个点。每条明细都引用同一版快照,但各自比较自己的成交价与当时的 ask1/bid1,从而得到每条明细的方向标签与穿透深度。

四、构建标注数据集的字段与校验

把上述过程固化为一张可复用的标注表,字段应同时保留原始信息与派生标签,便于回溯与误差分析。下面给出一个示例结构(字段为示例设计,数值为合理假设,非实测结果):

trade_id | trade_ts | price | size | snap_ts | bid1 | ask1 | bid1_sz | ask1_sz
T1       | 160       | 10.05 | 300  | 100     | 10.03| 10.05| 800     | 500
T2       | 255       | 10.02 | 200  | 200     | 10.02| 10.04| 600     | 700

派生字段:
side_label   = buy / sell / uncertain
penetration  = 成交价相对 ask1(或 bid1) 的档位差
spread       = ask1 - bid1
snap_age     = trade_ts - snap_ts   (快照陈旧度)

其中 snap_age 是质量校验的关键指标。若某笔成交的 snap_age 接近或超过快照周期,说明它引用的报价可能已失效,应标记为低置信样本。实践中可设定阈值,例如快照周期为 100 ms 时,snap_age > 80 ms 的样本进入复核队列,而不是直接进入训练集。

建议在数据集中同时保留“原始成交方向字段”(若数据源提供)与“推断方向标签”,两者不一致的样本正是验证标注误差的高价值对象,可用于反查对齐规则或快照频率是否合理。

五、常见对齐陷阱

第一,时区与单位不统一:一侧是毫秒时间戳,另一侧是秒级浮点,直接比较会整体错位。入库前统一转换为整数毫秒。第二,快照乱序到达:按接收顺序存储的快照可能时间倒挂,匹配前必须按交易所时间排序。第三,成交聚合:部分数据源把同一毫秒的多笔成交合并为一条,导致价格与数量失真,应优先使用逐笔明细。第四,零成交区间:长时间无成交时快照仍在更新,as-of join 会引用很久以前的快照,需用 snap_age 截断。

完成对齐与关联后,数据集才具备方向推断的基础。此时每条样本都携带“成交价、当时买一卖一、价差、穿透深度、快照陈旧度”这组可解释特征,后续无论是规则标注还是模型学习,都能在同一时间语义下被一致地评估。