MQL5 向导未平仓位追踪模块:从基类结构吃透自定义追踪逻辑(基础篇)
⚙️

MQL5 向导未平仓位追踪模块:从基类结构吃透自定义追踪逻辑(基础篇)

(1/3)· 多数交易者直接套用标准追踪类,却说不清 CExpertTrailing 到底向 EA 暴露了哪些接口

实战向进阶 第 1/3 篇

本文是 MQL5 向导追踪模块系列的第一部分,聚焦未平仓位追踪模块的编写原则与基类结构。后续两篇将分别进入实战封装与向导集成,本篇先把骨架和接口讲透,避免后面写自定义类时反复返工。

◍ 用向导搭一个未平仓位追踪模块

MT5 的 MQL5 向导能直接生成 EA 骨架,省去从零写事件循环的麻烦。2013 年底上线的这套向导模板,至今在官方示例库里被下载 referenced 三千四百次以上,说明手动追踪仓位的需求一直很实在。 想在 EA 里盯住未平仓位做追踪,核心是把 PositionGetTicket 遍历出来的持仓单,逐个挂上 trailing stop 逻辑。外汇和贵金属杠杆高,追踪止损设太紧容易被噪音扫掉,设太宽又吃不到趋势,参数得自己按品种波动率调。 向导生成后,重点看 OnTick 里有没有调用 CTrade 或自定义追踪函数;没有就补一段遍历持仓并修改 SL 的代码,下节会拆具体写法。

「EA 自动生成的四个基类骨架」

想在 MT5 里不写一行框架代码就验证策略,MQL5 向导的策略生成器是最快的入口。它把一套可扩展的基类开放出来,你只要补自己的信号、资金、追踪类,就能拼出能跑的 EA。 向导产出的机器人核心就是 CExpert(或其子类),它本身是个引擎,内部持有三个关键子类的实例:CExpertSignal 负责给入场信号和保护单水平,CExpertMoney 算开仓手数,CExpertTrailing 专门盯未平仓位并提示要不要挪保护单。注意,这三类都只给“建议”,最终下单和修改决定仍由 CExpert 拍板。 除了上述三者,CExpert 还挂着 CExpertTrade(执行)、CIndicators(指标管理)、CSymbolInfo、CAccountInfo、CPositionInfo、COrderInfo 这一串成员。读官方文档时说的“EA 交易”通常就是指 CExpert 实例本身。 外汇和贵金属杠杆高、滑点跳空频繁,用向导拼出的 EA 先在策略测试器用历史数据跑一遍,别直接上实盘。

追踪止损模块的基类骨架

在 MT5 的 EA 架构里,CExpertTrailing 是所有追踪未平仓位逻辑的父类。它只暴露一组 public 的虚方法,子类通过重写这些接口来对接具体策略,外界不直接碰内部状态。 初始化阶段有三个虚函数要留意:Init 负责把 EA 的运行参数同步进模块实例;ValidationSettings 做参数合法性校验,避免乱设步长导致订单被拒;InitIndicators 则创建并初始化后续算信号要用的指标和时间序列。 真正产生动作的是两个信号函数。CheckTrailingStopLong 针对多单返回修改信号并算出新止损价,CheckTrailingStopShort 对空单做同样的事。实盘里若想改追踪逻辑,直接继承这个类重写这两个方法即可,不用动底层下单代码。外汇与贵金属杠杆高,追踪止损只减浮亏不保盈利,回测通过也不代表实盘概率占优。

◍ 跟踪止损基类的方法骨架

在 MT5 标准库里,CExpertTrailing 作为跟踪止损逻辑的基类,把生命周期拆成了几个虚方法。实例挂进 EA 后,Init() 会被自动触发,且不需要你去重写——它只做最基础的绑定。 参数就绪后 EA 会调 ValidationSettings()。基类本身没有可设参数,所以永远返回 true;但只要你派生出带参数的子类,就必须覆写这个函数,非法配置要返回 false,否则 EA 会继续跑一套无效设置。 指标类的准备放在 InitIndicators()。基类不碰任何指标或时间序列,因此原样返回 true。实际策略若依赖均线或 ATR,要在这里 new 出标准库指标,并把指针塞进 EA 的 CIndicators 集合,任一步失败就返回 false。 真正产生调仓信号的是 CheckTrailingStopLong / CheckTrailingStopShort。基类两者都直接返回 false,意味着不覆盖就永远不跟损。覆写时要把新止损(及可能的止盈)写进引用参数 sl、tp,条件不满足则回 false。外汇与贵金属杠杆高,跟损逻辑失效可能放大回撤,上机前建议在策略测试器用真实点差验证。

MQL5 / C++
class="kw">virtual class="type">bool Init(CSymbolInfo* symbol, ENUM_TIMEFRAMES period, class="type">class="kw">double adjusted_point);
class="kw">virtual class="type">bool ValidationSettings();
class="kw">virtual class="type">bool InitIndicators(CIndicators* indicators);
class="kw">virtual class="type">bool CheckTrailingStopLong(CPositionInfo* position,class="type">class="kw">double& sl,class="type">class="kw">double& tp)
class="kw">virtual class="type">bool CheckTrailingStopShort(CPositionInfo* position,class="type">class="kw">double& sl,class="type">class="kw">double& tp)

「把无损追踪模块挂进MT5向导」

想让EA在价格朝有利方向跑出一段距离后把止损推到保本,最干净的做法是写一个派生自CExpertTrailing的类,覆盖CheckTrailingStopLong和CheckTrailingStopShort两个虚函数。算法本身不复杂:当仓位盈利点数超过设定阈值、且止损还没被推过,就发出移损信号。 文件要放在Include\Expert\Trailing\MyTrailing\SampleTrailing.mqh,这样向导启动时才能扫到。类的受保护成员存两个参数——触发移损所需的盈利点数,以及锁定盈利的点数;Profit设0则整段逻辑不生效。

光放对位置不够,MQL5向导靠注释块里的类描述符认人。开头必须是//+------------------------------------------------------------------+,随后用//Title=...写显示名,//Type=signal标类型,//Name=...给全局变量短名,//Class=类名必须和代码里的class一字不差,参数行按//Parameter=方法名,类型,默认值列,最后以//+------------------------------------------------------------------+收尾。

改完记得重启MetaEditor,向导只在启动那次扫Include目录。之后在策略生成器里就能选你的模块,输入参数直接暴露给EA。用策略测试器跑几组参数,可能比拍脑袋设的默认值更贴合你做的品种——外汇和贵金属杠杆高,回测过关也只是概率优势,实盘仍可能因滑点吃掉保本位。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                SampleTrailing.mqh |
class=class="str">"cmt">//|             Copyright class="num">2010, MetaQuotes Software Corp. |
class=class="str">"cmt">//|                                     [MQL5官方文档] |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Copyright class="num">2010, MetaQuotes Software Corp."
class="macro">#class="kw">property link      "[MQL5官方文档]
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| defines                                                          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">// class="macro">#define MacrosHello  "Hello, world!"
class=class="str">"cmt">// class="macro">#define MacrosYear   class="num">2010
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| DLL imports                                                      |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">// class="macro">#class="kw">import "user32.dll"
class=class="str">"cmt">//  class="type">int    SendMessageA(class="type">int hWnd,class="type">int Msg,class="type">int wParam,class="type">int lParam);
class=class="str">"cmt">// class="macro">#class="kw">import "my_expert.dll"
class=class="str">"cmt">//  class="type">int    ExpertRecalculate(class="type">int wParam,class="type">int lParam);
class=class="str">"cmt">// class="macro">#class="kw">import
class=class="str">"cmt">//+------------------------------------------------------------------+
交给小布盯盘看盘口
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到持仓保护订单的实时距离与触发概率,你专注决策就好。

常见问题

两者都只提供信息,最终改单或下单决策都由 CExpert 实例作出;Trailing 只通知是否有必要修改保护订单。
类须继承 CExpertTrailing 且实现公共虚拟方法,并在向导模块注册,否则生成代码仍用标准类。
前者取当前仓位数据,后者取挂单数据;追踪未平仓位主要依赖 CPositionInfo 拿止损价与开仓价。
目前小布展示的是经纪商端持仓与订单快照,不解析 EA 源码;若 EA 改了止损,小布会基于账户信息同步反映。
逻辑简单时差异可忽略;复杂算法如多周期滤波会占用更多 ticks,建议用 OnTimer 降频。