4. 逐笔数据源接入与原始校验
逐笔数据管线的一切下游计算——快照重建、指标聚合、异常检测——都建立在“原始逐笔记录可信”这一前提上。如果接入环节把一条字段错位、时间戳倒序或价格精度错误的记录放进了管线,后续再精巧的校验逻辑也只能在错误数据上做二次加工。因此本节聚焦管线最前端的三件事:格式校验、字段完整性检查、初始快照比对。它们共同回答一个问题:这批刚进来的逐笔数据,是否可以被信任并进入后续处理。
一、接入时的格式校验:先确认“能解析”,再谈“对不对”
逐笔数据通常以两种形态到达:交易所或数据商推送的实时流(如基于 TCP 的二进制/文本协议),以及落盘的逐笔成交/逐笔委托文件(CSV、JSON Lines 或自定义二进制)。无论哪种形态,第一步都是结构级校验,即验证记录能否按约定格式被完整切分和解析。
以常见的逐笔成交文本行为例,约定字段顺序为:证券代码, 成交时间, 成交编号, 成交价格, 成交数量, 买卖方向, 通道号。格式校验至少要覆盖以下几点:
- 字段数量:按分隔符切分后字段数必须等于约定数量,多一个或少一个都说明记录被截断或串行。
- 类型可转换:价格、数量、时间必须能转换为数值或时间类型;转换失败即判为格式错误。
- 编码与分隔符:确认字符编码(如 UTF-8/GBK)与分隔符一致,避免中文或特殊字符导致错位。
- 记录边界:流式接入时,一条记录必须完整结束(换行或长度前缀匹配),防止半包被当作完整记录解析。
实操中建议把格式校验写成“解析即校验”的函数:解析成功返回结构化对象,失败则记录原始行、行号、失败原因,并进入隔离区而不是直接丢弃。这样既保证管线不被脏数据污染,又保留了排查线索。
# 示例:逐笔成交行格式校验(示例参数,非实测)
def parse_tick(line, lineno):
parts = line.rstrip("\n").split(",")
if len(parts) != 7:
return None, f"line {lineno}: 字段数={len(parts)},期望7"
code, t, trade_id, price, qty, side, chan = parts
try:
price = float(price); qty = int(qty)
except ValueError:
return None, f"line {lineno}: 数值转换失败"
if price <= 0 or qty <= 0:
return None, f"line {lineno}: 价格/数量非正"
return dict(code=code, time=t, trade_id=trade_id,
price=price, qty=qty, side=side, chan=chan), None
二、字段完整性检查:区分“缺失”与“非法”
格式能解析,不代表字段内容可用。字段完整性检查要逐字段判断三类问题:空值、越界、枚举非法。以逐笔委托为例,关键字段包括证券代码、委托时间、委托编号、方向、价格、数量、委托类型。检查要点如下:
| 字段 | 完整性规则(示例) | 典型异常 |
|---|---|---|
| 证券代码 | 非空,符合市场代码规则(如6位数字+市场后缀) | 空串、含空格、长度不符 |
| 委托时间 | 可解析为 HH:MM:SS 或毫秒时间戳,落在交易时段内 | 时间缺失、超出 09:15–15:00 |
| 方向 | 取值属于 {买, 卖} 或约定枚举 | 空值、未知枚举 |
| 价格 | 大于0,且符合最小价格变动单位 | 0、负数、精度超限 |
| 数量 | 正整数,且为最小交易单位整数倍 | 0、负数、非整倍 |
这里要特别强调“缺失”与“非法”要分开统计。缺失往往指向接入链路问题(字段没推、截断、映射表缺列),非法则更多指向数据源本身或单位/精度约定不一致。两类问题的处置路径不同:缺失应回查接入配置与协议版本,非法应回查数据源口径与字段映射。把两者混在一个“错误率”里,会让排障失去方向。
三、初始快照比对:用“已知正确”锚定“刚接入”
格式与字段检查只能保证单条记录“长得像对的”,无法发现系统性偏差,例如价格整体放大了100倍、买卖方向被整体颠倒、时间戳统一偏移了时区。这类问题最有效的发现手段是初始快照比对:选取一个已知正确的基准时点(如开盘前快照或上一交易日收盘快照),用接入的逐笔数据从该基准开始重放,重建出目标时点的快照,再与数据源提供的官方快照逐字段比对。
比对的核心是“同口径”:两边必须是同一时点、同一证券范围、同一字段定义。实操中通常比对以下字段:最新价、成交量累计、成交额累计、买一/卖一价量、委托笔数。若重放快照与官方快照在这些字段上一致(在约定容差内),说明接入的逐笔数据在方向和量级上没有系统性错误;若出现整体性偏差,则优先怀疑单位、精度、方向映射或时区。
四、把三项校验串成可执行的接入闸门
三项校验不应各自为政,而应组成一道“接入闸门”:格式校验不过的记录进隔离区;字段完整性检查按字段维度输出缺失率与非法率;快照比对给出整体一致性结论。闸门的放行条件建议明确为:格式错误率低于约定阈值、关键字段缺失率为零、快照比对在容差内一致。任一条件不满足,则阻断下游并输出诊断报告。
下面是一份可直接参考的接入校验记录表,用于每次数据源接入或口径变更后填写:
| 检查项 | 检查内容 | 示例结果 | 结论 |
|---|---|---|---|
| 格式校验 | 字段数、类型转换、记录边界 | 10万行中12行字段数异常 | 隔离12行,其余放行 |
| 字段完整性 | 空值、越界、枚举非法 | 方向字段空值0,价格越界3条 | 越界记录回查数据源 |
| 快照比对 | 最新价、累计量额、买卖一档 | 500只证券中498只一致 | 2只差异需定位 |
| 综合判定 | 三项是否同时满足放行条件 | 差异证券已定位为停牌无成交 | 放行 |
最后需要强调一个容易被忽视的点:初始快照比对要保留可复现的基准。基准快照、重放起止时间、比对字段与容差都应记录在案。这样当后续某天发现数据异常时,可以回到最近一次通过的基准重新比对,快速判断问题是“一直存在但没发现”还是“某次变更后引入”。接入环节的严谨,正是整条逐笔数据管线可信度的起点。