回测与验证 intermediate 12 分钟阅读

MT5 参数优化:116 个组合、252 次运行,最终采用 0 个设置

我们把 MT5 参数优化跑在自家的八个策略模板上,最后一个也没有采用。真正有用的是它们各自失败的方式:样本内涨得最凶的那个跌得最狠,有一个设计通过了唯一一次样本外检验之后照样崩掉,还有两个连在自己被拟合的那段行情上都没能越过 1.0。本文给出完整流程,以及那种让你不会直接把表格第一行发出去的读法。

发布于 · 审阅于

MetaTrader 5 里的参数优化是一次搜索:你为每个输入参数声明一个范围,策略测试器把每一种组合都跑一遍,然后按你选定的指标排好序,把一张表交到你手上。难的不是把它跑起来。难的是这张表永远有第一行,而第一行几乎永远是错的。

你从这篇文章里带走的,是一套产出决定而不是产出数字的流程:一次你守得住的搜索,一种在遇到第二段时期之后仍然成立的通过表读法,以及一条停止规则。

测试条件
实验编号EXP-PARAM-SEARCH-OUTCOMES-001
上级实验EXP-BUILDER-TEMPLATE-BASELINE-001
来源ea-templates-manifest.jsbt.explored
样本总体8 recorded searches of the 53 measured templates
品种 / 时间周期USDJPYm, M5 and H1
模型M1 OHLC (Model=1), Exness MT5, measured 2026-06-18
变动的参数stop loss and take profit only
最近验证2026-08-25

设置:网格、切分与数据

有三项设置决定这次搜索到底值不值得跑。把它们设错了,通过表就是一台非常昂贵的随机数发生器。

项目位置该怎么设为什么
OptimisationSettings 标签页网格小就用 Slow complete algorithm遗传模式只是对这个空间做抽样;12–32 种组合,你完全有余力把它们全看一遍
Start / Step / StopInputs 标签页,逐个输入参数两个参数,粗一点的步长你每勾一个输入参数,网格就乘一次。我们只动了两个
ForwardSettings 标签页1/21/31/4把区间切开,让测试器对后半段单独打分——这正是你跑这次搜索做的那项检验
Optimisation criterionSettings 标签页在你看到网格之前就定下来它是测试器给各次通过排序所用的那个指标,所以是它决定了哪一行才是第一行
ModellingSettings 标签页先用粗模式扫,再把活下来的那个拿真实 tick 重跑扫描用的模式是用来给候选排序的,绝不能用于你要发布的数字
PeriodSettings 标签页长到能装下不止一种行情格局一次只在一段趋势里做的搜索,找到的是骑上了这段趋势的那个设置

这个准则值得你做一个决定,而不是用默认值。按净利润排序,奖励的是冒险最多的那次通过;按基于回撤的指标排序,奖励的是交易最少的那次——恢复因子之所以存在,就是因为这两个答案彼此矛盾。我们自己的搜索压根没有按测试器的排序来判断:每一个活下来的候选,都在三段各自独立的窗口上用盈利因子打分,而其中任何一段内部的排序,从来没有决定过任何事情。

数据质量排在最前面:在坏 tick 上做的搜索,优化的是那些缺口。简短版本是:建模质量低于 90% 会让日内的通过表变得没法用,而用插值 tick 数据搭出来的运行,分辨不出一个落在K线内部的止损。

  1. 先按默认值跑一次回测,并且把报告留下来。没有基线,通过表就没有可以超越的对象——怎么做一次回测把那一次通过从头到尾讲了一遍。
  2. Settings 标签页里,把 Optimisation 设成适用于小网格的完全遍历,并把 Forward 设成 1/3,让测试器把区间的最后三分之一留出来。
  3. Inputs 标签页里只勾选你真正要测的那些参数,并给每一个都设好 StartStepStop。两个输入参数配粗步长,胜过四个配细步长。
  4. Start,让它跑完。把 Optimisation Results 标签页当成一张表来读,把 Optimisation Graph 当成一个形状来读——孤零零的一根尖峰是警告,一片高原才是发现。
  5. 挑出活下来的那些——不是冠军——把每一个都当作单次回测,在优化窗口之前的一段时期上重跑一遍。我们这组里每一条否定判定都出自这一步,而这一步也正是人们会跳过的那一步。

读结果:三段时期,而不是一段

下面是我们记录在案的这一整组搜索,按每次搜索达到的最佳样本内盈利因子排序。IS 是设置被拟合的那段时期,OOS 是留出段,prior 是这次搜索从未见过的一段更早的窗口。

模板搜索的网格最佳 ISOOS此前窗口判定
ichimoku12 种组合 × 3 段窗口1.370.890.80no_robust_edge
ma_crossover20 + 12 种组合,两个时间周期1.230.89–0.940.78no_robust_edge
cci_level12 种组合 × 3 段窗口1.071.050.92no_robust_edge
adx_trend12 种组合 × 3 段窗口1.040.910.80no_robust_edge
breakout12 种组合 × 3 段窗口1.040.79–0.890.64–0.84no_robust_edge
macd_signal12 种组合 × 3 段窗口1.14–1.150.74–0.77no_robust_edge
rsi_reversal12 种组合 × 3 段窗口0.91no_robust_edge
bb_bounce12 种组合 × 3 段窗口0.91no_robust_edge

先把第一列数字从上往下读一遍,再横着读。这一组里样本内成绩最大的那一个,崩得也最狠:ichimoku 的 1.37 掉到 0.89,再掉到 0.80。这个先后次序不是巧合——最贴合一段窗口的那个设置,按其构造方式,正是把这段窗口的噪声吸收得最多的那一个。

现在来看真正最接近可用的那个设置。它不在上面的表里,因为它从来都不是任何东西的第一行:在同一张 ichimoku 网格上,SL50/TP150 拿到了样本内 1.18、样本外 0.99、此前窗口 1.00。三段时期,全都大致持平。它被记录为最接近的候选,而且依然没有被采用,因为在三段窗口上都只是打平并不是优势——那是优势不存在这件事,被仔细地测量了出来。

与之相对,这些搜索试图超越的那些基线,落在 0.92 到 1.03 之间。没有任何一次搜索动得了一个已经发布的默认值。

要避开的陷阱

这五条底下的失败模式是同一个。过拟合不是你在一次搜索的末尾犯下的错误——它是跑一次搜索的默认结果,而三段时期的纪律之所以存在,就是为了在你据此行动之前把它显出来。

改进与迭代:改什么,以及什么时候停

改一样东西,重跑,和你留下来的那条基线比较。最省时间的顺序是:

  1. 先把时期放宽,再把网格放宽。 更多的行情格局胜过更多的组合。一次只覆盖一段趋势的搜索,无论精度多高,找到的都是骑上了这段趋势的那个设置。
  2. 然后把步长变粗,而不是精调它。 如果一个结果只在 SL47 上存在,那它就不存在。
  3. 然后,而且只有到了这时候,才去加一个参数。 我们的搜索从来没走到这一步,因为两个参数就已经过不了三段时期这道关。

符合下面任意一条就停下来,并且把是哪一条写下来:

  • 有一个幸存者过了全部三段时期。 把它发出去,并且把你搜索过的整张网格都记录下来——不只是你留下的那次通过。
  • 最佳样本内成绩低于 1.0。 你得到了一个真实的答案:我们八次搜索里有两次就止步于此,而在 36 次评估之后止步于此是很便宜的。
  • 幸存者总是过了一段窗口又倒在另一段。 这条规则依赖行情格局。搜得更多,只会搜出更多依赖行情格局的设置。
  • 你已经开始解释为什么此前那段窗口“不算数”。 就是在那一刻,这次搜索不再是一次测试了。

一次搜索的诚实记录,是你覆盖过的范围判定,两者放在一起。我们那八次每一次都是这样存下来的,这也正是这篇文章能够完全从它们身上写出来的原因——光存一个赢家,什么都证明不了。

下一步:先做前进测试,再做决定

优化是四步里的第二步。顺序是回测 → 优化 → 前进分析 → 模拟盘,每一步都拿掉一种不同的犯错方式。

  • 拿一个你自己掌控的东西来练这个循环:在 Builder 里搭一套策略,自己去搜索它的止损和目标,因为一张你亲手声明的网格,远比一张你继承来的网格更容易读得诚实。
  • 三段时期检验的正式版本是前进分析,它把切分点向前滚动,而不是固定在某一处。
  • 不管这次搜索交回来的是什么,交回它的那份报告仍然得读:读懂一份 MT5 回测报告讲的是每一个头条数字实际上是在替哪一个样本总体说话。
  • 想看看数字真的活下来之后,一份完成的记录长什么样,已发布的 EA每一项都带着完整的平仓交易清单和运行清单。
  • 我们如何测试、打分并记录这一切,写在我们的测试方法里。

常见问题

一次应该优化几个参数?
比测试器允许的要少。我们记录在案的每一次搜索都只动了两个参数——止损和止盈——组合数在 12 到 32 之间,而八次里没有任何一次给出我们愿意发布的设置。加上第三个、第四个参数并不能解决这一点;它只会让网格成倍膨胀,让你更容易找到一个正好贴合测试窗口噪声的组合。如果两个参数都做不出一个能扛过三段时期的结果,问题出在规则上,而不是搜索的精度上。
在一次优化通过里,盈利因子该看到多少?
要看三个数字,而不是一个。在我们这组记录里,样本内盈利因子的最高值是 ichimoku 模板的 1.37——而同一个设置在样本外只有 0.89,在更早的那段窗口上只有 0.80。最接近可用的那个设置,样本内的成绩反而寒酸得多:1.18,并在另外两段窗口上守住了 0.99 和 1.00。它依然没有被采用,因为三段窗口里有两段只是打平,那不是优势。屏幕上信息量最小的数字,正是那个很高的样本内数字。
一次样本外测试,足以验证一个优化出来的设置吗?
不够,而且我们手上就有一个能说明为什么的案例。macd_signal 模板给出的设置在样本外达到了 1.14 到 1.15——单次留出检验干干净净地通过了——然后在测试期之前的那段窗口上只拿到 0.74 到 0.77。另一个设计 cci_level 走得更远:样本内 1.07,样本外 1.05,此前窗口 0.92。两段时期同样不够。按通常那条单次留出的规矩,这两个都会被发出去。
如果优化根本找不到一个能盈利的设置,说明什么?
说明你早早地、而且很便宜地拿到了答案,这是好结果。我们八次搜索里有两次——rsi_reversal 和 bb_bounce——连在自己被拟合的那段行情上都没能让盈利因子越过 1.0;它们样本内最好的成绩是 0.91。一条在自己被调参的数据上都跑不通的规则,不会靠更宽的网格或者更长的运行被救回来。把你搜索过的范围和判定记录下来,然后去做下一个想法。