4. 盘中数据采集与清洗实战
盘中信号有效性评估的前提,是拿到一份“时间可信、口径一致、异常可控”的高频数据底稿。逐笔成交、快照行情、委托队列这三类数据分别刻画了“成交发生了什么”“盘口此刻长什么样”“买卖意愿如何排队”,它们的采集频率、字段结构和时间语义差异很大。本节围绕这三类数据的获取方式、时间对齐与异常值处理展开,目标是让读者能够独立搭起一条可复现的盘中数据清洗链路。
一、三类数据的获取方式与字段要点
逐笔成交记录每一笔撮合成交,核心字段通常包括成交时间(精确到毫秒或更细)、证券代码、成交价、成交量、成交方向(主动买/主动卖或买卖盘标志)、成交编号。获取途径主要有两类:一是交易所行情网关推送的逐笔成交流,二是券商或数据商提供的历史逐笔文件。实盘采集时要注意成交编号的连续性,它是后续去重和乱序修复的关键。
快照行情按固定频率(常见为每3秒一档,部分场景为逐秒)推送盘口切片,字段包括快照时间、最新价、成交量累计值、成交额累计值、买一至买十价与量、卖一至卖十价与量。快照是“截面数据”,它不记录两次快照之间的过程,因此不能直接用快照成交量差分替代逐笔成交,否则会丢失盘中瞬时冲击信息。
委托队列数据描述买一/卖一价位上的逐笔委托排队情况,字段包括委托时间、委托价格、委托数量、买卖方向、委托编号以及该笔委托在队列中的位置变化。它比快照更细,能反映“盘口挂单是真实堆积还是频繁撤补”。采集时需重点关注委托编号与撤单记录的配对关系,否则队列长度会被高估。
二、时间对齐:先统一时基,再谈拼接
时间对齐的第一步是统一时基。建议全部转换为交易所时区的毫秒时间戳,并明确约定:所有“前向填充”只允许用“已经发生的最近一条数据”,禁止用未来数据回填历史时点,否则会引入前视偏差,让信号评估结果虚高。
具体做法上,逐笔成交与委托队列属于事件流,天然按时间排序;快照属于周期截面。将事件流对齐到快照时点,常用“区间归属”而非“最近邻”:对每个快照时点 t,统计 (t−Δ, t] 区间内的逐笔成交笔数、成交量、主动买卖差额,Δ 取快照间隔(如3秒)。这样每个快照都对应一段“刚过去”的成交行为,语义清晰且无未来信息。
委托队列与快照的对齐则要注意“队列是状态量”。同一价位在两次快照之间可能经历多次挂撤,正确做法是保留委托事件序列,在快照时点重建该价位的队列快照,而不是简单取最近一条委托记录。若数据量较大,可按“价位+方向”分组,用委托编号做增量维护。
# 示例:将逐笔成交聚合到3秒快照区间(伪代码)
snapshots = load_snapshots("snap_20240603.csv") # 含 snap_time
trades = load_trades("trade_20240603.csv") # 含 trade_time, price, volume, side
trades.sort_values("trade_time", inplace=True)
snapshots.sort_values("snap_time", inplace=True)
for t in snapshots["snap_time"]:
window = trades[(trades.trade_time > t - 3000) & (trades.trade_time <= t)]
snapshots.loc[t, "trade_cnt"] = len(window)
snapshots.loc[t, "trade_vol"] = window.volume.sum()
snapshots.loc[t, "active_buy"] = window.loc[window.side == "B", "volume"].sum()
snapshots.loc[t, "active_sell"] = window.loc[window.side == "S", "volume"].sum()
上述示例参数(3秒窗口、买卖方向字段名)属于教学假设,实际使用时需按数据商字段定义调整。对齐完成后应抽查若干时点,确认“快照累计成交量差分”与“区间逐笔成交量之和”在合理误差内一致,这是检验对齐是否正确的一道有效关卡。
三、异常值处理:识别、标记、留痕
盘中高频数据的异常大致分四类,处理原则是“先标记、后决策,不轻易删除”。
- 重复与乱序:逐笔成交按成交编号去重,按交易所时间重排;若同一编号出现价格或数量不一致,保留首条并记录冲突。
- 时间戳异常:出现非交易时段时间、时间倒退或跨日跳变时,标记为可疑,不参与区间聚合,避免污染快照特征。
- 价格与数量越界:成交价超出当日涨跌停价、成交量为零或为负、快照买一价大于卖一价(交叉盘口),均属硬异常,应单独隔离。
- 统计型离群:对成交量、主动买卖差等指标用滚动分位数或中位数绝对偏差(MAD)识别极端值,超过阈值只做标记,保留原始值供复核。
以交叉盘口为例,若某快照出现买一价 10.02、卖一价 10.01,说明该切片撮合状态异常或字段错位。处理时不应直接交换价格,而应将该快照标记为不可用,并在评估时跳过该时点,同时统计异常占比。若某只标的当日异常快照占比超过 1%,应回查采集链路而非继续使用。
四、可执行的清洗检查清单
下面这份清单可直接用于每日盘后数据验收,字段与阈值可按标的和策略调整,示例阈值仅作教学参考。
| 检查项 | 对象 | 判断方法 | 示例阈值/处理 |
|---|---|---|---|
| 成交编号唯一性 | 逐笔成交 | 按编号计数去重 | 重复率>0.1% 回查采集 |
| 时间单调性 | 三类数据 | 相邻时间戳差分 | 出现负值即标记乱序 |
| 累计量一致性 | 快照 vs 逐笔 | 快照累计量差分对比区间成交和 | 偏差>2% 标记该区间 |
| 盘口合法性 | 快照 | 买一价≤卖一价 | 交叉即隔离该快照 |
| 队列配对完整性 | 委托队列 | 委托与撤单编号配对 | 未配对委托单独统计 |
| 离群值比例 | 成交量/买卖差 | 滚动MAD识别 | 超3倍MAD仅标记 |
完成上述步骤后,得到的底稿应满足三个条件:每个快照时点都有明确的成交聚合结果、盘口状态和队列状态;所有异常都有标记字段和原因码;任意一个特征值都能回溯到原始记录。只有这样的底稿,后续做分时段信号有效性对比时,才不会把采集缺陷误判为信号失效。