投资理财

Walk-forward 滚动验证切分器

输入总区间、训练窗与验证窗,排出每一轮的滚动窗口,看清一共能验证几轮、每轮各覆盖哪段。

  • 免费免注册
  • 结果可分享链接
  • 浏览器本地计算

滚动窗口(训练窗长度固定,整体往前挪)

你手上全部历史数据有多少期

每轮用多长的数据定参数

定完参数后往后验证多长

每轮整体往前挪多少期

「期」是你自己的口径:喂日线就是交易日,喂月线就是月。切分只是区间算术,与数据频率无关, 但四个数字必须用同一种口径,混着填算出来的排布没有意义。

5 轮
总轮数
50%
验证覆盖率
120 / 240 期
120 期
开头只训练不验证
0 期
轮间重叠

每一轮覆盖哪一段

训练段(定参数)验证段(不许回头改参数)
1
2
3
4
5
第 1 期240
轮次训练段训练长度验证段验证长度
1112012012114424
22514412014516824
34916812016919224
47319212019321624
59721612021724024

风险提示:排得开窗口,不等于策略成立

  • 本工具只做区间切分,不接任何行情数据,也不计算收益——它回答的是「怎么排」,不是「排完能赚多少」。
  • 滚动验证只能降低一次性调参带来的过拟合,无法消除它。轮次越多、每轮都重新优化参数,反而越容易在整段历史上留下拟合痕迹。
  • 回测不等于实盘。滑点、冲击成本、流动性、停牌与规则变化都不会出现在切分表里,实盘结果通常明显差于任何一轮验证段的成绩。

教育演示:本工具仅按输入的区间参数排列训练段与验证段,用于回测方法教学, 不获取行情、不产生绩效结论,也不发出任何买卖信号。本工具不构成投资建议。

链接带当前参数,发给别人打开就是同一份结果。

怎么用

6 步
  1. 先定总区间:把你手上全部历史数据折成「期」数填进去。日线就填交易日数,月线就填月数——工具只做区间算术,不关心频率,但后面四个数字必须用同一种口径。
  2. 填训练窗与验证窗:训练窗是每轮用多长的数据定参数,验证窗是定完之后往后验证多长。经验上训练窗通常明显长于验证窗,具体多长取决于你的策略要多少样本才够稳。
  3. 定步进:步进是每轮整体往前挪多少期。想让验证段首尾相接、既不漏也不重,把步进设成和验证窗一样长;填大了会跳过数据,填小了会重复统计。
  4. 切换滚动 / 累积窗口:滚动窗口的训练段长度固定、整体往前挪,老数据会被挤出去;累积窗口的起点钉死在第 1 期,训练段一路往后扩,历史全部留在训练集里。两者的验证段排法完全一样。
  5. 看甘特条和那几个数:每一轮一条横向条带,浅色是训练段、深色是验证段,一眼看出整段历史被怎么切开。重点看总轮数、验证覆盖率,以及下方的参数搭配提示。
  6. 导出或分享:轮次明细可导出 CSV,直接拿去当回测脚本的循环边界。复制结果链接发给同伴,打开就是同一份切分方案。
深入讲解

这里算的是一张时间表,不是一份成绩单

回测最常见的自欺欺人,是用同一段数据既调参数又验证效果。 你在 2015 到 2024 这十年里试了两千组参数,挑出表现最好的那组,然后指着这十年的收益曲线说策略有效—— 这句话没有任何信息量,因为那条曲线本来就是「挑出来的」。 滚动验证要解决的正是这件事:让定参数的数据和验证成绩的数据在时间上严格分开,而且不止分开一次。

做法很朴素。取一段训练窗定参数,紧接着往后取一段验证窗,用刚定好的参数在这段没见过的数据上跑一遍,记下成绩; 然后整体向前挪一个步进,重复上述动作。挪到数据尽头为止,你就得到了一串验证结果。 这套流程英文叫 walk-forward analysis,中文有人叫滚动验证、有人叫前推分析,说的是同一件事。

工具做的就是把这张时间表排出来:给定总区间、训练窗、验证窗和步进, 算出第 1 轮训练哪一段、验证哪一段,第 2 轮又是哪一段,一共能排几轮, 整段历史里有多少比例真正进入过验证段。每一轮画成一条横向条带,浅色训练、深色验证, 堆在一起就是整个验证方案的全貌。至于每轮跑出来成绩多少,那需要你自己的回测代码,本工具不涉及。

四个参数各自控制什么

总区间就是你手上全部历史数据的长度,单位是「期」。 日线数据填交易日数,周线填周数,月线填月数——切分是纯粹的区间算术,与频率无关, 但四个数字必须统一口径,混着填排出来的表毫无意义。

训练窗决定每轮用多长的数据定参数。 这个数字是有下限的:样本太少,参数估计的方差会大到参数本身失去意义; 但它同时也是有代价的,训练窗越长,第一轮验证开始得越晚,可验证的区间就越短。 工具里那个「开头只训练不验证」的期数,就是这笔代价的具体金额。

验证窗决定每轮往后验证多长。 短验证窗轮数多,但每轮的成绩噪声大,一两笔交易就能把结果翻个个儿; 长验证窗每轮成绩更稳,但轮数少,也意味着参数在更长时间里不重新调整, 离「定期调参」的真实做法更远。这里没有标准答案,只有权衡。

步进决定每轮整体前移多少期,它直接控制验证段之间的关系。 步进等于验证窗时,验证段首尾相接,不漏不重,这是最干净的排法; 步进大于验证窗会在轮与轮之间留下空档,那部分数据谁也没验证; 步进小于验证窗则让验证段互相重叠,轮数看着变多,实际是同一段行情被反复统计。

滚动窗口与累积窗口

两种模式的验证段排法一模一样,差别只在训练段的左端。 滚动窗口把训练窗长度钉死,整体向前平移,最老的数据每轮被挤出去一批; 累积窗口把起点钉在第 1 期,训练段的右端一路后移、左端不动,训练集越滚越大。

选哪个取决于一个判断:老数据还算不算数。 如果你认为市场结构会变,你的策略依赖的那类模式可能已经不复存在,滚动窗口更合适—— 它天然让模型只看最近的一段,对结构变化的反应更快。 如果你认为规律足够长期稳定,而且样本本来就不宽裕,累积窗口能让训练集持续变大,参数估计更稳。

累积窗口有个不容易注意到的副作用:越到后面,新数据在训练集里的权重越低。 第 20 轮时最近这一年可能只占训练集的二十分之一,模型对近期变化几乎不响应了。 工具会把最后一轮的训练段长度直接标出来,让这件事在你按下切换之前就变得可见。

几个常见误用

把汇总成绩当成唯一结论。 滚动验证真正的产出是一串跨轮的结果,而不是把它们平均出来的那个数。 五轮里四轮平平、一轮暴赚,和五轮都稳稳小赚,平均下来可能一样,但它们是完全不同的两种策略。 看滚动验证的报告,先看每轮的分布和最差的那一轮,再看平均值。

跑完不满意,回头改切分方案再跑一遍。 这是最隐蔽也最致命的一种泄漏。每一轮内部确实严守了样本外原则, 但你作为研究者看着全部结果在调整训练窗、改搜索范围、换评价指标—— 整段历史就这样通过你的手进入了模型选择。防这个只能靠纪律:开跑前把方案定死,跑完就认。

用轮数掩盖数据不足。 把步进调小、验证窗调短,轮数立刻能从 3 轮变成 30 轮,报告瞬间显得厚重。 但底下还是那么长的历史,重叠的验证段并不产生新的信息量。 轮数是结果不是目标,真正决定验证价值的是被覆盖的历史有多长、跨越了多少种市场环境。

忽略最后剩下的那一截。 结尾凑不满一个完整验证窗时,工具不会排一个短了半截的残窗——长度不等的验证段没法横向比较。 但被剩下的往往正是最近这段行情,也正是你最想知道策略表现如何的那段。 看到「结尾还剩若干期」的提示,值得回头微调一下步进或验证窗,把它纳进来。

边界与本工具的假设

本工具只做区间切分,不接任何行情数据,不计算收益,也不做参数优化。 所有端点都是 1-based 的闭区间,含首含尾。训练段与验证段严格相邻,中间不留缓冲期—— 如果你的策略有信号延迟或者需要预热期,实际执行时要自己在两段之间空出相应的期数。 期数一律向下取整,验证段必须完整落在区间内,凑不满的尾部不排残窗。 轮数超过展示上限时后续轮次不再排出,那种参数搭配下的表格本来也没人看得完。

还有一点关于口径:切分表算出的「验证覆盖率」只描述数据被覆盖的比例,不评价覆盖得好不好。 同样是 50% 的覆盖率,横跨牛熊震荡的那 50% 和全在单边行情里的那 50%,价值差着量级。 这件事工具判断不了,只能靠你对自己那段历史的了解。

风险提示:滚动验证只能降低一次性调参带来的过拟合,无法消除它;排布合理也不代表策略成立。 回测不等于实盘,切分表里不包含滑点、冲击成本、流动性、停牌与交易规则变化, 实盘结果通常明显差于任何一轮验证段的成绩。历史表现不代表未来。 本工具仅为回测方法教学演示,不获取行情、不产生绩效结论,不发出任何买卖信号,不构成投资建议。

常见问题

7 条
滚动验证和普通的样本内外切分,区别到底在哪?
普通切分只切一刀:前面 70% 当训练段调参数,后面 30% 留着验证,从头到尾只有一个验证结果。这个做法最大的软肋是「只有一次考试」——你的验证段恰好覆盖的是哪一段行情,几乎决定了结论好看还是难看。碰上单边上涨的那三年,几乎什么策略都能过关;碰上震荡市,好策略也可能被判死刑。滚动验证把这一刀变成很多刀:训练一段、往后验证一段,然后整体前移,再训练再验证,循环下去。你得到的不是一个数字,而是一串跨越不同市场环境的验证结果。真正有用的信息藏在这串结果的分布里——是每轮都稳稳过关,还是只有牛市那两轮撑起了全部成绩。后者在单次切分里几乎看不出来,在滚动验证的表格里却一目了然。代价是计算量成倍上升,而且每轮都要重新调参,工程上麻烦得多。
滚动窗口和累积窗口该选哪个?
两者的差别只在训练段的左端要不要跟着走。滚动窗口把训练窗长度钉死,整体向前平移,超出窗口的老数据被挤出去;累积窗口把起点钉在第 1 期,训练段随着轮次一路变长,所有历史都留着。选择取决于你对「老数据还算不算数」的判断。如果你认为市场结构在变——交易制度改过、参与者结构换过、你的策略依赖的那类行为模式可能已经消失,那么滚动窗口更合适,它天然让模型只看最近的一段。如果你认为规律足够长期稳定、且样本本来就不多,累积窗口能让训练集越来越大,估计出的参数方差更小。累积窗口有个容易被忽略的副作用:越到后面,新数据在训练集里的占比越低,模型对近期变化的反应会越来越钝——第 20 轮时,最近这一年可能只占训练集的二十分之一。工具会在你选累积窗口时直接把最后一轮的训练段长度算给你看。
验证覆盖率多少算够?这个数为什么总是上不去?
覆盖率是「被至少一轮验证段盖到的期数」除以总区间。它天生上不去,因为开头那一整段训练窗永远不可能被验证——第一轮要先有训练数据才能往后验证。训练窗 120 期、总区间 240 期,理论上限就是 50%,怎么调步进都突破不了。所以不要盯着一个绝对数字,而是看两件事:一是覆盖率有没有接近「1 减去训练窗占比」这个理论上限,明显偏低说明步进设得太大、中间漏了数据;二是被覆盖的那部分有没有跨越足够多样的市场环境。一个覆盖率 45% 但横跨牛熊震荡的切分,比覆盖率 70% 却全在同一段单边行情里的切分有说服力得多。顺带说一句,工具在算覆盖率时对重叠只计一次——步进小于验证窗时验证段互相压着,把每轮长度直接相加会算出超过 100% 的荒唐结果。
步进比验证窗大或小,各会出什么问题?
步进大于验证窗,相邻两轮的验证段之间会留出空档,那几期数据谁也没验证到——它们既不在任何训练段的末尾,也不在任何验证段里,等于白白浪费。工具会把跳过的期数合计出来给你看。步进小于验证窗则相反:验证段互相重叠,同一段行情被多轮反复统计。表面看轮数变多了、样本变足了,实际上这些轮次并不独立,一次特殊行情会同时影响好几轮的结果,你算出来的「跨轮稳定性」就带了水分。真要按重叠样本做统计推断,还得考虑自相关的修正,那已经超出这个工具的范围。最省事也最干净的做法是让步进等于验证窗,验证段首尾相接,既不漏也不重,覆盖率也刚好达到理论上限。工具在这两种情况下都会给出提示并算出具体期数。
只排得出两三轮,说明什么?
说明你的数据长度撑不住这套验证方法。轮数少有三种典型原因:历史数据本来就短;训练窗设得太长,第一轮就吃掉了大半区间;步进设得太大,往前挪两下就到头了。轮数太少的直接后果是结论极不稳健——两轮里有一轮成绩好,你无法判断那是策略有效还是运气好,因为样本量根本不支持任何统计判断。遇到这种情况,可以按优先级依次尝试:先找更长的历史数据,这是唯一真正解决问题的办法;其次考虑缩短训练窗,但要确认缩短后的样本量仍够估计你的参数;再次是缩短验证窗,代价是每轮验证结果的噪声变大。如果三条路都走不通,诚实的结论是这个策略在现有数据上没法做滚动验证,那就别硬做——排出来的三轮表格看着很专业,但它给不了你想要的信心。
每一轮都重新优化参数,到底是好事还是坏事?
两面都有,而且两面都很重要。好的一面:这更接近你真实的使用方式。实盘里你本来就会定期重新调参,滚动验证如实模拟了「用过去的数据定参数、拿到未来去用」这个动作,得到的成绩比一次性调参再全段回测诚实得多。坏的一面有两层。第一层是计算量,每轮都要跑一遍参数搜索,轮数乘以参数组合数,很快就大到跑不动。第二层更隐蔽:虽然每一轮内部严格遵守了样本外原则,但你作为研究者是看着全部轮次的汇总结果在做决策的。如果你因为汇总成绩不理想而回头调整训练窗长度、换个参数搜索范围、改一改验证指标,再重跑一遍——这时整段历史就已经通过你的手泄漏进了模型选择里,滚动验证的「样本外」保护被绕过了。防这个只能靠纪律:切分方案和评价指标在开跑前定死,跑完就认,想改就换一份彻底没用过的数据从头来。
排出来的表格能直接说明策略行不行吗?
不能。这个工具只做一件事:把区间按你给的参数切开,告诉你一共几轮、每轮各覆盖哪一段。它不接行情数据、不跑策略、不算收益,自然也给不出任何绩效结论或买卖信号。切分表的作用是让验证流程本身站得住脚——它保证你没有拿同一段数据既调参又验证、没有偷偷跳过难看的年份、没有把最近的行情漏在窗口之外。至于每一轮跑出来的成绩怎么解读,那是另一回事,而且要格外小心:回测终究不等于实盘,切分表里不会出现滑点、冲击成本、流动性不足、停牌与规则变化,这些在实盘里往往就是盈亏的分界线。一份排布漂亮、每轮都过关的滚动验证,只是把「明显不成立」这个可能性排除掉了一部分,它不承诺任何未来收益。

本工具仅为测算演示,不构成投资建议。计算结果受输入假设影响,实际情况请以官方规定与金融机构公布为准。

回到计算器