Holdout Validation 阶段
阶段概述
定义
Holdout Validation (留存验证) 是在完全未参与任何设计环节的最终时间窗口上,验证策略方案是否仍然有效的阶段。
核心价值
- 提供最后的独立验证,防止策略过拟合历史数据
- 模拟真实的”盲测”环境,检验策略的泛化能力
- 作为进入生产环境前的最终门禁
关键约束
- 完全隔离:Holdout 窗口从未参与任何阶段的设计、调参或优化
- 单向验证:只能验证,不能根据结果回头调整任何参数
- 一次机会:只有一次验证机会,不能多次尝试后选择最优结果
阶段输入
必需的 Frozen Spec
来自 Backtest Ready 阶段的冻结规范:
| 输入项 | 说明 |
|---|---|
| 交易规则 | 完全冻结的买入、卖出、风控规则 |
| 参数组合 | 经过 Backtest 验证的最终参数 |
| Universe | 冻结的交易标的集合 |
| Whitelist | 通过验证的标的白名单 |
| Best Horizon | 冻结的持仓周期 |
| Thresholds | 冻结的阈值、分位切点 |
数据要求
- Holdout 窗口:在 Mandate 阶段划定,与 Train/Test/Backtest 完全独立
- 数据质量:必须通过 Data Ready 的所有质量检查
验证内容
1. 严格执行冻结规则
要求:
- 使用 Backtest 冻结的所有交易规则
- 使用 Backtest 冻结的参数组合
- 不得进行任何参数调优
- 不得进行规则微调2. 核心指标验证
收益指标:
- 累计收益率
- 年化收益率
- 胜率
风险指标:
- 最大回撤 (Max Drawdown)
- 夏普比率 (Sharpe Ratio)
- 收益波动率
稳定性指标:
- 月度/季度收益分布
- 回撤恢复时间
- 连续亏损次数3. 过拟合检查
详见下方”过拟合检查清单”
Holdout vs Backtest 的区别
| 维度 | Backtest | Holdout |
|---|---|---|
| 数据用途 | 可能有多轮参数优化 | 完全未参与设计 |
| 修改自由度 | 可调整规则和参数 | 完全冻结,只能验证 |
| 尝试次数 | 可能多次迭代 | 只有一次机会 |
| 目的 | 验证可交易性 | 验证泛化能力 |
| 结果性质 | 可能过拟合 | 真正的”盲测”结果 |
Formal Gate 要求
PASS 条件
收益要求:
- Holdout 收益为正(或符合 Mandate 设定的最低预期)
- 年化收益不低于 Backtest 的合理阈值(如 >60%)
风险要求:
- 最大回撤在可接受范围内
- 夏普比率符合最低标准
稳定性要求:
- 无明显过拟合信号
- 关键指标不显著退化CONDITIONAL PASS 条件
可能的情况:
- 收益略低于预期但稳定
- 回撤略大但在可控范围
- 某些次要指标不达标
要求:
- 必须明确记录不符合的条件
- 必须评估风险可控性
- 需要团队讨论决定是否进入下一阶段NO-GO 条件
触发条件:
- Holdout 收益为负
- 关键指标严重退化(如收益降低 >50%)
- 明显的过拟合信号
- 与 Backtest 结果严重不一致常见错误
错误 1:根据 Holdout 结果回头调整
错误行为:
- 看到 Holdout 结果不理想
- 回到 Test/Backtest 阶段调整参数
- 重新运行 Holdout
为什么错误:
- 这违反了 OOS 原则
- Holdout 窗口实际上参与了设计
- 导致虚假的验证结果
正确做法:
- 接受结果
- 如果不通过,触发 Rollback 或 Child Lineage错误 2:多次 Holdout 选择最优
错误行为:
- 尝试多个参数组合
- 选择 Holdout 表现最好的那个
- 声称"只验证一次"
为什么错误:
- 本质上是在 Holdout 上优化
- 破坏了独立验证的意义
- 属于隐藏的过拟合
正确做法:
- Holdout 只验证一次
- 使用 Backtest 确定的唯一参数组合错误 3:把 Holdout 当作额外优化窗口
错误行为:
- 在 Holdout 上测试不同规则
- 比较 Holdout 上的多种变体
- 根据表现调整策略
为什么错误:
- Holdout 不是优化窗口
- 它是最终的验证门禁
- 这种行为会完全破坏验证意义
正确做法:
- Holdout 只做验证
- 不做任何比较或优化过拟合检查清单
定量指标检查
收益对比:
- [ ] Holdout 收益是否严重低于 Backtest?
- [ ] 收益下降幅度是否 >50%?
- [ ] 是否出现负收益?
风险对比:
- [ ] 回撤是否显著扩大?
- [ ] 夏普比率是否大幅下降?
- [ ] 波动率是否超出预期?
稳定性对比:
- [ ] 收益分布是否发生明显变化?
- [ ] 是否出现异常亏损期间?
- [ ] 胜率是否显著下降?定性检查
市场环境:
- [ ] Holdout 期间市场环境是否发生重大变化?
- [ ] 是否有黑天鹅事件影响?
- [ ] 市场结构是否改变?
执行差异:
- [ ] 交易执行是否符合预期?
- [ ] 滑点和冲击是否合理?
- [ ] 是否有流动性问题?
信号质量:
- [ ] 信号分布是否稳定?
- [ ] 是否出现信号退化?
- [ ] 是否有异常集中的交易?过拟合信号识别
强过拟合信号:
- Holdout 收益为负而 Backtest 很高
- 回撤放大 2 倍以上
- 收益模式完全改变
中等过拟合信号:
- 收益下降 30%-50%
- 回撤显著扩大但在可控范围
- 某些月份表现异常
弱过拟合信号:
- 收益略低于预期
- 指标轻微退化
- 个别异常时期Holdout 验证报告模板
# Holdout Validation 报告
## 基本信息
- **Lineage ID**: [谱系标识]
- **Run ID**: [运行标识]
- **Holdout 窗口**: [起始日期] - [结束日期]
- **验证时间**: [时间戳]
## 验证参数
- **参数组合**: [Param ID]
- **交易规则**: [规则版本]
- **Universe**: [标的数量]
## 收益指标
| 指标 | Backtest | Holdout | 变化 |
|------|----------|---------|------|
| 累计收益 | | | |
| 年化收益 | | | |
| 胜率 | | | |
## 风险指标
| 指标 | Backtest | Holdout | 变化 |
|------|----------|---------|------|
| 最大回撤 | | | |
| 夏普比率 | | | |
| 波动率 | | | |
## 过拟合检查
- [ ] 收益退化是否在可接受范围?
- [ ] 风险指标是否稳定?
- [ ] 是否有异常过拟合信号?
## 市场环境分析
- [ ] 期间市场环境描述
- [ ] 是否有特殊事件影响
- [ ] 执行层面是否有异常
## 结论
**Verdict**: [PASS / CONDITIONAL PASS / NO-GO]
**决策依据**:
- [列出关键判断依据]
**冻结内容**:
- 确认无修改,使用 Backtest 冻结的所有规则和参数
**下一步**:
- [通过后] 进入 Shadow Admission 阶段
- [未通过] 触发 Rollback 或 Child Lineage失败处理
1. Rollback 决策
适用情况:
- 实现层 bug 导致验证失败
- 数据问题导致结果失真
- 计算错误需要修正
Rollback 记录要求:
rollback_stage: [目标阶段]
allowed_modifications: [允许修改的范围]
reason: [回退原因]
timestamp: [时间戳]
禁止事项:
- 不能借此改变研究主问题
- 不能修改已冻结的规则参数
- 不能重新划定时间窗口2. Child Lineage 启动
适用情况:
- 策略机制需要根本性调整
- Universe 需要重新定义
- 信号机制需要改进
- 时间切分需要调整
Child Lineage 要求:
- 新的 lineage_id
- 明确与主线的关系
- 不能自动替换主线
- 需要完成完整流程3. 失败原因分析
分析维度:
1. 过拟合识别
- 参数过度优化
- 规则过度适配
- 数据泄漏
2. 市场环境变化
- 状态转换
- 结构变化
- 流动性变化
3. 执行问题
- 滑点超预期
- 冲击成本
- 流动性不足
4. 信号退化
- 信号失效
- 预测能力下降
- 相关性变化输出 Artifact
必需产物
1. 机器可读产物
holdout_results.parquet:
用途: Holdout 验证的核心结果数据
粒度: 逐笔交易或逐日
主键: [timestamp, symbol]
消费者: Shadow Admission 阶段
holdout_metrics.json:
用途: 关键指标汇总
内容: 收益、风险、稳定性指标
消费者: 报告生成、决策支持
holdout_runs.csv:
用途: Holdout 执行记录
最低字段: lineage_id, run_id, timestamp, param_id, verdict
消费者: 审计、复盘2. 人类可读产物
holdout_validation_report.md:
用途: 验证报告
内容: 按"验证报告模板"撰写
消费者: 团队评审、决策参考
gate_decision.md:
用途: 门禁决策文档
必需字段:
- stage: "HoldoutValidation"
- status: "PASS" / "CONDITIONAL PASS" / "NO-GO"
- decision_basis: [决策依据]
- frozen_scope: [确认冻结的内容]
- next_steps: [下一步行动]
negative_results/:
用途: 保存失败的验证记录
内容: 被拒绝的参数、失败的 gate 记录
重要性: 避免幸存者偏差与 Shadow Admission 阶段的交接
交接内容
Frozen Spec 传递:
- 交易规则(完全冻结)
- 参数组合(完全冻结)
- Universe(完全冻结)
- Holdout 验证结果
关键信息:
- Holdout 收益和风险指标
- 过拟合评估结果
- 稳定性分析结论
- 任何 CONDITIONAL PASS 的条件Shadow Admission 的关注点
- Holdout 阶段只验证策略逻辑有效性
- Shadow Admission 需要补充执行语义和实现细节
- 包括:撮合假设、容量评估、成本模型、监控方案
质量保证
自检清单
验证前:
- [ ] Holdout 窗口确实未参与任何设计
- [ ] 参数组合完全来自 Backtest 冻结
- [ ] 交易规则与 Backtest 完全一致
- [ ] 数据质量检查通过
验证中:
- [ ] 没有根据结果调整任何参数
- [ ] 没有尝试多个版本选择最优
- [ ] 完整记录了所有尝试
验证后:
- [ ] 完成过拟合检查清单
- [ ] 撰写完整的验证报告
- [ ] 完成门禁决策文档
- [ ] 保存所有 artifact学习要点
核心原则
- Holdout 是盲测:只有一次机会,不能回头调整
- 冻结即冻结:Backtest 冻结的内容在 Holdout 中完全不可动
- 结果即结果:接受结果,不通过就走 Rollback 或 Child Lineage
常见疑问
Q:Holdout 结果不理想怎么办? A:如果不通过门禁,触发 Rollback 或启动 Child Lineage。不能根据 Holdout 结果回头调整。
Q:可以尝试多个参数组合吗? A:不可以。Holdout 只验证一次 Backtest 确定的参数组合。
Q:Holdout 和 Backtest 的区别是什么? A:Backtest 可能有多轮优化,Holdout 是真正的”盲测”,只有一次验证机会。
Q:如何判断是否过拟合? A:使用过拟合检查清单,对比 Backtest 和 Holdout 的关键指标,识别过拟合信号。