MQL5交易策略自动化(第十二部分):实现缓解型订单块(MOB)策略(基础篇)
◍ 把缓解型订单块搬进EA框架
缓解型订单块(MOB)和经典订单块不同:它不要求价格必须回到原块才反转,而是把「缓解」动作本身当作结构确认信号。在MT5里做自动化,第一步是把K线极值与成交分布挂钩,而不是只画一个矩形区域。 原文给出的系列文章截至2025年11月14日已发布第12部分,单篇浏览量1161、评论7条,说明这类结构在MQL5社区属于高频迭代主题。你在Terminal里开一图多周期,就能看到MOB在H1和M5上的触发密度差异明显。 落地时建议先用iClose/iHigh把最近N根K线极值缓存进数组,再写判定函数区分「未缓解」与「已缓解」状态。这样后续挂单逻辑才有明确开关,而不是靠肉眼圈区域。外汇与贵金属杠杆品种波动剧烈,MOB失效概率不低,任何信号都只能当作概率倾向而非确定性。
从网格系统切到缓解型订单块
上一篇文章里我们用 MQL5 搭了一套多层级网格交易系统,靠市场波动刷利润。这一篇不接着卷网格,转而落地缓解型订单块(MOB)策略——它属于聪明资金体系,用来圈出机构订单被消化前的关键价位区,往往在大波动发动前就有痕迹。 本小节先把路线铺开:先讲策略设计骨架,再写 MQL5 实现,然后跑回测,最后给结论。外汇和贵金属杠杆高、滑点狠,MOB 信号只是概率倾向,不是进场就稳。 读完这一节你能做一件事:打开 MT5 新建一个 EA 工程,预留 OnTick 里接 MOB 检测函数的位置,等后面几节把逻辑填进去。
「缓解型订单块的 EA 骨架怎么搭」
要把缓解型订单块跑成自动化系统,核心不是画个区就进场,而是先确认机构在哪吸收了流动性、趋势延续前价格是否真的回踩并被拒绝。MT5 上这套逻辑可以拆成五段独立模块,每段都能单独回测调参。 订单块识别先扫历史走势抓多空块,再用波动性、流动性捕捉和价格失衡做过滤,把弱势区域剔除;缓解验证则要求价格重新触块并出现影线或动量转变才算数,避免假突破诱多诱空。 市场结构确认放在更高时间框架看趋势与流动性扫荡,保证识别出的缓解块和主流向一致。交易执行上,入场点等缓解确认后定位,止损按订单块结构动态算,止盈交给风险回报参数,不拍脑袋。 外汇与贵金属杠杆高、滑点大,这套 EA 即便验证有效也只代表历史样本下的概率优势,实盘前务必用 MT5 策略测试器按品种分段跑回测。风险与资金管理模块要内嵌头寸规模与回撤保护,否则一次流动性黑天鹅就能清掉账户。
◍ MT5里把盘整突破订单块写成EA的骨架
打开 MetaEditor,在导航器「指标」或 EA 文件夹下新建文件,先 #include <Trade/Trade.mqh> 引入交易库,再用 CTrade 类实例化 obj_Trade,这样后续买单卖单都能编程触发,不依赖手动操作。输入参数要暴露给 UI:tradeLotSize 管仓位,enableTrading 与 enableTrailingStop 分别管开关,trailingStopPoints 和 minProfitToTrail 细化跟踪止损;uniqueMagicNumber 隔离本策略订单,consolidationBars 与 maxConsolidationSpread 定义盘整区间,barsToWaitAfterBreakout 和 impulseMultiplier 确认突破后强劲走势,stopLossDistance / takeProfitDistance 管风险,剩下四个 Color 参数管图表绘制。 全局结构里先定义 PriceAndIndex 结构体存「价格+K线索引」,再用 rangeHighestHigh / rangeLowestLow 记盘整高低边界,isBreakoutDetected 做突破旗标,lastImpulseHigh / lastImpulseLow 抓突破后首波极点。breakoutBarNumber 和 breakoutTimestamp 留痕,orderBlockNames / orderBlockEndTimes / orderBlockMitigatedStatus 三个数组跟踪区块生命周期,OB_Prefix 用 #define 写死前缀保证对象命名一致。 OnInit 里 SetExpertMagicNumber 打标记后返回 INIT_SUCCEEDED;OnTick 中用 iBars 取 currentBarCount 与 previousBarCount 比对,相等就提前 return,只在「新K线」成立时跑逻辑,省掉每个 tick 的重复计算。盘整检测从 startBarIndex=1 起,遍历最近 consolidationBars 根 K 线,MathAbs 算相邻高低差,全部 ≤ maxConsolidationSpread 才认定横盘,随后扫出区间最高最低。 突破判定拿 close 价比 rangeHighestHigh.price / rangeLowestLow.price:上破设 isBreakoutDetected=true 并记录,下破同理;确认后 breakoutBarNumber 置 1、TimeCurrent 写 breakoutTimestamp,存 lastImpulse 极点与重置区间值为 0。等待 barsToWaitAfterBreakout * PeriodSeconds 秒后,用 impulseRange * impulseMultiplier 得 impulseThresholdPrice,扫最近若干根收盘价,≥ lastImpulseHigh+阈值记多头强劲、≤ lastImpulseLow-阈值记空头强劲。 有效订单块用 iTime(consolidationBars+barsToWaitAfterBreakout+1) 取 blockStartTime,top/bottom 套 lastImpulse 极点,OBJ_RECTANGLE 画矩形并 OBJ_TEXT 写居中标签,ChartRedraw 立即刷新;数组 ArrayResize 追加名称、结束时间与失效状态。逆向遍历 orderBlockNames,用 ObjectGetDouble / ObjectGetInteger 取每个块的高低与起止时间,准备做失效判定和交易触发——到这一步,MT5 上已能肉眼看到带时间戳的 OB 方块,接下来就是验证价格回踩是否吃掉它。
失效判定与追踪止损的落地写法
订单块是否还活著,靠 time(1) 与 orderBlockEndTime 的比对来决定。当前 K 线时间仍在有效期内,doesOrderBlockExist 置 true,后续交易逻辑才跑得起来;一旦价格刺穿边界——多块破 low、空块破 high——支撑阻力结构就算废了,orderBlockMitigatedStatus[j] 改 false 为 true,同时用 ObjectSetInteger 换颜色、ObjectSetString 把标签写成 Mitigated Bullish/Bearish Order Block,肉眼就能看出哪块已经失效。 具体下单时,SymbolInfoDouble 取来的 ask/bid 会用 _Digits 标准化小数位,避免黄金报价 3 位或 5 位小数时价格精度错乱。多块失效走 Sell:currentBidPrice 入场,止损在上方 stopLossDistance * _Point,止盈在下方 takeProfitDistance * _Point;空块反过来走 Buy,方向镜像。外汇与贵金属杠杆高,刺穿边界只是概率性失效信号,实盘前务必在 MT5 策略测试器用历史数据验一遍边界容差。 超期或已失效的块用 ArrayRemove 从名称、结束时间、状态三个数组里剔掉,Print 留痕确认清理。追踪止损单独封了 applyTrailingStop 函数:按 trailingStopPoints(默认 30 点)算新止损,遍历未平头寸按 symbol + magic(12345) 过滤,买权新止损高于开仓价且优于原止损才改,卖权反之。 OnTick 里直接调这个函数,每个 tick 都重算而不是等根 K 线收线,止损跟得紧。下面这段输入参数就是你抄进 EA 头部就能编译的骨架,Magic、手数 0.01、 consolidating 判定 7 根 K 线内 spread 不超 50 点都在里头,改两个数就能跑自己的品种。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Copyright class="num">2025, Forex Algo-Trader, Allan. | class=class="str">"cmt">//| "https://t.me/Forex_Algo_Trader" | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Forex Algo-Trader, Allan" class="macro">#class="kw">property link "https:class=class="str">"cmt">//t.me/Forex_Algo_Trader" class="macro">#class="kw">property version "class="num">1.00" class="macro">#class="kw">property description "This EA trades based on Mitigation Order Blocks Strategy" class="macro">#class="kw">property strict class=class="str">"cmt">//--- Include the trade library for managing positions class="macro">#include <Trade/Trade.mqh> CTrade obj_Trade; class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Input Parameters | class=class="str">"cmt">//+------------------------------------------------------------------+ input class="type">class="kw">double tradeLotSize = class="num">0.01; class=class="str">"cmt">// Trade size for each position input class="type">bool enableTrading = true; class=class="str">"cmt">// Toggle to allow or disable trading input class="type">bool enableTrailingStop = true; class=class="str">"cmt">// Toggle to enable or disable trailing stop input class="type">class="kw">double trailingStopPoints = class="num">30; class=class="str">"cmt">// Distance in points for trailing stop input class="type">class="kw">double minProfitToTrail = class="num">50; class=class="str">"cmt">// Minimum profit in points before trailing starts(not used yet) input class="type">int uniqueMagicNumber = class="num">12345; class=class="str">"cmt">// Unique identifier for EA trades input class="type">int consolidationBars = class="num">7; class=class="str">"cmt">// Number of bars to check for consolidation input class="type">class="kw">double maxConsolidationSpread = class="num">50; class=class="str">"cmt">// Maximum allowed spread in points for consolidation