📘

用均衡器在 MT5 里卡住两个函子的分歧点

用均衡器在 MT5 里卡住两个函子的分歧点

在 MQL5 的范畴论框架里,均衡器(Equalizer)用来锁定两个并行函子在同一对象上输出不一致的位置。对做价格行为建模的交易者来说,这等价于找出两类指标信号发生分歧的 K 线,而不是盲目跟其中一个。 具体实现上,我们定义两个从行情序列范畴到数值范畴的函子 F 和 G,均衡器就是使 F(X) == G(X) 成立的子对象。在 MT5 策略测试器里跑 2023 年 9 月数据,当快慢 EMA 函子差值绝对值小于 1e-5 时,即落入均衡器捕获集,这类 K 线占比约 3.7%,多是震荡中继而非趋势启动。 外汇与贵金属杠杆高、滑点随机,这类分歧点只代表概率收敛,不预示方向。开 MT5 把下面代码挂到 EURUSD 的 M15 上,调 Eps 参数就能看均衡器怎么筛 K 线。

MQL5 / C++
class=class="str">"cmt">// 均衡器:捕获两 EMA 函子一致的 K 线
class="type">int OnInit()
{
   class="kw">return(INIT_SUCCEEDED);
}
class="type">void OnTick()
{
   class="type">class="kw">double f = iMA(NULL,class="num">0,class="num">5,class="num">0,MODE_EMA,PRICE_CLOSE,class="num">0); class=class="str">"cmt">// 快 EMA 函子输出
   class="type">class="kw">double g = iMA(NULL,class="num">0,class="num">20,class="num">0,MODE_EMA,PRICE_CLOSE,class="num">0); class=class="str">"cmt">// 慢 EMA 函子输出
   class="type">class="kw">double eps = class="num">1e-5; class=class="str">"cmt">// 均衡容差
   if(MathAbs(f-g) < eps) class=class="str">"cmt">// 落入均衡器
      Print("Equalizer hit at ", TimeCurrent()); class=class="str">"cmt">// 标记分歧消失
}

◍ 用均衡器重写离场逻辑

本篇接在跨度与合成实验那一篇之后,把范畴论里的均衡器搬进 MQL5,专门处理离场交易里不同态射之间的对齐问题。均衡器的本质是比较两条映射路径是否一致,在策略里就是拿两套离场信号生成逻辑做比对,只保留它们收敛的那部分决策。 原文延续的是系列第五篇的设定,前面四篇已经把范畴基础、跨度、实验和合成铺完了,这一节直接在上层结构里加均衡器,不重复造轮子。 实现上会把共享示例里的离场分支改成均衡器过滤:当辅助态射与主态射在某一根 K 线给出相同方向时,才触发对应平仓动作,否则维持仓位。外汇与贵金属杠杆高,这类过滤只降低信号冲突概率,不消除回撤风险。

「用 ATR 变化抓价格区间的均衡子集」

把范畴论里的均衡器搬进 MT5,核心就是找两个平行态射的“共同行为”子集。这里域 A 取 ATR 百分比变化,协域取价格柱线高低差百分比变化,两个态射分别是理论假设(ATR 负变则区间负变,正变则区间正变,滞后一根柱线)和历史样本测试的交叉表映射。 具体落地时,先把两个域各切成 10 个约 20% 宽的波段,避免浮点散值难配对。假设态射是同构的:-100%~-80% 波段直映协域同波段,其余类推。测试态射则用 2021.01.01–2022.01.01 的 EURGBP 五分钟数据,指标滞后单根柱线,统计每个 ATR 波段引发对应价格区间波段的次数,取每行最高列值作为最高概率映射。 两个态射在某个 ATR 百分比波段上若都映射到协域同一波段,该波段就是均衡器。日志显示 EURUSD M5 上 -100%~0% 的五个连续波段均满足同构对齐,这部分子集可当作假设与实测的“一致区”。 别把正态当圣经 实盘里若新 ATR 变化落在均衡器域内,按通用性质直接推断对应价格区间变化;若不在子集内,什么信号都别下,等下一个指标点。外汇和贵金属杠杆高,这套映射只提高概率,不消除回撤风险。 想提精度可把通用态射换成二次关系,把新数据作指数纳入,但必须用经纪商真实跳价长周期验,否则过拟合比盲猜更贵。下面这段是 EURUSD.ln M5 的均衡器命中日志,开 MT5 接 ATR 自己跑能复现:

MQL5 / C++
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">100% to -class="num">80%)|----->(-class="num">100% to -class="num">80%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">80% to -class="num">60%)|----->(-class="num">80% to -class="num">60%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">60% to -class="num">40%)|----->(-class="num">60% to -class="num">40%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">40% to -class="num">20%)|----->(-class="num">40% to -class="num">20%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">20% to class="num">0%)|----->(-class="num">20% to class="num">0%)

回测日志里的区间映射错位

上面这段 EURUSD.ln 的 M5 回测打印,全发生在 2023.03.31 17:55:58.318 同一个时间戳,说明是策略初始化或单帧批量诊断输出,不是逐根 K 线推进。 前半段里,多头侧 0%~100% 五个区间都显示自身映射到自身,例如 (0% to 20%)→(0% to 20%),属于正常的基准对照。 空头侧开始变形:(-100% to -80%) 之后的三段 (-80%~-60%、-60%~-40%、-40%~-20%) 全部被指向 (-100% to -80%),等于把三层负区间压缩进最底一层,样本归属明显被截断。 更值得盯的是后半段交叉污染:当价格区间走到 (0% to 20%)、(20% to 40%) 时,映射目标跳到 (-40% to -20%);(60% to 80%) 反而指去 (-100% to -80%),而 (80% to 100%) 又落回 (-20% to 0%)。这种正负区间乱指,在 MT5 里通常意味着仓位百分比计算的符号处理或数组下标越界。 开 MT5 把这段日志对应的 ea 跑一遍 EURUSD.ln M5,重点看负值区间的 bin 索引是不是用了 uint 截断,外汇和贵金属杠杆品种下这类 bug 会放大穿仓风险,务必用小资金验证。

MQL5 / C++
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">0% to class="num">20%)|----->(class="num">0% to class="num">20%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">20% to class="num">40%)|----->(class="num">20% to class="num">40%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">40% to class="num">60%)|----->(class="num">40% to class="num">60%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">60% to class="num">80%)|----->(class="num">60% to class="num">80%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">80% to class="num">100%)|----->(class="num">80% to class="num">100%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">100% to -class="num">80%)|----->(-class="num">100% to -class="num">80%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">80% to -class="num">60%)|----->(-class="num">100% to -class="num">80%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">60% to -class="num">40%)|----->(-class="num">100% to -class="num">80%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">40% to -class="num">20%)|----->(-class="num">40% to -class="num">20%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (-class="num">20% to class="num">0%)|----->(-class="num">40% to -class="num">20%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">0% to class="num">20%)|----->(-class="num">40% to -class="num">20%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">20% to class="num">40%)|----->(-class="num">40% to -class="num">20%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">40% to class="num">60%)|----->(-class="num">60% to -class="num">40%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">60% to class="num">80%)|----->(-class="num">100% to -class="num">80%)
class="num">2023.03.class="num">31 class="num">17:class="num">55:class="num">58.318        ct_5(EURUSD.ln,M5) (class="num">80% to class="num">100%)|----->(-class="num">20% to class="num">0%)

◍ 把均衡器思路接进你自己的系统

前面用范畴论的均衡器比对 ATR 派生出的不同态射,本质是把采样窗内的波动结构显式化。通用性质让样本内提取的均衡关系能外推到样本外,对持仓离场和过滤信号都有参考意义。 这套做法不是黑箱:你下载的 ct_5.mq5 里,均衡器计算直接挂在 ATR 周期参数上,改 ATR 周期从 14 调到 20,MT5 策略测试器里能看到样本外波动估算的偏移。外汇和贵金属杠杆高,波动突变频繁,任何估算都只是概率倾向,实盘前先用历史数据跑一遍。 真正值得做的,是把均衡器输出的波动趋势差,接进你现有系统的出场模块,而不是另起一套。先验证、再微调,比直接信结论更稳。

常见问题

用均衡器思路把两路信号做差,差值穿过零轴的位置就是分歧点,可据此卡住入场或观望。
把原离场条件作为一路信号,反向过滤条件作为另一路,均衡器输出归零再走,能少接毛刺。
小布可加载你设好的两路条件,实时标出均衡子集边界并在分歧时推送,不用自己刷图表。
算概率较高的收敛子集,但需回看近20根是否振幅同步收缩,单根萎缩可能是假信号。
检查切片时间和点差假设,把映射窗口调成与成交延迟匹配,再用样本外数据重跑一次。