MQL5 中如何调用指标(基础篇)
📘

MQL5 中如何调用指标(基础篇)

第 1/2 篇

「在 MQL5 里把指标请进来」

MQL5 里调用指标不走 EA 主循环硬算,而是用 iCustom 或内置的 iMACD、iRSI 这类函数先拿到指标句柄,再靠 CopyBuffer 取数据。这套机制从 MT5 诞生起就是标准做法,官方示例在 2013-09-27 那篇基础帖里被查看过 6712 次、收到 15 条讨论,说明新手卡这儿的概率不低。 下面这段是取 MACD 指标两个缓冲区的极简骨架,句柄拿不到就别谈后续信号。外汇与贵金属杠杆高,指标失效时亏损可能迅速扩大,任何调用都先在策略测试器里跑通再上真仓。 调用核心是先建句柄、再拷缓冲、最后判空。句柄为负数基本等于指标名写错或周期不对,这时候 CopyBuffer 会直接返回 -1,硬读数组只会喂给 EA 一堆垃圾值。

MQL5 / C++
class="type">int macd_handle = iMACD(_Symbol, PERIOD_CURRENT, class="num">12, class="num">26, class="num">9, PRICE_CLOSE);
if(macd_handle == INVALID_HANDLE) class="kw">return;
class="type">class="kw">double macd_main[class="num">1], macd_signal[class="num">1];
CopyBuffer(macd_handle, class="num">0, class="num">0, class="num">1, macd_main);
CopyBuffer(macd_handle, class="num">1, class="num">0, class="num">1, macd_signal);

EA源文件怎么从零建起来

在 MQL5 里调指标基本绕不开 IndicatorCreate() 和 iCustom(),两者都只吐出一个指标句柄(handle),后续取值、计算全靠这个整数句柄去索引。句柄不是数据本身,更像 MT5 内核里那块指标缓冲区的门牌号,搞错这一步后面全白忙。 新建 EA 最顺手的办法是开 MetaEditor,走 File -> New 调出 MQL5 Wizard。第一步选「EA 交易」点 Next;第二步填 EA 名称(必填)和作者,输入参数可以先留空,后面直接在代码里补。 点 Finish 后向导会生成一份最小可编译骨架,里面只包含 OnInit、OnDeinit、OnTick 三个空函数。下面这段就是默认产出的源码,注意版权行里的作者名会直接写成你刚填的字段。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                 SampleMQL5.mq5 |
class=class="str">"cmt">//|                                                Copyright KlimMalgin |
class=class="str">"cmt">//|                                                          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "KlimMalgin"
class="macro">#class="kw">property link      ""
class="macro">#class="kw">property version   "class="num">1.00"
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA初始化函数                                               |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
  {
class=class="str">"cmt">//---
  
class=class="str">"cmt">//---
   class="kw">return(class="num">0);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA去初始化函数                                             |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnDeinit(const class="type">int reason)
  {
class=class="str">"cmt">//---
  
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA tick函数                                                 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnTick()
  {
class=class="str">"cmt">//---
  
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
逐行看:#property 三行是元数据,copyright 填了 KlimMalgin、link 为空、version 1.00;OnInit 返回 0 表示初始化成功,返回非 0 会让 EA 加载失败;OnDeinit 拿 reason 知道被卸载原因;OnTick 每个报价触发一次,现在全空,后续接指标句柄就写这儿。 外汇和贵金属杠杆高、滑点跳空频繁,EA 未接实盘逻辑前别直接挂真仓,先接句柄跑几根 K 线看返回是不是 INVALID_HANDLE(-1)。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                 SampleMQL5.mq5 |
class=class="str">"cmt">//|                                                Copyright KlimMalgin |
class=class="str">"cmt">//|                                                          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "KlimMalgin"
class="macro">#class="kw">property link      ""
class="macro">#class="kw">property version   "class="num">1.00"
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA初始化函数                                               |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
  {
class=class="str">"cmt">//---
  
class=class="str">"cmt">//---
   class="kw">return(class="num">0);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA去初始化函数                                             |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnDeinit(const class="type">int reason)
  {
class=class="str">"cmt">//---
  
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA tick函数                                                 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnTick()
  {
class=class="str">"cmt">//---
  
  }
class=class="str">"cmt">//+------------------------------------------------------------------+

◍ 拆开 EA 源文件看骨架

打开任意 MT5 的 EA 源码,最顶端是一段头注释,写清文件名和作者;紧跟着是 #property 区块,用来声明程序属性。这里有个坑:属性必须写在主 mql5 文件里,被 include 进来的文件就算写了 #property 也会被编译器直接忽略。 头文件和属性之后是输入参数区(初期可留空)与全局变量声明。再往下才是真正跑逻辑的三个事件函数。OnInit() 在 EA 加载、品种属性变更或周期切换时触发一次,负责初始化;OnDeinit(const int reason) 同样只跑一次,在 EA 停止或重初始化时执行,reason 里带着退出的原因代码;OnTick() 最频繁,所在图表每来一个新报价就调用一次。 想在 MT5 里验证很简单:新建一个空白 EA,把 OnInit/OnDeinit/OnTick 各打印一行 Comment,挂上 EURUSD 图表,切换周期就能看到前两个函数各跑一次,而报价跳动会刷屏 OnTick。外汇与贵金属杠杆高,实盘前务必先在策略测试器跑历史数据。

「从 iCustom 到句柄:MQL5 取数逻辑变了」

老 MQL4 玩家刚切到 MQL5 最容易踩的坑,就是还想着用 iCustom() 按柱索引直接掏指标缓冲区。MQL5 改了路数:先拿句柄(handle),再用 CopyBuffer() 按区间把值拷出来,柱索引变成 CopyBuffer 的参数而非指标调用的参数。 句柄本质就是一个 int 型整数,是某个指标实例的唯一标识。拿到它之前,你跟指标之间根本没有通信通道。MQL5 给句柄提供了两条等价路径:IndicatorCreate() 成功返回句柄、失败返回 -1;或者直接调具体技术指标函数(如 iMA、iRSI),返回值同样是句柄或 -1。 两种写法在 MT5 里跑出来的结果没有优劣之分,选哪个纯看你是想动态建指标还是直接调现成技术函数。开 MT5 按 F4 建个空 EA,分别用两种方式取一下 EURUSD 的 MA 句柄,Print 出来对比整数返回值,比看文档直观得多。外汇与贵金属杠杆高,实盘前务必先在策略测试器验证句柄失效(返回 -1)的异常处理。

常见问题

打开客户端左侧导航栏的「导航器」,右键「专家顾问」选新建,按向导生成 .mq5 文件,默认存于 MQL5/Experts 目录下,编译后才会出现在列表里。
OnInit 只跑一次负责初始化句柄和校验,OnTick 每次报价触发跑交易逻辑;新手常把指标句柄创建写进 OnTick,导致反复申请拖慢执行。
可以,小布盯盘的 AIGC 已内置常见指标诊断与异动提醒,打开对应品种页就能看到,把重复劳动交给小布,你专注决策。
MQL5 改为句柄机制,先 iCustom 拿到指标标识,再用 CopyBuffer 按索引拷数组,避免旧版全局变量冲突,数据更隔离稳定。
先确认文件在 Experts 目录且重新编译无报错,再看图表右键「EA 交易」是否勾选启用,以及 OnInit 返回值是否为 INIT_SUCCEEDED。