种群优化算法:Nelder-Mead(NM),或单纯形搜索方法·综合运用
🧭

种群优化算法:Nelder-Mead(NM),或单纯形搜索方法·综合运用

(3/3)·从算法原理到回测结果,手把手把 NM 单纯形搜索接进 EA 优化流程

含代码示例实战向 第 3/3 篇
不少交易者把 EA 参数优化只交给平台默认遗传算法,遇到无导数、多局部极值的目标函数就卡壳。Nelder-Mead 不依赖梯度,却常被误认为只能做单单纯形玩具演示。这一篇把多智能体单纯形实现和回测结果摊开,少走弯路。

◍ 收缩与飞行两步里的坐标重映射

这段逻辑来自一个多坐标智能体优化器,核心是把当前解往收缩点或反射点推,再离散化回合法区间。收缩段直接拿 contractionCoeff 做线性插值,跳过了原注释里的随机收缩,等于把搜索半径固定按比例收。 [CODE] for (int c = 0; c < coords; c++) { Xo = agent.s.c [c]; Xw = agent.s.p [indW].c [c]; //Xc = Xo + RNDfromCI (0.0, contractionCoeff) * (Xw - Xo); Xc = Xo + contractionCoeff * (Xw - Xo); agent.s.Xc.c [c] = SeInDiSp (Xc, rangeMin [c], rangeMax [c], rangeStep [c]); agent.c [c] = agent.s.Xc.c [c]; } agent.s.operation = contraction; } //—————————————————————————————————————————————————————————————————————————————— //—————————————————————————————————————————————————————————————————————————————— void C_AO_NMm::Flying (S_Agent &agent, int indW) { for (int c = 0; c < coords; c++) { double r1 = RNDfromCI (-1.0, 1.0); r1 = r1 > 0.5 ? 1.0 : -1.0; double r2 = RNDfromCI (1.0, 20.0); r2 = pow (r2, -2.0); if (r1 > 0.0) Xr = cB [c] + Scale (r2, 0.0, 1.0, 0.0, rangeMax [c] - cB [c], false); else Xr = cB [c] - Scale (r2, 0.0, 1.0, 0.0, cB [c] - rangeMin [c], false); //Xr = RNDfromCI (rangeMin [c], rangeMax [c]); agent.s.Xr.c [c] = SeInDiSp (Xr, rangeMin [c], rangeMax [c], rangeStep [c]); agent.c [c] = agent.s.Xr.c [c]; } agent.s.operation = reflection; } //—————————————————————————————————————————————————————————————————————————————— [/CODE] 飞行段先抽 r1 落在 (-1,1),大于 0.5 才取正方向,否则反向;r2 从 (1,20) 抽后再做 -2 次幂,实际落在约 (0.0025, 1.0) 区间,越大的原始值被压得越狠。 别把正态当圣经 r2 用 pow(r2,-2.0) 之后分布严重右偏,小步长占绝大多数,MT5 里把 20.0 调到 5.0 会明显让反射跳变更活跃,可实盘前用历史 tick 回测验证收敛速度差异。 两段最后都调 SeInDiSp 把连续值 snap 到 rangeStep 网格上,这意味着参数若设得比 rangeStep 粗,优化器可能在相邻网格点间空转,外汇与贵金属波动下这种空转会放大过拟合风险。

MQL5 / C++
for (class="type">int c = class="num">0; c < coords; c++)
{
  Xo = agent.s.c   [c];
  Xw = agent.s.p [indW].c [c];
  class=class="str">"cmt">//Xc = Xo + RNDfromCI(class="num">0.0, contractionCoeff) * (Xw - Xo);
  Xc = Xo + contractionCoeff * (Xw - Xo);
  agent.s.Xc.c [c] = SeInDiSp(Xc, rangeMin [c], rangeMax [c], rangeStep [c]);
  agent.c        [c] = agent.s.Xc.c [c];
}
agent.s.operation = contraction;
}
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="type">void C_AO_NMm::Flying(S_Agent &agent, class="type">int indW)
{
  for (class="type">int c = class="num">0; c < coords; c++)
  {
    class="type">class="kw">double r1 = RNDfromCI(-class="num">1.0, class="num">1.0);
    r1 = r1 > class="num">0.5 ? class="num">1.0 : -class="num">1.0;
    class="type">class="kw">double r2 = RNDfromCI(class="num">1.0, class="num">20.0);
    r2 = pow(r2, -class="num">2.0);
    if (r1 > class="num">0.0) Xr = cB [c] + Scale(r2, class="num">0.0, class="num">1.0, class="num">0.0, rangeMax [c] - cB [c], false);
    else          Xr = cB [c] - Scale(r2, class="num">0.0, class="num">1.0, class="num">0.0, cB [c] - rangeMin [c], false);
    class=class="str">"cmt">//Xr = RNDfromCI(rangeMin [c], rangeMax [c]);
    agent.s.Xr.c [c] = SeInDiSp(Xr, rangeMin [c], rangeMax [c], rangeStep [c]);
    agent.c        [c] = agent.s.Xr.c [c];
  }
  agent.s.operation = reflection;
}
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————

NMm 在测试台上的真实分数

把 NMm(Nelder-Mead 方法 M)丢进标准测试台,参数设为 C_AO_NMm:5;1.0;2.0;0.5,每个函数跑 10000 次。Rastrigin 函数上 5/25/500 维得分分别为 0.96607 / 0.76427 / 0.62730,平滑曲面上表现相当能打;但 Forest 与 Megacity(离散)立刻露怯,500 维得分只剩 0.05601 和 0.03357。 横向对比 24 个算法,NMm 总评 39.660,排第 9。前面 SDSm、SSG、DE、HS 都过了 70 分,NMm 和它们不在一个量级,但在无梯度直接搜索里算站稳了。 可视化里能看见群体退化、活点挤成一团,靠 Levy 航班稍微救回一点分散度,收缩图并不稳。第三个 1000 变量测试跑太久没进 GIF,只放了前两个。 外汇与贵金属实盘用这类优化器调参时,高杠杆下模型失效会迅速放大亏损,属高风险操作,回测分数不等于实盘概率。

「一点提醒」

Nelder-Mead 原版在重优化里基本可以弃了:它要在初始阶段把单纯形每个顶点的适应度都算一遍,这在多维搜索空间里直接把效率拖死,所以评级表里只留了改版 NMm。SDS 算法也已从表中删除,仅保留其修改版本。 NMm 的改版优势是外部参数少、在变量少且平滑的函数上结果尚可,但缺点很实打实:实现复杂、难接第三方应用、运算速度低、可伸缩性差、结果分散、还容易陷局部极值。这些优劣都只针对这个特定改版,常规 NM 因结果太弱没进表。 文末附的 24_The_world_of_AO_NM.zip(421.03 KB)里有前几篇算法代码的当前更新版,作者说明多处修改只为提升搜索能力,结论基于实验、不对规范算法绝对准确负责。外汇与贵金属优化回测高风险,实盘前务必在 MT5 策略测试器自跑一遍验证。

把重复劳动交给小布
这些诊断与小布盯盘的 AIGC 已内置,打开对应品种页即可看到参数敏感度热图,你专注决策而非手写寻优循环。

常见问题

NM 不需要目标函数导数或解析梯度,靠单纯形顶点反射、收缩在参数空间里挪动,适合无解析导数或多局部极值的函数。
小布内置的 AIGC 诊断可呈现参数区间与敏感度,但寻优循环仍需在 MT5 策略测试器用本文代码跑,小布负责替你盯结果异动。
标准 NM 只用 one 单纯形,但本实现给多个智能体各开一个单纯形并行探索,所以归类为群体式实现,搜索更不易陷局部极小。
外汇贵金属杠杆高、跳空频繁,回测优参过拟合概率偏大,实盘表现可能偏离,务必用样本外数据复核并控仓。