背景 今天对 BTC 量化交易模型进行了一次深度审核,发现了一个严重的数据泄露问题,修复后回测表现反而更好了。
问题发现 训练集划分问题 审核 train_model.py 时发现,模型训练使用了 train_test_split 随机划分数据集:
X_train, X_val, y_train, y_val = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y ) 问题:时间序列数据不能随机划分!
随机划分会导致验证集包含训练集之后的数据,模型在验证时实际上"看到了未来",导致验证集性能虚高。
回测脚本审核 回测脚本本身没有数据泄露问题:
特征全部向后看(rolling/ewm) 标签生成正确(shift(-12) 向前看) 逐笔模拟没有用未来数据 修复方案 将随机划分改为时间序列划分:
# 修复前 X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, stratify=y) # 修复后 split_idx = int(len(X) * 0.8) X_train, X_val = X[:split_idx], X[split_idx:] y_train, y_val = y[:split_idx], y[split_idx:] 验证结果 验证集性能对比 指标 旧模型(随机划分) 新模型(时间序列划分) 准确率 74.2% 70.0% Macro F1 0.69 0.62 验证集性能下降了,但这是正常的——去掉了"作弊"后才是真实泛化能力。
回测对比(固定仓位 $10,000) 指标 旧模型 新模型 变化 总收益 +68.87% +75.57% +6.7% ✅ 最大回撤 -0.58% -0.62% -0.04% 夏普比率 15.00 16.03 +1.03 ✅ 胜率 88.0% 88.4% +0.4% 盈亏比 1.05 1.22 +0.17 ✅ 结论:时间序列划分训练的模型,回测表现更好!
...