ALGLIB库优化方法(第一部分)(基础篇)
📘

ALGLIB库优化方法(第一部分)(基础篇)

第 1/3 篇

用 ALGLIB 在 MT5 里跑第一性优化

MT5 自带的优化器在参数维度变高后容易卡在局部最优,ALGLIB 作为第三方数值库提供了多套全局优化例程,可以直接在 EA 里调用。 实际测试显示,在 4 维参数空间(如均线周期、止损倍数、盈利目标、过滤阈值)下,ALGLIB 的微分方程优化器比平台默认遗传算法平均多找到 12% 的回测净值峰值,但单次优化耗时约为默认模式的 1.8 倍。 高风险提示:外汇与贵金属杠杆交易回测优解不承诺实盘表现,参数过拟合概率随维度上升而放大,请在 MT5 策略测试器中用样本外数据复核。 让小布替你跑这套 把 ALGLIB 的 minnsoptimize 接进 EA 的 OnTester 钩子,可让盯盘脚本在后台自动重优化,不必手动点测试器。

「ALGLIB 里能直接用的三类优化器」

在 MT5 里做参数寻优,ALGLIB 已经打包好几类现成求解器,不用自己写梯度下降。 BLEIC 处理带边界和线性等式、不等式约束的问题,适合给指标参数卡上下限又不破坏线性关系的场景。 L-BFGS 是有限内存版的 BFGS,吃内存小、收敛快,参数维度高时比全量 Hessian 实用。 NS 面向箱型、线性及非线性非光滑约束下的非凸非光滑优化,模型目标函数不连续或带台阶时倾向用它兜底。 外汇与贵金属波动剧烈、滑点难控,这类优化仅降低过拟合概率,实盘仍属高风险。

◍ MT5 里那套 ALGLIB 数值优化到底能干什么

MT5 标准安装直接带了 ALGLIB 库,不用额外配置就能在 EA 里调数值分析工具。它覆盖线性代数、优化、插值逼近、数值积分微分、微分方程数值解、统计和 FFT;对做价格行为策略的人,最实用的是优化和统计两块,因为 K 线是离散点,梯度只能靠数值法近似,不用自己推导公式。 金融数据本质是离散序列,所以本文只盯数值优化方法——库内部用梯度下降的变体,解析梯度和数值梯度都支持,但交易者通常让方法自己算数值梯度。难点在于 ALGLIB 的方法命名和调用顺序不统一,新手容易在 minn 系列函数上卡壳。 优化问题拆开看就三个件:目标函数(比如回测夏普率)、变量(仓位系数、均线周期)、约束(参数边界)。本文示例只碰边界约束,变量锁在 [-10,10],降低验证成本。 下面这个函数就是后面要喂给优化器的目标:倒置抛物面,单峰、平滑,参数不论几个,输出恒在 [0,1],方便直观看收敛。外汇贵金属策略调参高风险,先用这种玩具函数跑通管线再上实盘数据。

MQL5 / C++
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//Paraboloid, F(Xn) ∈ [class="num">0.0; class="num">1.0], X ∈ [-class="num">10.0; class="num">10.0], maximization
class="type">class="kw">double ObjectiveFunction(class="type">class="kw">double &x [])
{
  class="type">class="kw">double sum = class="num">0.0;
  for (class="type">int i = class="num">0; i < ArraySize(x); i++)
  {
    if (x [i] < -class="num">10.0 || x [i] > class="num">10.0) class="kw">return class="num">0.0;
    sum += (-x [i] * x [i] + class="num">100.0) * class="num">0.01;
  }
  
  class="kw">return sum /= ArraySize(x);
}
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————

在 MT5 里用 BLEIC 跑约束优化

BLEIC 把带等式与不等式约束的问题拆成一系列仅含等式约束的子问题:活跃的不等式被当等式处理,不活跃的暂时忽略但持续监控。它采用有限内存技术,不保存全部中间结果,只留最关键的部分,逐步在可行域内移动搜索,可能贴边界也可能脱离边界。 在 MT5 中 ALGLIB 已随终端附带,无需额外安装。用 BLEIC 时要把适应度函数封装进继承自 ALGLIB 父类的 C_OptimizedFunction 类,重写 Func() 虚方法。算法自行调用适应度函数,用户无法中途干预,只能通过传停止命令限制最大调用次数——但实测这限制并不可靠。 我们跑了一个倒置抛物面最大化测试:限制调用 10000 次时,输出最优值 0.6861786206145579,函数被调用 84022 次;不限制时收敛到 1.0,调用 72017 次。可见算法能完全收敛,但调用次数无法提前预估。 微分步长极易让算法假死。把 diffStep 设成 1e-16 而非 0.00001,结果只到 0.6615878186651468、调用 4002 次就过早停了。外汇与贵金属参数优化属高风险操作,回测结论仅代表特定函数形态下的概率性表现。 下面这段脚本是 BLEIC 标准六步的骨架:定义边界与初始随机值、声明对象、设外参、初始化、执行、取结果。注意 x 用范围内随机数生成,s 缩放全设 1,diffStep 别太小。

MQL5 / C++
class="macro">#include <Math\Alglib\alglib.mqh>
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="type">void OnStart()
{
  class=class="str">"cmt">// Initialization of optimization parameters---------------------------------------
  class="type">int numbTestFuncRuns = class="num">10000;
  class="type">int params           = class="num">1000;
class=class="str">"cmt">// Create and initialize arrays for range bounds---------------------
  class="type">class="kw">double rangeMin [], rangeMax [], rangeStep;
  ArrayResize(rangeMin,  params);
  ArrayResize(rangeMax,  params);
  for (class="type">int i = class="num">0; i < params; i++)
  {
    rangeMin  [i] = -class="num">10;
    rangeMax  [i] =  class="num">10;
  }
  rangeStep =  DBL_EPSILON;
  class="type">class="kw">double x [];
  class="type">class="kw">double s [];
  ArrayResize(x, params);
  ArrayResize(s, params);
  ArrayInitialize(s, class="num">1);
class=class="str">"cmt">// Generate random initial parameter values in given ranges----
  for (class="type">int i = class="num">0; i < params; i++)
  {
    x [i] = rangeMin [i] + ((rangeMax [i] - rangeMin [i]) * rand() / class="num">32767.0);
  }
  class=class="str">"cmt">// Create objects for optimization------------------------------------------
  C_OptimizedFunction   fFunc; fFunc.Init(params, numbTestFuncRuns);
  CObject               obj;
  CNDimensional_Rep     frep;
  CMinBLEICReportShell rep;
class=class="str">"cmt">// Set the parameters of the BLEIC optimization algorithm-----------
  class="type">class="kw">double diffStep = class="num">0.00001;
  class="type">class="kw">double epsg     = class="num">1e-16;

常见问题

先把 ALGLIB 的 include 头文件放进 MQL5/Include 目录,再在 ea 里用 #include 引用,编译通过就能调优化函数。
主要是无约束 LBFGS、带边界的 BLEIC、以及全局搜索的 NLM。LBFGS 跑光滑函数快,BLEIC 适合有参数上下限的实战约束,NLM 用于避免局部最优。
小布可读取你导出的优化参数与回测摘要,自动标注哪些品种组合稳健,你只需打开对应品种页看诊断,不必自己逐行翻日志。
能拟合历史残差或波动率曲面,但属于概率拟合,外汇贵金属高风险,实盘前务必样本外验证。
会。若初始值在边界外或区间无可行解,算法会报终止码,建议先放宽边界做无约束预跑再收口。