第三章 数据工程基础:多源数据采集、数据清洗、特征对齐、时间序列处理
各位同学,欢迎来到实战课的第三讲。说实话,很多做量化的人,一上来就研究策略、调参数,结果模型跑起来全是噪音。为什么?因为数据没处理好。我见过太多团队,策略逻辑再漂亮,数据源一塌糊涂,最后回测曲线漂亮得像假的一样——嗯,其实就是假的。
今天这一章,咱们就把数据工程这个地基打牢。说白了,数据工程就是四个步骤:采集、清洗、对齐、处理。每一步都有坑,我一个个带你们踩一遍。
3.1 多源数据采集:别让数据源成为你的短板
做跨市场交易,数据源不可能只有一个。股票、期货、外汇、加密货币,每个市场的数据格式、频率、质量都不一样。我个人习惯,先把数据源分成三类:
- 交易所官方API:最可靠,但有限流,而且有些历史数据要付费
- 第三方数据商:比如Wind、Bloomberg、Quandl,数据全但贵
- 爬虫抓取:免费但脏,适合辅助验证
我在项目中遇到过一个问题:同时拉取A股和美股数据,A股是tick级,美股是分钟级,时间戳格式还不一样。你想想看,如果不对齐,后面做特征工程全是错的。
3.2 数据清洗:脏数据是策略的毒药
数据清洗听着简单,做起来全是细节。我刚开始做量化时,觉得清洗就是去掉空值。结果有一次回测收益高得离谱,一查发现是某天数据缺失,程序自动用前值填充,导致信号连续触发。嗯,从那以后我再也不敢轻视清洗了。
常见的脏数据问题:
- 缺失值:不能简单删除或填充,要看上下文。比如停牌日的数据,填充前值反而合理
- 异常值:比如价格突然跳涨100倍,多半是数据录入错误。我习惯用3σ原则或IQR方法检测
- 重复数据:API重连时容易产生重复行,必须去重
- 时间戳错乱:比如某条数据的时间戳比前一条还早,这通常是网络延迟导致的
3.3 特征对齐:跨市场交易的核心难点
特征对齐,说白了就是把不同频率、不同维度的数据,放到同一个时间轴上。举个例子:你要用日线级别的宏观经济数据,去预测分钟级别的股价波动。怎么对齐?
我常用的对齐策略有三种:
| 对齐方式 | 适用场景 | 注意事项 |
|---|---|---|
| 前向填充 | 低频数据对齐到高频 | 避免未来信息泄露 |
| 后向填充 | 高频数据聚合到低频 | 注意聚合方式(均值/中位数) |
| 插值法 | 缺失值较少的情况 | 线性插值可能引入偏差 |
我曾经犯过一个低级错误:用当天的收盘价去预测当天的涨跌。你想想看,这不就是作弊吗?特征对齐时,一定要确保所有特征都是「已知信息」,不能包含未来数据。
3.4 时间序列处理:让数据说话
时间序列处理,是量化交易的核心技能。说白了,就是把原始价格数据,变成模型能理解的「特征」。我常用的处理方式包括:
- 差分处理:价格序列通常非平稳,差分后变成收益率序列,模型更容易学习
- 滚动统计:比如过去20天的均值、标准差,用来刻画趋势和波动
- 季节性分解:有些品种有明显的日间效应或周内效应,分解后能提取规律
- 归一化/标准化:不同品种的价格量级不同,必须统一到同一尺度
这里我特别想强调一点:时间序列的划分必须严格按时间顺序。不能用未来的数据去训练模型,也不能用随机打乱的方式做交叉验证。我见过有人用K折交叉验证做时间序列,结果模型在测试集上表现极好,实盘一塌糊涂——因为时间顺序被打乱了,模型学到了「未来信息」。
3.5 知识体系总览
下面这张图,是我自己总结的数据工程核心流程。每次做新项目,我都会先过一遍这张图,确保没有遗漏。
3.6 实战代码示例
光说不练假把式。下面这段代码,是我在实际项目中常用的数据清洗流程。你们可以直接拿去用,但记得改参数。
import pandas as pd
import numpy as np
def clean_market_data(df):
"""
多市场数据清洗函数
df: DataFrame,必须包含 'timestamp', 'open', 'high', 'low', 'close', 'volume'
"""
# 1. 去重
df = df.drop_duplicates(subset=['timestamp'])
# 2. 时间戳排序
df = df.sort_values('timestamp')
# 3. 异常值检测(3σ原则)
for col in ['open', 'high', 'low', 'close']:
mean = df[col].mean()
std = df[col].std()
df = df[(df[col] > mean - 3*std) & (df[col] < mean + 3*std)]
# 4. 合理性校验
df = df[df['high'] >= df['low']]
df = df[df['volume'] > 0]
# 5. 缺失值处理(前向填充)
df = df.fillna(method='ffill')
return df
# 使用示例
# raw_data = pd.read_csv('market_data.csv')
# clean_data = clean_market_data(raw_data)
3.7 总结
数据工程这件事,说白了就是「磨刀不误砍柴工」。我见过太多人急着跑模型,结果数据质量不过关,浪费了大量时间。记住:垃圾进,垃圾出。数据工程做得好,模型训练事半功倍;做不好,再牛的算法也是白搭。
嗯,这一章的内容就到这里。你们回去之后,可以拿自己手头的数据跑一遍清洗流程,看看能发现多少问题。相信我,第一次跑完,你可能会怀疑自己之前做的策略是不是都在瞎搞——我当年就是这样。