数据采集与清洗:交易数据源与质量管控

做量化风控这些年,我最大的体会就是:数据质量决定了模型的天花板。你算法再牛,喂进去的是垃圾,出来的还是垃圾。今天咱们就聊聊交易对手行为建模中最基础也最容易被忽视的一环——数据采集与清洗。

核心观点:数据清洗不是体力活,是技术活。它占掉整个建模流程60%以上的时间,但恰恰是这60%,决定了剩下40%的价值。

一、交易数据源:Level2与逐笔委托

先说说数据源。我个人习惯把交易数据分成两类:快照型数据流水型数据

  • Level2行情数据:每3秒一张快照,包含十档买卖盘口、逐笔成交、委托队列等。说白了,就是市场在某个时刻的“照片”。
  • 逐笔委托数据:每一笔挂单、撤单、成交的完整记录。这是“录像”,能还原交易的全过程。

我在项目中遇到过一个问题:用Level2数据做对手行为分析,发现某些账户的挂单模式很奇怪。后来换成逐笔委托数据一查,才发现是高频交易者在用“冰山订单”策略。Level2快照根本抓不到这种细节。

我的建议:如果条件允许,尽量用逐笔委托数据。Level2适合做宏观流动性分析,但对手行为建模需要微观层面的订单流信息。

二、数据清洗规则:别让脏数据毁了模型

数据清洗,说白了就是给数据“洗澡”。我总结了一套自己的清洗规则,分享给你:

清洗类型 具体规则 我踩过的坑
格式统一 时间戳转统一时区,价格单位统一 曾经遇到港股和A股时间戳混用,导致回测结果完全错位
去重 同一笔委托出现多次,保留最早一条 交易所数据偶尔会重传,不处理的话特征会翻倍
范围校验 价格不能为负,成交量不能为0 这个看似简单,但真有人把价格填成-1.00
逻辑校验 委托时间 < 成交时间 < 撤单时间 时间顺序错乱,通常是数据拼接时出的问题

嗯,这里要注意:清洗规则不是越严越好。太严会把正常数据也干掉,太松又留了脏数据。我一般会先跑一遍统计,看看异常值的分布,再定阈值。

三、缺失值处理:别随便填0

缺失值处理,很多人上来就填0或者填均值。你想想看,这合理吗?

举个例子:某只股票全天没有成交,那“逐笔成交”字段就是空的。如果你填0,模型会以为这只股票流动性极差。但实际情况可能是——它涨停了,没人卖。

我常用的几种处理方式:

  • 时间序列插值:用前后时刻的数据做线性插值,适合价格类字段
  • 业务规则填充:比如停牌期间的数据,直接标记为“停牌状态”
  • 模型预测填充:用其他特征预测缺失值,适合关键字段
  • 直接删除:缺失比例超过70%的字段,我建议直接扔掉

警告:千万不要在缺失值上偷懒。我曾经因为图省事,把所有缺失值填了-1,结果模型学出了一个“-1代表异常”的假规律。上线后遇到正常数据,模型直接崩了。

四、异常交易识别:抓出那些“不对劲”的订单

异常交易识别,是数据清洗中最有意思的部分。说白了,就是找出那些“不该出现”的交易行为。

我总结了几类常见异常:

  1. 价格异常:成交价偏离市场均价超过5%
  2. 数量异常:单笔委托量超过该股票日均成交量的10%
  3. 时间异常:在非交易时段出现的委托
  4. 频率异常:同一账户在1秒内提交超过100笔委托
  5. 模式异常:典型的“老鼠仓”交易——大单买入后小单卖出

怎么识别?我一般用统计方法+规则引擎的组合拳:

# 伪代码示例:异常交易识别流程
def detect_anomalous_trades(df):
    # 1. 统计方法:3-sigma原则
    price_mean = df['price'].mean()
    price_std = df['price'].std()
    df['price_anomaly'] = abs(df['price'] - price_mean) > 3 * price_std
    
    # 2. 规则引擎:硬阈值
    df['qty_anomaly'] = df['quantity'] > df['avg_daily_volume'] * 0.1
    
    # 3. 组合判断
    df['is_anomaly'] = df['price_anomaly'] | df['qty_anomaly']
    
    return df[df['is_anomaly'] == True]

我曾经遇到过一个案例:某账户每天固定时间点,用固定金额买入某只股票。从数据上看,这完全符合“正常交易”的定义。但结合时间序列分析,发现这个模式持续了整整3个月——明显是程序化交易。这种“正常中的异常”,才是最难抓的。

五、知识体系总览

说了这么多,咱们用一张图把整个数据采集与清洗的流程串起来:

数据采集与清洗知识体系 数据源层 Level2行情数据(3秒快照) 逐笔委托数据(完整流水) 数据清洗层 格式统一 去重处理 范围校验 逻辑校验 缺失值与异常处理层 缺失值:插值/填充/删除 异常识别:统计+规则 质量标记:保留/剔除 高质量建模数据集

这张图把整个流程分成了四层:数据源层、清洗层、处理层、输出层。每一层都有明确的输入输出,环环相扣。我每次做新项目,都会先画这么一张图,确保流程没有遗漏。

避坑指南:我曾经在数据清洗阶段漏掉了“时间戳对齐”这一步。结果模型训练时,把9:30:00的委托和9:30:03的快照当成同一时刻的数据。你想想看,3秒的延迟在高频交易里能差出多少个价位?从那以后,我每次都会专门写一个时间对齐的校验函数。

好了,数据采集与清洗这部分就聊到这儿。记住一句话:数据清洗不是苦力活,是建模的基石。你花在清洗上的每一分钟,都会在模型效果上得到回报。


公众号:蓝海数据掘金营,微信deep3321