4. 数据采集与清洗:Tick数据实时采集架构、去重、异常值过滤、时间对齐
高频Tick数据的质量直接决定坏账率监控模型的成败。原始行情流中夹杂着重复推送、延迟乱序、极端异常值以及交易所间的时间戳偏差。本章围绕实时采集架构、去重、异常值过滤与时间对齐四个核心环节,构建一套生产级的数据清洗管线。
4.1 实时采集架构
Tick数据采集层采用“网关-缓冲-分发”三层解耦架构,确保低延迟与高可用。网关层直连交易所行情推送接口(如CTP、FIX/FAST协议),缓冲层使用内存队列或Kafka削峰,分发层将清洗后的数据推送给下游策略与风控模块。
架构要点: 网关层不参与业务逻辑,只做协议转换与心跳维持;缓冲层必须支持数据回放(Replay),用于故障恢复后的数据补录。
4.2 数据去重
交易所网关在重连或网络抖动时可能重复推送同一笔Tick。去重策略采用“交易所时间戳 + 本地序列号”联合主键,在缓冲层消费端做幂等性校验。
| 去重层级 | 实现方式 | 延迟影响 | 适用场景 |
|---|---|---|---|
| 网关层 | 基于消息ID(如FIX的MsgSeqNum)去重 | 低(< 1μs) | 标准FIX/FAST协议 |
| 缓冲层 | Kafka幂等生产者 + 消费者去重缓存 | 中(~1ms) | 分布式部署、多路订阅 |
| 分发层 | 滑动窗口BloomFilter + 时间戳校验 | 低(~10μs) | 超高吞吐(>10万msg/s) |
实战建议: 在分发层使用滑动窗口BloomFilter,窗口大小设为5秒,误判率控制在0.1%以内。每笔Tick到达时先查BloomFilter,若命中则丢弃;未命中则插入并更新窗口。
4.3 异常值过滤
Tick数据异常值主要分为三类:价格异常、数量异常、逻辑异常。过滤规则必须兼顾实时性与准确性,避免误杀有效行情。
- 价格异常: 单笔Tick价格偏离前一笔超过阈值(如股指期货±1%),或价格超出当日涨跌停板。
- 数量异常: 成交量或持仓量为负值、单笔成交量超过合约最大下单手数。
- 逻辑异常: 买一价 ≥ 卖一价(盘口倒挂)、最新价不在买卖价区间内、时间戳早于上一笔。
# 异常值过滤核心逻辑(Python伪代码)
def filter_tick(tick: Tick, prev_tick: Tick, limits: LimitConfig) -> bool:
# 1. 价格异常
if abs(tick.price - prev_tick.price) / prev_tick.price > limits.price_deviation:
return False
if tick.price < limits.lower_limit or tick.price > limits.upper_limit:
return False
# 2. 数量异常
if tick.volume < 0 or tick.volume > limits.max_order_volume:
return False
# 3. 逻辑异常
if tick.bid_price >= tick.ask_price:
return False
if tick.last_price < tick.bid_price or tick.last_price > tick.ask_price:
return False
if tick.timestamp < prev_tick.timestamp:
return False
return True
注意: 异常值过滤不能直接丢弃后简单跳过,必须记录异常日志并触发告警。连续出现3笔以上异常Tick时,应暂停该合约的行情消费并检查数据源状态。
4.4 时间对齐
不同交易所、不同数据源的时间戳存在系统时钟偏差。时间对齐的目标是将所有Tick统一到同一时间基准上,消除因时钟漂移导致的坏账误判。
对齐策略采用“主时钟参考 + 线性插值”方案:
- 选取一个高精度时间源(如NTP服务器或交易所撮合引擎时间戳)作为主时钟参考。
- 对每个数据源计算与主时钟的固定偏移量(每5分钟校准一次)。
- 将Tick时间戳减去偏移量,得到对齐后的时间。
- 对于跨交易所的Tick,使用对齐后的时间进行排序与合并。
4.5 清洗管线集成
将去重、异常值过滤、时间对齐三个模块串联成一条数据清洗管线,在分发层内按顺序执行。管线采用责任链模式,每个环节独立可插拔,便于调试与灰度发布。
| 环节 | 输入 | 输出 | 关键指标 |
|---|---|---|---|
| 去重 | 原始Tick流 | 去重后Tick流 | 去重率(通常0.5%~2%) |
| 异常值过滤 | 去重后Tick流 | 干净Tick流 | 过滤率(通常0.1%~0.5%) |
| 时间对齐 | 干净Tick流 | 对齐后Tick流 | 对齐误差(< 1ms) |
生产级注意事项: 清洗管线必须支持背压(Backpressure)机制。当下游消费速度低于上游生产速度时,管线自动降级:优先丢弃时间戳最旧的Tick,保证最新行情数据优先处理。