Appearance
第 7 讲:过拟合——换一段时间再考
本讲要点
样本内最优的参数,换一段时间往往失效;这就是过拟合。
1. 第 6 讲与本讲各管什么
| 讲次 | 任务 | 关键词 |
|---|---|---|
| 第 6 讲 | 在同一段历史上扫描,找出收益率最高的均线参数 | 参数优化 / 样本内最优 |
| 第 7 讲 | 把该参数冻结,拿到另一段历史上再跑,看是否仍然成立 | 过拟合 / 样本外失效 |
第 6 讲得到的冠军是 MA5(相对定投仅高 0.82 个百分点)。本讲不再调参,只做验收。
| 窗口 | 区间 | 用途 |
|---|---|---|
| 选参窗 | 2021-01-01—2026-03-04 | 第 6 讲已选出 MA5 |
| 考试窗 | 2017-01-01—2021-12-31 | 冻结 MA5,与定投对照 |
若考试窗上 MA5 不再优于定投,说明选参窗里的「最优」更像巧合,而不是可迁移的规律。
本讲采用「换一段独立历史」做迁移检验。严格按时间先后的滚动外推(walk-forward)见后续专讲。
2. 完整代码
python
CHAMPION_MA = 5 # 第 6 讲冠军,冻结
df_select = load_df("2021-01-01", "2026-03-04")
dca_s = backtest_dca(df_select)["return"].iloc[-1]
ma_s = backtest_dca_with_ma(df_select, ma_period=CHAMPION_MA)["return"].iloc[-1]
df_test = load_df("2016-10-01", "2021-12-31")
dca_t = backtest_dca(df_test, trade_start="2017-01-01")["return"].iloc[-1]
ma_t = backtest_dca_with_ma(
df_test, ma_period=CHAMPION_MA, trade_start="2017-01-01"
)["return"].iloc[-1]
print(f"选参窗 定投: {dca_s:.2%} MA5: {ma_s:.2%} 差 {ma_s - dca_s:+.2%}")
print(f"考试窗 定投: {dca_t:.2%} MA5: {ma_t:.2%} 差 {ma_t - dca_t:+.2%}")
if ma_t < dca_t:
print("换一段时间后参数失效——这是过拟合。")脚本:easy-quant/code/07_overfitting.py
3. 运行结果
text
选参窗口(第6讲): 2021-01-01 → 2026-03-04
定投: 17.70%
MA5: 18.53% (买入 37/63)
相对定投: +0.82%
考试窗口: 2017-01-01 → 2021-12-31 (冻结 MA5,不再调参)
定投: 28.97%
MA5: 25.06% (买入 29/60)
相对定投: -3.90%
========================================
换一段时间后参数失效——这是过拟合。
小结:单标的叠规则易过拟合;下一单元进入池内动量轮动。
========================================| 窗口 | 定投 | MA5 | MA5 − 定投 |
|---|---|---|---|
| 选参窗 2021–2026 | 17.70% | 18.53% | +0.82% |
| 考试窗 2017–2021 | 28.97% | 25.06% | −3.90% |

本讲要强调的现象:参数在发现它的那段历史上有效(或略有效),换一段时间后失效甚至反转——这就是参数过拟合。
4. 为什么会过拟合
- 统计:在 24 个参数里挑第一,容易挑到「这段运气好」的 (N)。
- 市场:不同年份的涨跌结构不同,合身参数换窗不合身。
- 优势本来就薄:样本内只高 0.82 个百分点,符号反转并不奇怪。
5. 第一单元小结:单标的叠规则的风险
第 1–7 讲始终在同一只沪深 300ETF 上,做的是:
定投 → 加均线门禁 → 扫描最优 (N) → 换窗验收
这与入门阶段常见的 单票叠指标(在单一标的上叠加均线、MACD、RSI 等并反复调参)属于同一类路径。本单元实验表明:
- 样本内可以扫出「最优参数」;
- 换一段时间后,该参数往往不再成立;
- 因此:在单一标的上堆规则、调参数,有显著的过拟合风险,不能把样本内最优当作可部署结论。
规则可写、回测可做、基准可设——这些纪律仍然必要;但研究对象若长期停留在「一只票 + 一串指标」,研究空间容易耗在拟合噪声上。
6. 下一单元:主线策略——池内动量轮动
从第 8 讲起,转入本书主线:池内动量轮动。
| 本单元(弯路对照) | 下一单元(主线) | |
|---|---|---|
| 对象 | 单一 ETF / 单标的 | 先定义 Universe(股票池) |
| 信号 | 纵向叠均线等指标并调参 | 横截面比较相对强弱(动量) |
| 动作 | 猜单票买卖时点 | 定期按排名轮动持仓 |
| 检验 | 已见:换窗后参数易失效 | 对组合做基准对照与样本外检验 |
下一讲不再追问「哪条均线适合沪深 300」,而问:在约定好的池子里,谁相对更强、多久换一次、组合整体表现如何。
7. 整条线回顾
| 版本 | 策略 | 教训 |
|---|---|---|
| v0 | 定投 | 收益多半是市场给的 |
| v1 | 定投 + 均线 | 加判断不保证更好 |
| v2 | 参数扫描得 MA5 | 样本内最优很诱人 |
| v3 | MA5 换到 2017–2021 | 过拟合:换窗失效 |
面对漂亮回测,先问:这是规律,还是巧合?
→ 上一讲 · 下一讲:进入主线——动量轮动