跳到主要内容

Walk-Forward 与样本内外验证

直觉

防止过拟合最有效的工程手段是样本外验证:只在训练集上调参,在从不参与调参的测试集上检验。Walk-Forward 更进一步——滚动地「用过去选参、交易未来」,模拟策略在实盘中不断重新适应的过程,是稳健性检验的金标准。

样本内外划分

数据=训练集(IS)调参    测试集(OOS)只评估一次\text{数据} = \underbrace{\text{训练集(IS)}}_{\text{调参}} \;\big|\; \underbrace{\text{测试集(OOS)}}_{\text{只评估一次}}
  • 在 IS 上扫参数、选最优;
  • 用该参数在 OOS 上跑一次,报告结果;
  • 永远不要反过来在 OOS 上挑参数(那是选择偏差,等于作弊)。

Walk-Forward

把时间切成连续窗口:第 kk 段用「之前的数据」选参,交易「下一段」,拼接所有 OOS 段得到真实可得的累计表现。

「人话」解释:Walk-Forward 为什么可信?

它模拟了「你当时只能看到那些数据」的现实——每一步都只用过去、交易未来,没有任何事后信息。 拼接起来的曲线,是你这个策略真能实现的历史表现,不像单次 IS 拟合那样乐观。 如果 Walk-Forward 夏普还过得去,策略才算「稳健」而非过拟合。

可运行案例:IS 选参 → OOS 检验 + Walk-Forward

import quant
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('/data/spy_daily.csv', parse_dates=['date']).set_index('date')
close = df['adj_close']
n = len(close); split = int(n * 0.7)
is_p, oos_p = close.iloc[:split], close.iloc[split:]
grid = [(5,20),(10,30),(20,60),(20,120),(40,120)]

def sig(p, f, s):
  raw = (p.rolling(f).mean() > p.rolling(s).mean()).astype(float)
  return raw.replace(0, np.nan).ffill().fillna(0)
def sh(p, f, s):
  return quant.sharpe(quant.vector_backtest(p, sig(p,f,s), cost_bps=2.0, freq=252)['returns'], freq=252)

# 1) IS 选最优参数, 看 OOS 是否守得住
best = max(grid, key=lambda fs: sh(is_p, *fs))
print(f"IS 最优参数 {best}:  IS 夏普={sh(is_p,*best):.3f}   OOS 夏普={sh(oos_p,*best):.3f}  (通常下降)")

# 2) 选择偏差: 作弊地在 OOS 选最优(高估真实能力)
cheat = max(grid, key=lambda fs: sh(oos_p, *fs))
print(f"OOS 作弊最优 {cheat}:  夏普={sh(oos_p,*cheat):.3f}  ← 用未来选参, 不可信")

# 3) Walk-Forward: 用过去 3 年选参, 交易下 1 年
w, step = 252*3, 252
seg_sharpe = []
for start in range(w, n - step, step):
  train = close.iloc[start-w:start]
  test  = close.iloc[start:start+step]
  fs = max(grid, key=lambda x: sh(train, *x))
  seg_sharpe.append(sh(test, *fs))
print(f"\nWalk-Forward 各年 OOS 夏普: {[round(x,2) for x in seg_sharpe]}")
print(f"均值={np.mean(seg_sharpe):.3f}  正比例={np.mean([x>0 for x in seg_sharpe]):.0%}")
print("→ 不依赖某次幸运选参, 才是稳健策略。")

小结

  • 样本外验证:只在 IS 调参,OOS 只评一次;
  • 选择偏差:在 OOS 上挑参数 = 作弊,会高估;
  • Walk-Forward:滚动「用过去选参、交易未来」,是稳健性金标准。

模块 8 完成,M5(模块 5–8)全部交付。下一批 M6 将进入机器学习、风控与 Capstone

小测验

1. 在测试集(OOS)上反过来挑最优参数,属于?

2. Walk-Forward 每一步是怎么做的?

3. 为什么 Walk-Forward 比「单次全样本拟合」更可信?