OptiNod 学院

过拟合:只有最高点周围平坦的设置才能扛住实盘

回测收益最高的参数,往往是迎合了过去噪音的曲线。只有相邻设置也同样表现良好的高原型业绩曲线,才能在实盘中站得住。

只有回测最高点旁边的设置值也同样表现良好的高原型曲线,才不会在实盘中崩溃。


过拟合(Overfitting)是指把策略的规则和参数,按过去数据里的偶然波动削磨定型的状态。用同一份数据把组合跑得足够多,任何策略都能做出漂亮的回测曲线。这条曲线究竟捕捉到了过去真实的规律,还是背下了恰好只在那段时间吻合的噪音,单凭回测收益率无法区分,这正是过拟合的要害。


大多数交易者这样使用优化:把参数范围设得很宽,跑几百次回测,然后挑出收益率最高的那一个组合上实盘。RSI周期是14好还是13好,止损设2%还是2.3%,都要把回测收益率比到小数点后,找出最高点。这个过程中选出的最优值,确实是过去区间里收益最高的设置。问题在于,这个最高点在实盘中往往是最先崩塌的位置。


这篇文章要说的很简单:优化的关键,是最高点周围长什么形状。把RSI周期从14挪到13或15,只差一格,业绩就像悬崖一样掉下去,那14这个值就是恰好对准了过去某段特定波动的巧合。反过来,如果从12到18都持续保持相近的良好业绩,这个区间就是捕捉到市场真实结构的稳固区域。同样看回测收益率,有没有同时看旁边的值,决定了实盘业绩的分化。


同样的最高收益,悬崖型峰值与高原型峰值在实盘中分化
同样的最高收益,悬崖型峰值与高原型峰值在实盘中分化

站在悬崖边上的最高点很危险


假设有两个参数,回测收益率都是200%。一个是尖峰,两侧的值收益率掉到50%;另一个在平缓高原的正中间,两侧仍保持180%。标准的优化把两者当作同一个值,因为都是200%。可是在实盘中,两个设置的结果截然相反。


原因是未来的数据与过去的数据存在细微差别。即使回测中RSI周期14是峰值,实盘价格也不会和回测区间的走法完全一样。波动率稍微变大,或者趋势速度有所不同,过去的最优值在未来就会向旁边挪一格。站在悬崖型峰值上的话,一挪格,收益率就从200%跌到50%。处在高原正中间的话,挪一格仍在高原之内,业绩得以保持。


这是举例用的数字,但悬崖型和高原型的差别,在实盘中就是这样表现出来的。2021年一年里,BTC从约29,000美元起步,在11月10日涨到约69,000美元。为了在强劲上升趋势中表现得好,把止损幅度削得很窄,把趋势跟踪参数按最高点拧紧,这段区间的回测就会很华丽。但进入2022年,市场在6月因Luna、3AC的连环清算跌到17,000美元一带,11月因FTX崩塌创出约15,500美元的低点。趋势方向和波动率整体翻转的这个阶段,对准2021年峰值的悬崖型设置,在最初几周就会扩大累计亏损。因为这个峰值只在那种市场状态下才是峰值。


不能只看最高点的高度来选设置,还要同时确认它周围有多平坦。


自由度越多,越是在背噪音


每给策略增加一个参数或规则,自由度(Degrees of Freedom)就多一分。自由度是能把策略嵌合到过去数据上的旋钮个数。旋钮越多,就越能拧到与过去任何一条曲线精确吻合,也就越分不清真实规律和偶然噪音,把两者一起背下来。


原理与统计学的基础相同。两个点可以用一条直线精确连起来,三个点可以用二次曲线精确连起来。参数加得足够多,就能画出穿过过去所有交易的曲线,但这条曲线对未来新出现的点完全预测不准。在策略里逐个加入止损、止盈、入场过滤、时段条件,就等于让曲线弯得更复杂。规则越多,过去区间(样本内)的业绩通常越好,但其中哪部分是真实规律、哪部分是背下来的噪音,在样本内无从确认。


五条规则的策略和十五条规则的策略,在同一段过去区间里做出同样的收益率,就应该选五条的。用更少的自由度做出同样的业绩,说明对偶然性的依赖更少。用十五条规则做出的业绩,其中一半以上很可能是硬套过去噪音的多余部分。简单的策略在实盘中更持久,原因就在这里。


不去看每加一条规则能让样本内收益率提高多少,而是先问:没有这条规则为什么不行。


自由度增加后,穿过过去所有交易,却错过未来的点
自由度增加后,穿过过去所有交易,却错过未来的点

样本少,动几个旋钮就是过拟合


仅凭自由度的绝对个数,判断不了是否过拟合。还要同时看参数个数与交易样本数的比例。同样是五个参数,发生过1,000笔交易的策略还能承受,只有30笔交易的策略,动五个就会立刻陷入过拟合。样本越小,偶然波动在整体业绩中的占比越大,也就越容易把这种偶然误认成真实信号。


交易笔数少的策略,在统计上很难信任。就像一枚硬币抛十次出现七次正面,不能就此断定这枚硬币偏向正面。30笔交易得出60%的胜率,这个60%的置信区间大致从40%出头一直到将近80%,范围很宽。在这么宽的区间里,参数稍微一改,胜率就大幅晃动,顺着这种晃动去选最优值,下一个30笔交易里完全无法复现。


用BTC日线回测一年,K线只有约365根。如果是平均持仓两周的波段策略,一年的交易只有二十笔上下。用这个样本同时优化五个参数,实际上等于每四笔交易就套一个旋钮,所以碰巧出现与过去严丝合缝的设置是理所当然的。要增加样本,就得用更长的过去区间,或者把同一个策略同时用在多个资产上,把交易笔数加总。交易样本不到参数个数的几十倍,就不要相信优化结果本身。


跑优化之前,先数一数发生了多少笔交易。


样本内越华丽,越要怀疑


和直觉相反,回测曲线越平滑,没有一次回撤地向右上方延伸,这个策略就越值得怀疑。真实市场总有难以承受的回撤阶段。如果回测连这些回撤也平滑地越过去了,说明规则被调成了避开过去的每一段下跌。未来的下跌会以与过去不同的形状到来,避开了过去所有下跌的设置,会在未来的第一次下跌中原样暴露。


这个陷阱产生于不断增加止损、止盈、过滤条件,只挑出过去的亏损交易并将其剔除的过程。跑一次回测,某笔亏损交易碍眼,就加一个避开这笔交易的过滤;再跑一次,又加一个避开另一笔亏损的条件。每多跑一次,曲线就更平滑,但新加的过滤条件大多除了避开那一次过去的交易之外,没有任何依据。结果是,策略只是背下了过去发生的那些特定亏损清单,并没有理解产生亏损的结构。


用同一份数据跑几百个组合再挑最高点的做法,也会产生同样的结果。试1,000个组合,其中有几个纯靠运气就几乎完美地穿过过去区间。从这几个里挑最高点,等于挑了碰巧运气最好的设置。反复盯着同一份数据挑最高点的做法,通常称为数据窥探(Data Snooping),测试的组合越多,出现偶然最高点的概率越大。曲线完美得不真实,就是把数据看了太多遍的结果。


没有回撤的回测不值得炫耀,它是最先该被怀疑的检查对象。


加规则后变平滑的样本内曲线,在样本外崩塌
加规则后变平滑的样本内曲线,在样本外崩塌

悬崖型和高原型,由邻近业绩区分


区分稳健设置和过拟合设置,最直接的方法是同时看最优值周围的邻近值。不要只记录最优值一个收益率,把它两侧各个值的收益率一起列成表,确认形状。形状是尖尖的山峰就是悬崖型,是宽阔的山丘就是高原型。对所有核心参数重复同样的步骤。


看邻近业绩之所以有效,是因为把参数往旁边挪,相当于提前模拟未来市场状态的变化。波动率变大,RSI信号晚一拍到达,这样的未来放到回测里,效果类似于最优值从周期14向16移动。在周期16仍保持业绩的高原型设置能扛住这样的未来,在周期16业绩掉到一半以下的悬崖型设置会在这样的未来里崩溃。看邻近业绩,即使没有未来数据,也能预先估计这个设置能撑多久。


下面的检查用在所有核心参数上。


  • 设定邻近范围:以最优值为中心,两侧各3格,共7个值,在同一时间段上记录回测业绩。例如最优值是RSI周期14,就把11、12、13、14、15、16、17的业绩全部看一遍。
  • 高原判定:7个值中,靠近最优值的中间5个(12到16)的业绩都保持在最高值的70%以上,就视为高原型并采用。
  • 否决悬崖:只从最优值挪一格,业绩就掉到最高值的一半以下,这个最优值就视为过拟合并舍弃。改选处在高原正中间的其他值。
  • 同时确认多个参数:参数在两个以上时,不要只晃动一个参数,还要看两个参数同时移动的网格上高原是否仍然保持。只在一个方向平坦的山脊,和悬崖没有区别。

要放弃只记下7个值中最高点的习惯,把7个全部记下来看形状。


把时间段分开看,背下来的曲线就会被筛掉


邻近业绩是在参数空间里晃动的检查,时间段分割则是在时间轴上晃动的检查。不要对整个过去区间一次性优化,先在前半部分选参数,再在后半部分验证这些参数。前半部分称为样本内,后半部分称为样本外(Out-of-sample)。在样本内很华丽的设置,如果在样本外崩塌,说明这个设置背下了前半部分的数据。


这种分割能识别出过拟合,是因为验证区间在优化过程中被完全隔离。选参数时一次都没看过后半部分数据,那么后半部分的业绩,就如实展示这组参数在初次见到的数据上如何运作。一次分割不够,就扩展为滚动前推分析(Walk-forward Analysis),把样本内窗口和样本外窗口沿时间轴滚动,多次验证。累计查看每个区间里前面选出的参数在下一个区间是否有效,就能区分偶然有效一次的设置和始终有效的设置。


再加上蒙特卡洛(Monte Carlo)检验,可以把稳健性再验证一层。把回测中的交易顺序随机打乱几千次,或者把入场时点随机晃动几天,然后看结果的分布。仅仅是换了交易顺序,在部分模拟中账户就陷入难以承受的回撤,说明原来回测里平滑的曲线,依赖的是交易恰好以有利顺序发生的偶然。入场时点晃动几天,业绩就急剧变化,说明这个策略过度依赖某根K线上的某个特定价格。稳健的策略,在这些随机扰动下,结果的平均值不会大幅晃动。


按顺序应用三项检查。


  • 时间段分割比例:用整个过去区间的前70%作样本内选参数,用后30%作样本外验证。样本外业绩掉到样本内的一半以下,就视为过拟合,重新选参数。
  • 重复滚动前推:把样本内和样本外窗口沿时间轴至少滚动5次以上,确认5个区间中有4个区间的样本外没有亏损。
  • 蒙特卡洛分布:在把交易顺序随机打乱1,000次以上的分布里,看最差5%位置的回撤,是否落在实际账户能承受的限度之内。

不分时间段、对整体一次性优化出来的结果,称不上验证。更像自己给自己的答案打分。样本内越华丽,越要再用样本外过一遍,只有在两者中都扛得住的设置,才能上实盘。

样本内很华丽的设置,在隔离的样本外区间崩塌
样本内很华丽的设置,在隔离的样本外区间崩塌

检查你自己的回测结果

上传优化结果 CSV 或 TradingView 策略的交易列表,即可同时查看绩效指标和稳健性检查结果。无需登录即可分析。

分析我的结果文件 查看分析示例