一、行情数据清洗概述
1.1 数据清洗的定义与重要性
数据清洗,说白了就是给数据「洗澡」。
把脏的、乱的、不靠谱的数据处理干净。我做了这么多年数据工程,见过太多「垃圾进,垃圾出」的惨案。你想想看,如果原始数据就有问题,后面再牛的模型也是白搭。
具体来说,数据清洗包括:
- 缺失值处理——比如某条行情记录里价格字段是空的
- 异常值检测——比如突然冒出一个涨了1000%的离谱数据
- 重复数据去重——比如同一笔成交被推送了两次
- 格式统一——比如时间戳有的是毫秒级,有的是秒级
核心观点:数据清洗不是可有可无的「锦上添花」,而是数据工程的「地基」。地基不稳,楼盖得越高越危险。
我在项目中遇到过一件事:某次做回测,策略明明很漂亮,但收益曲线就是不对劲。查了三天,最后发现是某天的行情数据里混入了「测试数据」——交易所的模拟盘数据没被过滤掉。嗯,从那以后,清洗流程里我永远把「数据源校验」放在第一步。
1.2 行情数据的特殊性
行情数据跟普通数据不一样。它有三个特点,让清洗变得特别棘手。
高频
毫秒级甚至微秒级的数据流。你想想看,A股一天的Level-2行情数据,光逐笔成交就有几千万条。如果是期货或者加密货币,数据量更大。
我个人的习惯是:高频数据清洗,绝对不能逐条处理。必须用批处理+流式处理的混合架构。
海量
单日数据量轻松上GB,一个月就是几十TB。传统的关系型数据库?别想了,根本扛不住。
我曾经用MySQL存过一周的行情数据,查询一次要等十几分钟。后来换了ClickHouse,同样的查询只要几秒钟。工具选对,事半功倍。
时序
行情数据是严格按时间顺序排列的。时间戳就是它的「身份证」。但问题来了——
- 网络延迟会导致数据乱序到达
- 不同交易所的时间基准可能不同
- 同一笔数据可能被重复推送
注意:时序数据的清洗,最忌讳「先到先得」。必须做时间对齐和序列校正。否则你的K线图可能会画出「穿越时空」的蜡烛来。
1.3 清洗流程总览
下面这张图是我自己总结的清洗流程。做了这么多年,改了好几版,现在这个结构我觉得最稳。
整个流程看起来是线性的,但实际上有个反馈循环。什么意思呢?
比如你在「异常检测」阶段发现了一批奇怪的数据,不能直接扔掉就完事。你得回溯到「数据采集」阶段,看看是不是源端出了问题。我曾经遇到过一家数据商,他们的某个字段在特定时间段内全部偏移了一位——这种问题不反馈回去,永远修不好。
我的经验:清洗流程一定要做「可追溯」。每条被清洗掉的数据,都要记录原因和时间。这样出了问题才能追责,也方便后续优化清洗规则。
1.4 清洗策略的选择
不同的场景,清洗策略差别很大。我整理了一个表格,方便你对照:
| 场景 | 清洗策略 | 常用工具 | 注意事项 |
|---|---|---|---|
| 实时交易 | 轻量级过滤,延迟优先 | Flink、Kafka Streams | 宁可漏数据,不可停服务 |
| 历史回测 | 严格清洗,质量优先 | Pandas、Spark | 必须做数据对齐和复权 |
| 量化研究 | 灵活清洗,保留原始数据 | Python + Jupyter | 清洗规则要可复现 |
| 监管报送 | 全量清洗,审计优先 | ETL工具 + 数据库 | 每条记录都要有审计日志 |
你看,同样是行情数据,用途不同,清洗的「度」完全不一样。实时交易里你不可能花500毫秒去算一个插值,但历史回测里你可以慢慢精修。
我个人建议:永远保留一份原始数据。不管清洗规则多完善,总有你没想到的情况。留一份「原汁原味」的数据,哪天发现清洗逻辑有问题,还能重新来过。
一句话总结:行情数据清洗,不是把数据「洗白」,而是把数据「洗对」。干净的数据,是量化交易的基石。