构建一个用于实现带约束条件的自定义最大值的通用优化公式(GOF)(基础篇)
📘

构建一个用于实现带约束条件的自定义最大值的通用优化公式(GOF)(基础篇)

第 1/3 篇

带约束的自定义最大值怎么写成通用优化式

在 MT5 的策略逻辑里,经常需要求一个「带约束条件」的自定义最大值,而不是简单取数组最大元素。比如只允许在波动率低于某阈值、或持仓方向符合约束的候选解里挑最优,这就需要一个通用优化公式(GOF)来统一描述。 把目标函数 f(x) 和约束集 C 分开写,GOF 可表达为:max_{x∈C} f(x)。在 MQL5 里没有内建这种带过滤的极值器,只能自己用循环加条件判断实现,循环次数直接取决于候选空间大小。 以一个具体现象为例:若候选参数有 200 组,每组需计算 5 个约束条件,单轮评估在最坏情况下要走 1000 次判断。这种规模在 OnInit 里跑没问题,但放进 OnTick 高频触发就可能拖慢执行,建议预计算或降频。

◍ 把EA调参拆成数学题:变量、目标与约束

在 MT5 里做策略优化,本质是一个两阶段过程:先定义问题,再数值求解。定义阶段要落定三样东西——输入变量、目标函数、约束函数;求解阶段交给内置的遗传优化器去跑数。 输入变量就是你手上的“旋钮”。实数型最常见,比如均线周期、TP/SL 倍数、止损点数(pips);整型和布尔型也能用,例如开关某个过滤条件。这些变量直接决定 EA 在每次回测 pass 里的参数组合。 目标函数只能有一个,MT5 优化器不接受多目标并行。想兼顾余额、胜率、年化收益,就得先合成。简单加权求和比连乘更稳,本文采用“有针对性且加权”的求和法。 约束函数用来卡边界。MT5 只认输入变量层面的侧面约束,例如 3 <= x_1 <= 4,像“连续亏损次数上限”“夏普比率下限”这类运行期指标无法作为独立约束,必须折进唯一目标函数 F(x) 里一起算。外汇与贵金属杠杆高,回测约束松了,实盘爆仓概率会显著放大。

「遗传算法与暴力穷举在 MT5 里的区别」

MT5 优化器里有两种常被混淆的机制。一种是「基于快速遗传的算法」,它属于无梯度优化,源头可追到 20 世纪 70 年代前后的演化算法思路,不计算目标函数和约束的梯度,因此能接纳那些梯度法根本处理不了的约束条件。 另一种在设置里叫「慢速完整算法」,严格说不是优化算法,而是暴力穷举:在参数侧约束范围内,把输入变量所有取值组合逐一跑完。 实际跑 10 个参数、每个 5 档的组合就是 5^10 ≈ 976 万次回测,遗传算法通常能把候选代次压到几千代内收敛,时间差可能差两个数量级。外汇与贵金属测试含极高风险,回测通过不代表实盘概率占优。 开 MT5 策略测试器切到这两种模式各跑同一 EA,看日志里的 pass 数量与耗时,就能直接验证穷举和遗传的代价差距。

把多个目标函数压成单一适应度

做 EA 多目标优化时,最省事的组合方式是把各个子目标加权求和成单一函数 F(x)。原文给的公式是把第 i 个目标 f_i(x) 先除以它的目标值 T_i 做归一化,再乘权重 W_i,最后除以所有权重之和,让 W_i 凸化,这样求和时不同量纲的目标才能放一块比。 x 是 n 个输入变量组成的向量,T_i 只干一件事:把 f_i(x) 除到可比的数量级,不然余额和盈利因子根本没法加。W_i 是归一化后的乘数,用来表达「哪个目标更受重视」——它只看相对大小。 权重的相对性很直接:三个目标年回报、回收率、盈利因子,配 W=(10,5,1) 和 W=(100,50,10) 效果一样,都表示回报重要性是回收率的 2 倍、是盈利因子的 10 倍。只要都是正数、能表达你的偏好,没有标准答案。 T_i 不能瞎填。举例:初始余额 10000,优化前 EA 跑完约 20000、盈利因子 0.9;若只优化余额和盈利因子两个目标,取 T_1=30000、T_2=2,两个归一化项就同量级了。正式优化后若发现某项数量级飘了,再回头调 T_i。T_i 也必须为正实数,外汇和贵金属品种波动大、过拟合风险高,T_i 设错容易把优化带歪。

◍ 用惩罚项把约束塞进遗传算法

把多目标压成一个加权和是常规操作,但 MetaTrader 5 自带的快速遗传算法不吃硬约束。这里用改版的拉格朗日思路:不从数学上解乘子方程组,而是给目标函数减一个惩罚项,让违规设计直接掉价。 惩罚函数 P_i(x) 只在不满足 g_i(x) 时取正值,满足则为零;若上下界 U_i 或 L_i 为 0,代码里会替成 1 防除零。这一步保证了约束度量可计算且数值稳定。 原版拉格朗日每个约束配一个乘子,本方案偷懒假定所有乘子相等且为常数 k_p。之所以能这么简化,是因为 MT5 遗传算法不依赖任何函数的梯度信息,只管排序和繁殖。 最终单一目标 F(x) 里,k_p 扮演迫使不可行设计排名垫底的角色,违规越狠目标值越低,被选中进下一代的概率就越小;k_o 则不是拉格朗日体系内的东西,它单纯放大可行设计的目标值,让优化结果图的 Y 轴正向区间拉得更开,肉眼更好辨。 两个系数都在 EA 输入参数的“其他参数”里可调。实操建议直接取 10 的幂——10、100、1000 这种,方便你开 MT5 做参数扫描时快速比对惩罚强度对可行解比例的影响。外汇与贵金属优化属高风险,回测可行不等于实盘稳健。

「GOF 三块参数区的实际边界」

打开 MT5 的 GOF 输入参数页,会看到三个分区:目标函数、约束函数、其他杂项。目标函数区代码里允许挂超过 18 个候选函数,但问题表述只暴露 18 个,且建议最多选 5 个;实测中选超过 3 个后,权重分配和函数取舍明显变乱,手工调参效率骤降。 约束函数区已实现 14 个硬约束,界面最多勾 10 个,代码层同样能突破这个上限或往 14 个列表里续写新约束。 其他优化参数区这一屏先不展开,后续段落会单独拆它的字段含义与联动逻辑。外汇与贵金属优化属高风险操作,参数组合过拟合后实盘可能快速失效。

常见问题

把约束写成惩罚项加到目标函数里:超限就扣适应度,这样遗传算法会自然避开违规解。
给每个目标乘权重再加总成单一适应度;权重按你更看重哪项来设,比如盈利0.7、胜率0.3。
小布可接管重复劳动:你填变量范围和约束,它用内置AIGC跑通用优化式并标出可行解,你只看结果。
变量多时穷举是指数级爆炸,遗传算法用种群迭代,通常几十代就能逼近,省90%以上时间。
变量区只放可调输入,目标区放要最大化的式子,约束区放硬限制;重叠会让适应度失真,分开写最稳。