3. 数据采集与预处理:交易所行情数据、订单数据、成交数据的获取与清洗
各位同学,咱们直接进入正题。
做异常交易识别,说白了就是跟数据打交道。你算法再牛,模型再炫,数据是脏的、乱的、缺的,那一切都是白搭。我见过太多团队,花80%的时间在调模型,结果最后发现是数据源出了问题——嗯,这种坑我踩过不止一次。
3.1 三大数据源:行情、订单、成交
交易所给咱们的数据,主要分三类。我习惯把它们比作「三层递进」的关系:
- 行情数据:最表层,就是价格、成交量、买卖盘口这些。说白了,是市场情绪的「快照」。
- 订单数据:中间层,记录了每一笔挂单、撤单的细节。谁在什么时间、什么价格、挂了多少单,全在这里。
- 成交数据:最底层,是实际发生的交易记录。每一笔买卖,谁跟谁成交,价格多少,量多少,清清楚楚。
你想想看,如果只看行情数据,你只能看到「价格涨了」。但结合订单数据,你就能看到「是不是有人在频繁挂单又撤单,故意制造假象」。这就是为什么我们做异常交易识别,必须把这三层数据打通。
核心观点:异常交易行为的本质,往往藏在订单层和成交层的「缝隙」里。行情数据只是表象。
3.2 数据获取:从哪里来,怎么拿?
我个人习惯把数据获取分成两种场景:
3.2.1 实时流式获取
做实时监控的时候,我们需要从交易所的行情网关订阅数据。常用的协议有:
- FIX协议:金融行业标准,稳定但有点重。
- Binary协议:各家交易所自己定义的,速度快,但解析麻烦。
- WebSocket:现在很多互联网券商用这个,轻量级,适合小团队。
我记得有一次,我们对接某家交易所的Binary协议,文档写得不清楚,结果解析出来的价格全是错的。后来我花了整整两天,对着原始二进制流一点一点对,才发现是字节序搞反了。嗯,这种坑,你们以后大概率也会遇到。
3.2.2 离线批量获取
做回测和模型训练的时候,我们一般从交易所的历史数据服务器拉取。常见格式有:
- CSV:简单,但大文件性能差。
- Parquet:列式存储,压缩率高,我强烈推荐。
- HDF5:适合科学计算,但生态不如Parquet。
我的建议:如果你们团队有大数据平台,直接用Parquet。如果只是个人研究,CSV也够用,但记得用gzip压缩一下。
3.3 数据清洗:脏数据是魔鬼
数据拿到手,别急着分析。先洗一遍。我总结了一套「四步清洗法」:
- 去重:同一个订单ID出现两次?删掉重复的。
- 补缺:某些字段为空?看情况填充或丢弃。
- 纠错:价格是负数?成交量是0?明显不合理,标记出来。
- 对齐:不同数据源的时间戳格式不一样?统一成毫秒级时间戳。
我曾经接手过一个项目,成交数据里居然有「负成交量」。查了半天,发现是交易所的某个网关在极端行情下产生了溢出错误。这种数据如果不洗掉,模型直接崩给你看。
3.3.1 常见脏数据类型
| 脏数据类型 | 典型表现 | 处理方法 |
|---|---|---|
| 重复数据 | 同一笔订单出现多次 | 按订单ID去重 |
| 缺失数据 | 价格、数量字段为空 | 前向填充或丢弃 |
| 异常值 | 价格超出涨跌停板 | 标记为异常,不参与训练 |
| 时间错乱 | 成交时间早于订单时间 | 按时间戳排序后检查 |
| 精度问题 | 价格小数点后位数不一致 | 统一精度,四舍五入 |
3.4 数据预处理:让数据「能用」
清洗完,还得预处理。这一步是为了让数据能被模型和规则引擎直接消费。
3.4.1 时间对齐
行情数据通常是毫秒级,订单数据可能是微秒级。我习惯统一对齐到毫秒,然后做重采样。比如把1秒内的所有订单聚合起来,计算挂单量、撤单率等特征。
3.4.2 特征衍生
原始数据里没有「撤单率」这个字段,但我们可以算出来:
# 伪代码示例
撤单率 = 撤单数量 / (挂单数量 + 撤单数量)
订单比 = 买单数量 / 卖单数量
价格偏离度 = (当前价格 - 最近成交均价) / 最近成交均价
这些衍生特征,才是识别异常交易的关键。我做过一个项目,光靠「撤单率」这一个特征,就抓出了好几个疑似对倒交易的账户。
3.4.3 标准化与归一化
不同股票的价格区间不一样,茅台几百块,某ST股几毛钱。如果不做标准化,模型会天然偏向高价股。我一般用Z-score标准化:
标准化价格 = (原始价格 - 均值) / 标准差
注意:标准化的时候,均值和标准差要用训练集的,不能用全量数据的。否则会造成数据泄露,模型在回测里表现很好,一上线就拉胯。
3.5 知识体系总览
下面这张图,是我自己总结的本章知识结构。你们可以保存下来,以后做数据预处理的时候对照着看。
3.6 避坑指南
最后,分享几个我踩过的坑:
- 时间戳陷阱:不同交易所的时间戳精度不一样,有的到秒,有的到微秒。合并数据前一定要先对齐,否则你会看到「成交时间早于订单时间」这种诡异情况。
- 涨跌停板数据:涨停的时候,卖单可能全部被吃掉,这时候的订单数据会「失真」。做特征工程时,要单独处理这种极端行情。
- 数据量预估:别小看数据量。一个中等规模的交易所,一天就能产生几亿条订单数据。如果不提前规划存储和计算资源,你的ETL任务跑着跑着就OOM了。
我的习惯:每次开始一个新项目,我都会先花一天时间,把数据源的所有字段、类型、取值范围全部列出来,做成一个数据字典。这步看似费时间,但后面能省你十倍的时间。
好了,数据采集与预处理这块,核心就是这些。记住一句话:数据质量决定了模型的天花板。你花再多时间在清洗上都不为过。