第二章:数据准备——外汇数据源选择与清洗

做回测这么多年,我踩过最大的坑,就是数据问题。你策略再牛,数据是垃圾,结果就是垃圾。说白了,回测的起点就是数据准备。这一章,我带你搞定外汇数据源的选择、清洗和对齐。

2.1 外汇数据源怎么选?

外汇市场没有统一的交易所,数据分散在各个流动性提供商手里。我个人习惯用下面几个数据源,各有优劣。

数据源 数据类型 优点 缺点
Dukascopy Tick、1分钟、5分钟等 免费、历史数据长(2003年起)、Tick级精度 偶尔有跳空、需自行清洗
TrueFX Tick、1分钟 机构级数据、质量高 需注册、部分数据收费
HistData.com 各种周期 整理好的CSV、直接可用 付费、更新频率一般
OANDA 1分钟、日线 API接口方便、实时数据 历史数据有限
我的建议:新手先用Dukascopy的免费数据练手。等策略成熟了,再考虑TrueFX或付费数据。我在项目中遇到过,用免费数据回测赚了30%,换到机构数据直接变亏——数据质量差异就这么大。

2.2 数据清洗——别让脏数据毁了你的策略

数据拿到手,第一件事不是跑策略,而是清洗。你想想看,外汇数据里常见的坑有哪些?

2.2.1 去除重复数据

同一个时间戳出现两次,这在Dukascopy的数据里偶尔会发生。我一般这样处理:

import pandas as pd

# 假设df是原始数据,包含'DateTime', 'Open', 'High', 'Low', 'Close', 'Volume'
df = df.drop_duplicates(subset='DateTime', keep='first')
df = df.sort_values('DateTime').reset_index(drop=True)

2.2.2 处理异常价格

有时候会出现价格瞬间暴涨暴跌,比如EUR/USD突然跳到1.5000,明显是数据错误。我的经验是:用3倍标准差过滤。

# 计算价格变化率
df['return'] = df['Close'].pct_change()
# 过滤掉超过3倍标准差的异常点
mean = df['return'].mean()
std = df['return'].std()
df = df[(df['return'] > mean - 3*std) & (df['return'] < mean + 3*std)]
注意:别把正常的市场波动当异常过滤了。比如2015年瑞郎黑天鹅事件,那是真实的市场行为,不是数据错误。我曾经因为过滤太狠,把那次大行情给洗掉了,回测结果完全失真。

2.3 数据对齐——不同时间框架的整合

做多品种回测时,数据对齐是个大问题。比如你要同时交易EUR/USD和GBP/JPY,它们的Tick数据时间戳可能不完全对齐。怎么办?

我的做法是:统一用1分钟K线作为基准。把所有数据都重采样到1分钟,然后做inner join。

# 重采样到1分钟
df_1min = df.resample('1T', on='DateTime').agg({
    'Open': 'first',
    'High': 'max',
    'Low': 'min',
    'Close': 'last',
    'Volume': 'sum'
}).dropna()

# 多品种对齐
merged = pd.merge(df_eur_1min, df_gbp_1min, on='DateTime', suffixes=('_eur', '_gbp'))

2.4 处理跳空与缺失值

外汇市场周末休市,周一开盘经常有跳空。还有节假日、数据源故障,都会导致缺失。嗯,这里要注意,不同策略对跳空的敏感度不一样。

2.4.1 跳空处理

我个人习惯分情况处理:

  • 趋势跟踪策略:保留跳空,因为跳空本身就是市场信息
  • 均值回归策略:建议填充跳空,否则容易触发假信号
  • 高频策略:必须用Tick数据,跳空区域直接跳过
# 检测跳空(价格变化超过正常范围)
df['gap'] = abs(df['Open'] - df['Close'].shift(1)) / df['Close'].shift(1)
# 标记跳空点
df['is_gap'] = df['gap'] > 0.005  # 0.5%的跳空阈值

2.4.2 缺失值填充

缺失值处理,我推荐三种方法:

方法 适用场景 代码示例
前向填充 短期缺失(几分钟) df.fillna(method='ffill')
线性插值 中期缺失(几小时) df.interpolate(method='linear')
删除 长期缺失(超过一天) df.dropna()
核心原则:缺失值处理没有银弹。我的经验是——先可视化看看缺失模式,再决定用哪种方法。别一上来就全删,有时候缺失本身就是一个信号。

2.5 知识体系总览

下面这张图,是我做数据准备时的完整流程。你可以把它当作一个检查清单。

外汇数据准备流程 数据源选择 Dukascopy / TrueFX 数据清洗 去重 / 异常过滤 数据对齐 重采样 / Join 跳空与缺失处理 前向填充 / 插值 / 删除 跳空处理策略 趋势跟踪:保留跳空 均值回归:填充跳空 高频策略:跳过跳空 ✅ 干净可用的数据
避坑指南:我曾经因为偷懒,没做数据对齐,直接拿不同时间戳的数据跑回测。结果策略信号频繁触发,实际交易时根本执行不了。后来花了整整两天重新清洗数据,才找到问题。所以,数据准备这一步,千万别省。

好了,数据准备好了。下一步就是把这些数据喂给回测引擎。记住一句话:垃圾进,垃圾出。数据质量决定了你回测结果的可信度。

专注资料整理