4. 数据获取与处理:量化策略的“原材料”准备
做量化交易,说白了就是“数据喂进去,策略跑出来”。
数据质量直接决定了策略的生死。我见过太多人,策略逻辑写得天花乱坠,结果数据一塌糊涂,回测曲线漂亮得像假的一样,实盘一跑就崩。嗯,这里咱们得把地基打牢。
4.1 数据获取:从哪拿货?
国内做商品期货,我个人最常用的两个库是 tushare 和 akshare。它们都是免费开源的,但风格不太一样。
- tushare:老牌库,数据质量稳定,但部分高级接口需要积分。适合做深度研究。
- akshare:更新快,接口丰富,几乎覆盖了所有国内金融数据源。适合快速验证想法。
我一般这么选:如果是做日内高频,用 akshare 的 tick 数据;如果是做日线级别策略,tushare 的复权数据更省心。
核心原则:数据源要稳定,接口要可重复调用。别用爬虫去扒网页,那是给自己挖坑。
4.2 数据清洗:把脏东西筛掉
拿到的原始数据,就像刚从菜市场买回来的菜——你得先摘掉烂叶子。
常见的脏数据有:
- 空值:某天没交易?或者数据源漏了?
- 异常值:价格突然跳涨100倍?那肯定是数据错误。
- 重复值:同一根K线出现了两次。
我在项目中遇到过最离谱的一次,是某个品种的夜盘数据因为服务器时间错乱,导致凌晨3点的数据被标记成了下午3点。嗯,那一次回测直接给我整出了年化500%的“神迹”。
清洗的常规操作:
# 用pandas做清洗,简单粗暴
import pandas as pd
df = pd.read_csv('future_data.csv')
# 1. 删除全空的行
df.dropna(how='all', inplace=True)
# 2. 填充缺失值(用前一天的收盘价)
df['close'].fillna(method='ffill', inplace=True)
# 3. 剔除异常值(比如价格超过3倍标准差)
mean = df['close'].mean()
std = df['close'].std()
df = df[(df['close'] > mean - 3*std) & (df['close'] < mean + 3*std)]
# 4. 去重
df.drop_duplicates(subset=['datetime', 'symbol'], keep='last', inplace=True)
我的小技巧:清洗完数据后,一定要做一次可视化检查。把价格曲线画出来,肉眼扫一遍,很多问题一眼就能看出来。
4.3 缺失值处理:别让数据“断片”
期货市场有夜盘、有节假日,数据天然就是不连续的。缺失值处理,不是简单地把空的地方填上就完事了。
常见的处理方式:
| 方法 | 适用场景 | 我的评价 |
|---|---|---|
| 向前填充(ffill) | 非交易时段(如夜盘休市) | 最常用,简单有效 |
| 向后填充(bfill) | 数据开头缺失 | 慎用,容易引入未来信息 |
| 插值法 | 日内分钟级数据 | 适合平滑处理,但别用在跳空缺口上 |
| 直接删除 | 缺失比例小于5% | 最干净,但会损失样本 |
我曾经犯过一个错:用线性插值去填补日线级别的缺失值。结果把两个不同合约的跳空缺口给“平滑”掉了,回测时策略表现完美,实盘一开就亏。你想想看,跳空缺口本身就是重要的市场信息,怎么能随便抹掉呢?
注意:处理缺失值时,千万别引入“未来数据”。比如用当天的收盘价去填充当天的开盘价,那就是作弊。
4.4 数据对齐:让不同品种“步调一致”
做多品种策略时,最头疼的就是数据对齐。螺纹钢和铁矿石的交易时间不完全一样,节假日也可能不同。
对齐的核心思路:以时间戳为索引,强制对齐到同一时间轴。
# 假设你有两个品种的DataFrame
rb = pd.DataFrame(...) # 螺纹钢
i = pd.DataFrame(...) # 铁矿石
# 合并时间索引
all_dates = rb.index.union(i.index)
# 重新索引,缺失值用NaN填充
rb_aligned = rb.reindex(all_dates)
i_aligned = i.reindex(all_dates)
# 然后统一处理缺失值
rb_aligned.fillna(method='ffill', inplace=True)
i_aligned.fillna(method='ffill', inplace=True)
这里有个坑:不同交易所的节假日不同。比如上期所和郑商所的休市安排就不一样。我建议直接用 交易日历 来对齐,别自己手动去数日子。
4.5 复权处理:还原真实的交易场景
期货的复权和股票不太一样。股票复权是为了消除分红送股的影响,而期货复权主要是处理 换月 带来的价格跳空。
举个例子:螺纹钢主力合约每个月都会换一次。旧合约到期前,价格是4000,新合约开盘可能是3900。如果你直接把两个合约的价格连起来,就会看到一个莫名其妙的“暴跌”。
常用的复权方法:
- 前复权:调整历史价格,让它们和当前价格可比。适合看趋势。
- 后复权:调整当前价格,让它们和历史价格可比。适合算收益。
- 等比复权:按比例调整,保持收益率不变。我个人最推荐这个。
我的经验:做回测时,一定要用复权后的连续合约。直接用主力合约的原始数据,换月那天你的策略会“自动”产生一笔莫名其妙的盈亏。
下面这张图,是我自己总结的数据处理全流程,你可以照着这个框架来搭建你的数据管道:
嗯,数据这块儿就讲这么多。记住一句话:花80%的时间处理数据,花20%的时间写策略。数据干净了,策略自然就稳了。
避坑指南:我曾经因为数据对齐没做好,导致两个品种的买卖信号差了1天,回测时年化收益差了20%。从那以后,我每次跑回测前都会先打印出数据的时间范围,确认一下。