参数应该在进入样本外测试之前锁定。一旦你开始用样本外数据评估表现,任何基于该表现的参数调整都会让这段数据失去"样本外"的意义。滚动回测的价值恰恰在于它强制你在每个窗口的边界上做这个决定:训练窗口内可以反复优化,跨过边界进入测试窗口时,参数必须冻结,测试结果只记录不修改。如果你在测试窗口表现不好时回头改参数,那就不再是滚动回测,而是一次伪装成验证的过拟合。
锁定发生在哪个时刻
滚动回测的每个折叠(fold)有明确的训练段和测试段。参数选择只发生在训练段内,测试段只用于评估。CoinPaprika 对滚动回测的描述是:在一个窗口上拟合参数,将参数原封不动地应用到下一个样本外窗口,记录结果,然后推进两个窗口并重复。VectorBT 的示例更具体:每个训练年选出的最优参数在随后季度的样本外夏普比率平均只有 0.24,而训练段内的夏普是 1.92。这个差距本身就是锁定参数后才会暴露的信息。
所以"锁定"的准确含义是:训练窗口结束的那一刻,参数就固定了。 测试窗口的结果无论好坏,都不能反过来用于调整同一组参数再重新测试同一段数据。如果你发现测试表现很差,正确的做法是记录这个失败,推进到下一个折叠,而不是回到上一个训练窗口里换一组参数。
为什么不能等到"全部回测完再定参数"
有一种常见的错误做法:把所有滚动窗口跑一遍,挑出整体表现最好的那组参数,然后声称这是最终参数。这等于把测试窗口也纳入了选择过程。CoinPaprika 的测试数据很说明问题:在 88 个 RSI 参数配置中,78 个在样本内是盈利的,但扣除基准收益率之后,只有 2 个产生了正超额收益。如果你在全部 88 个配置里挑一个整体曲线最好看的,你挑中的大概率是那个恰好赶上了 2017 到 2021 年牛市环境的配置,而不是一个在未来仍然有效的规则。同一份数据还显示,2017-2021 年这八种资产的无条件 30 天收益率是 17.92%,而 2022-2026 年只有 2.40%。时段本身的差异远大于大多数参数带来的差异。
锁定之后,什么情况下可以解冻
参数锁定不是永久的。滚动回测的推进本身就是一种受控的解冻:下一个折叠开始,训练窗口向前移动,你可以在新的训练数据上重新优化参数。Gate 的一篇策略验证文章把这一点列为分层验证的一环:样本内回测用于建立策略和初步选择参数,样本外测试使用未参与优化的数据检查泛化能力,滚动测试则在不同的时间窗口重复检验。
这意味着参数可以随市场状态的变化而更新,但更新必须发生在新的训练数据上,而不是在已经看过的测试数据上。如果你在实盘运行一段时间后,发现策略表现持续偏离回测预期,是否调整参数、何时调整,取决于你的策略规则是否预先定义了"失效条件"。一个没有预先定义失效条件的策略,在实盘亏损时做出的任何参数调整,都很难和过拟合区分开。
一个可执行的核验标准
在锁定参数之前,用两个问题检验这组参数是否值得进入样本外测试。
第一,参数在训练窗口内是否稳定? 如果参数在相邻的训练窗口之间剧烈跳动,比如均线周期从 10 和 200 变成 20 和 60,又变回 10 和 200,这本身就是一个警告信号。CoinPaprika 指出,最佳参数在窗口之间跳来跳去的不稳定性,通常是反对该规则的证据。稳定的参数不一定是好参数,但剧烈跳动的参数几乎不可能是。
第二,成本假设是否已经计入? CoinPaprika 的同一组数据显示,一次 1% 的往返成本足以把最好的 +0.23 个百分点的超额收益变成 -0.77 个百分点。如果你的策略是高换手率的,成本敏感性测试应该在锁定参数之前完成,而不是在样本外结果出来之后。一个在零成本假设下勉强盈利的策略,在真实成本下大概率不成立。



