首页 / 交易学院 / 小布知识库 / MQL5 向导实战:编写自定义交易信号模块
MQL5 向导实战:编写自定义交易信号模块
🚦

MQL5 向导实战:编写自定义交易信号模块

EA 开发实战 难度 · 进阶 2012 11 分钟阅读
MQL5向导信号模块CExpertSignal

一、向导的四大支柱

通过 MQL5 向导创建的 EA 基于四个基本类:CExpert(引擎)、CExpertSignal(信号)、CExpertMoney(资金)、CExpertTrailing(追踪)。其中 CExpertSignal 负责回答“现在该不该进/平/反”。

二、CExpertSignal 虚方法签名

信号模块的本质是一组返回 bool 的虚方法。引擎每 tick 调用它们,由 EA 综合信号、资金、追踪后做最终决策。保持“只判断、不下单”是良好设计。

class CExpertSignal : public CObject
{
public:
   virtual bool Init(...) { return false; }
   virtual bool ValidationSettings(void) { return true; }
   virtual bool InitIndicators(void) { return false; }
   virtual bool CheckOpenLong(void)   { return false; }
   virtual bool CheckOpenShort(void)  { return false; }
   virtual bool CheckCloseLong(void)   { return false; }
   virtual bool CheckCloseShort(void)  { return false; }
   virtual bool CheckReverseLong(void) { return false; }
   virtual bool CheckReverseShort(void){ return false; }
   virtual bool CheckTrailingOrderLong(...)  { return false; }
   virtual bool CheckTrailingOrderShort(...) { return false; }
};

三、最小可用信号类

下面用 MACD 金叉做例子:快线上穿慢线返回开多信号。注意指标句柄在 Init/InitIndicators 中初始化。

class CSampleSignal : public CExpertSignal
{
protected:
   CiMACD m_macd;
public:
   virtual bool InitIndicators(void)
   {
      return m_macd.Create(_Symbol, PERIOD_CURRENT, 12, 26, 9);
   }
   virtual bool CheckOpenLong(void)
   {
      if(m_macd.Main(0) > m_macd.Signal(0)
      && m_macd.Main(1) <= m_macd.Signal(1))
         return true;
      return false;
   }
};

四、信号处理链

CExpert 在每个 tick 依次调用:信号模块→资金模块→追踪模块,收集各方建议,最后由 EA 决策。这种链式结构让模块可以自由组合。

五、常见坑

⚠ 加载失败的元凶
1) 必须重写 Init/InitIndicators 初始化指标句柄,否则句柄为无效值;2) ValidationSettings 返回 false 会让向导直接拒绝加载;3) 不要在主信号里直接 OrderSend,只返回 bool。

六、信号模块接口约定

向导的信号模块有一套固定接口:提供 CheckOpen/CheckClose 之类的方法,返回是否该开平仓,以及方向。任何信号只要实现这套接口,就能被向导或主 EA 即插即用,不必关心内部怎么算。

接口约定是「可插拔」的前提。想把自己的信号接进向导生态,第一步就是把逻辑包成这套接口,而非写一坨散落在 OnTick 里的判断。

七、盘点内置信号库

MQL5 向导自带一批信号模块:均线交叉、MACD、随机指标、RSI、布林带等。先用现成的拼出可跑策略,理解每个模块的输出语义,再决定哪些值得自己重写或增强。

✦ 先盘后写
内置信号库覆盖了绝大多数经典逻辑。先用现成拼可跑策略,再决定哪些自写,避免重复造轮子。

八、自定义信号接入向导

自定义信号要继承自信号基类,实现 LongCondition/ShortCondition 等虚函数,返回 0/1 信号,再在向导或主 EA 里注册。接入后它和内置信号地位相同,可参与投票组合。

一个易错点:自定义信号内部用的指标句柄要在模块初始化时获取、反初始化时释放,别在每次判断时重复 iCustom,既慢又漏句柄。

九、信号投票与权重

多个信号模块可以「投票」合成最终方向:每个模块投多/空/中性,按预设权重求和,超过阈值才动作。权重让你表达「更信哪个」——比如均线交叉权重高、RSI 权重低,组合比单信号稳。

投票还能做「冲突即观望」:多空票数接近时不出手,只在信号一致时交易,天然过滤掉大量模棱两可的行情,代价是交易次数变少。

十、信号模块的常见陷阱

两个高频坑:一是模块内部每次判断都重新 iCustom 取句柄,既慢又漏释放,句柄应在初始化获取一次;二是模块读了未来数据(如用未收盘的当前 bar 高低价),回测漂亮实盘穿帮。

第三个坑是信号「未来函数」式重绘:指标用了未来极值定参数,导致信号在历史上有、实盘没有。写模块时严格只用已确定的 bar 数据,是底线。 这条底线值得贴在显示器上:任何模块只要偷偷用了未来 bar,整条回测曲线的漂亮都是假象,实盘必然原形毕露。

十一、小结

✦ 信号模块保持纯判断
把下单与仓位交给引擎,信号模块只描述“条件是否成立”。这样同一信号可被不同资金/追踪组合复用,也便于单元测试。

常见问题

不应该。信号模块只返回开/平/反转的 bool,真正下单由 CExpert 决策,保证架构清晰。
Close 是平仓离场;Reverse 是平掉反向并反手,逻辑不同。
多半是 ValidationSettings 返回 false 或 OnInit 未初始化指标句柄,检查日志。