MQL5 初学者:EA 交易技术指标使用指南·进阶篇
(2/3)· 从 iMA 延伸到 iAC、iADXWilder 等 6 个内置指标,搞清句柄创建与序列索引的坑
◍ 用 OnTick 拉取鳄鱼线缓冲
在 MT5 的 EA 骨架里,订单逻辑往往从 OnTick 入口开始。这里不急着下单,而是先把鳄鱼指标(Alligator)的三条线缓冲抓进数组,供后续价格行为判断使用。 调用 GetAlligatorBuffers 时传入指标句柄、起始位置 0、取样长度 100,以及 Jaws、Teeth、Lips 三个数组,最后一个 true 表示按时间序列倒序填充。若返回失败直接 return,避免脏数据继续跑策略。 这段代码本身不下单,但它是后面所有信号判定的数据底座。打开 MT5 新建 EA,把这段塞进 OnTick 开头,编译后从观测窗口能看到三个数组被 100 根 K 线的鳄鱼值填满。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA订单函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { class=class="str">"cmt">//--- 设置数组索引为时间序列 class=class="str">"cmt">//--- 使用Alligator指标数值填充数组 class=class="str">"cmt">//--- 如果出错则返回 if(!GetAlligatorBuffers(Alligator_handle,class="num">0,class="num">100,Jaws,Teeth,Lips,true)) class="kw">return; }
「用 iAC 句柄把动能加速度拉进 EA」
加速震荡指标(AC)量的是中间价慢速与快速均线之差再减去这两条差值的均线,本质在捕捉价格加速度的转向。MT5 里不用手算,直接调 iAC(NULL,0) 拿句柄最省事。 下面这段 EA 骨架演示了怎么把 AC 接进来:初始化时建句柄,失败就打印错误并退出;OnTick 里用 CopyBufferAsSeries 把最近 100 根柱的 AC 值按时间序灌进数组。 #include <GetIndicatorBuffers.mqh> //---- 指标数组 double AC[]; // iAC指标对应的数组 //---- 指标句柄 int AC_handle; // iAC指标的句柄 //+------------------------------------------------------------------+
| // | EA初始化函数 |
|---|
//+------------------------------------------------------------------+ int OnInit() { //--- 创建iAC指标 AC_handle=iAC(NULL,0); //--- 如果对象创建出错则报告 if(AC_handle<0) { Print("iAC指标创建失败: 运行时错误 =",GetLastError()); //--- 强制程序退出 return(-1); } return(0); } //+------------------------------------------------------------------+
| // | EA订单函数 |
|---|
//+------------------------------------------------------------------+ void OnTick() { //--- 使用当前iAC的值填充AC[]数组 //--- 设置AC[] 索引方向为时间序列 //--- 如果出错则返回 if(!CopyBufferAsSeries(AC_handle,0,0,100,true,AC)) return; } 逐行看:第 1 行引头文件拿辅助函数;AC[] 存数值,AC_handle 存指标引用。OnInit 中 iAC(NULL,0) 表示用当前品种、当前周期。OnTick 的 CopyBufferAsSeries 第 4 参 100 决定取多少根,调大能看更长惯性。 外汇与贵金属杠杆高,AC 仅作动能参考,信号失效概率不低。开 MT5 把这段代码贴进 EA,把 100 改成 50 对比一下刷新频率,就能直观感觉加速度指标的滞后程度。
class="macro">#include <GetIndicatorBuffers.mqh> class=class="str">"cmt">//---- 指标数组 class="type">class="kw">double AC[]; class=class="str">"cmt">// iAC指标对应的数组 class=class="str">"cmt">//---- 指标句柄 class="type">int AC_handle; class=class="str">"cmt">// iAC指标的句柄 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA初始化函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">//--- 创建iAC指标 AC_handle=iAC(NULL,class="num">0); class=class="str">"cmt">//--- 如果对象创建出错则报告 if(AC_handle<class="num">0) { Print("iAC指标创建失败: 运行时错误 =",GetLastError()); class=class="str">"cmt">//--- 强制程序退出 class="kw">return(-class="num">1); } class="kw">return(class="num">0); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA订单函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { class=class="str">"cmt">//--- 使用当前iAC的值填充AC[]数组 class=class="str">"cmt">//--- 设置AC[] 索引方向为时间序列 class=class="str">"cmt">//--- 如果出错则返回 if(!CopyBufferAsSeries(AC_handle,class="num">0,class="num">0,class="num">100,true,AC)) class="kw">return; }
用 iAD 句柄抓累积分布流向
累积/分配指标(AD)把收盘价在当日区间的位置和成交量加权,用来观察资金是往多头还是空头一侧堆积。MT5 里它靠 iAD() 拿句柄,再靠 CopyBuffer 把数值拉进数组,比老式 iCustom 调用干净得多。 下面这段 EA 骨架在 OnInit 里用 iAD(NULL,0,VOLUME_TICK) 建句柄,参数分别是当前品种、当前周期、按 tick 成交量计。句柄小于 0 就打印错误并退出,避免后面空跑。 OnTick 中 CopyBufferAsSeries 一次性取最近 100 根 Bar 的 AD 值,索引按时间序列排,最新值在 AD[0]。你在 MT5 里把这段贴进 EA,编译后开 EURUSD 的 M1 图表,就能在观测窗口看到 AD 数组随 tick 流实时翻动,验证多空累积倾向。外汇和贵金属杠杆高,AD 只反映历史堆积,转向信号要结合价格结构看,别单靠它下注。
class="macro">#include <GetIndicatorBuffers.mqh> class=class="str">"cmt">//---- 指标数组 class="type">class="kw">double AD[]; class=class="str">"cmt">// iAD指标对应的数组 class=class="str">"cmt">//---- 指标句柄 class="type">int AD_handle; class=class="str">"cmt">// iAD指标的句柄 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA初始化函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">//--- 创建iAD指标 AD_handle=iAD(NULL,class="num">0,VOLUME_TICK); class=class="str">"cmt">//--- 如果对象创建出错则报告 if(AD_handle<class="num">0) { Print("iAD指标创建失败: 运行时错误 =",GetLastError()); class=class="str">"cmt">//--- 强制程序退出 class="kw">return(-class="num">1); } class="kw">return(class="num">0); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA订单函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { class=class="str">"cmt">//--- 使用iAD指标当前值填充AD[]数组 class=class="str">"cmt">//--- 设置AD[]数组的索引方式为时间序列 class=class="str">"cmt">//--- 如果出错则返回 if(!CopyBufferAsSeries(AD_handle,class="num">0,class="num">0,class="num">100,true,AD)) class="kw">return; }
◍ 用 iADX 抓三条线缓冲
ADX 在 MT5 里不是单值指标,iADX 一口气吐出主线和正负方向线三条缓冲。上面这段把句柄建好、在 OnTick 里拉 100 根柱的数据灌进数组,省得你每根 K 线都去调 CopyBuffer。 建句柄时周期传 0 代表当前图表周期,参数 14 是默认 ADX 周期。若 ADX_handle 小于 0 说明指标没建出来,直接打印错误码并让 OnInit 返回 -1,EA 起不来,避免后面空跑。 GetADXBuffers 那行把 Main、PlusDI、MinusDI 三个 double 数组按时间序列填充,从 0 到 100 根。实盘里你可以把 100 改成需要的深度,比如只看最近 50 根来判断 +DI 是否持续压过 -DI,从而倾向弱趋势过滤。外汇与贵金属杠杆高,ADX 只描述趋势强度,不预示方向,信号失效概率不低,验证前先用策略测试器跑一遍。
class="macro">#include <GetIndicatorBuffers.mqh> class=class="str">"cmt">//---- 指标数组 class="type">class="kw">double Main[]; class=class="str">"cmt">// iADX中MAIN_LINE对应的数组 class="type">class="kw">double PlusDI[]; class=class="str">"cmt">// iADX中PLUSDI_LINE对应的数组 class="type">class="kw">double MinusDI[]; class=class="str">"cmt">// iADX中MINUSDI_LINE对应的数组 class=class="str">"cmt">//---- 指标句柄 class="type">int ADX_handle; class=class="str">"cmt">// iADX指标的句柄 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA初始化函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">//--- 创建iADX指标 ADX_handle=iADX(NULL,class="num">0,class="num">14); class=class="str">"cmt">//--- 如果对象创建出错则报告 if(ADX_handle<class="num">0) { Print("iADX指标创建失败: 运行时错误 =",GetLastError()); class=class="str">"cmt">//--- 强制程序退出 class="kw">return(-class="num">1); } class="kw">return(class="num">0); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA订单函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { class=class="str">"cmt">//--- 设置数组索引为时间序列 class=class="str">"cmt">//--- 使用指标缓冲区的当前值填充数组 class=class="str">"cmt">//--- 如果出错则返回 if(!GetADXBuffers(ADX_handle,class="num">0,class="num">100,Main,PlusDI,MinusDI,true)) class="kw">return; }
「用 iADXWilder 拉三条线进 EA」
Wilder 版 ADX 和原生 iADX 的区别只在平滑算法,MT5 里单独给了 iADXWilder 接口。想在 EA 里同时拿 ADX 主线、+DI、-DI,得先建三个 double 数组挂缓冲,再用指标句柄去取。 下面这段初始化只做一件事:用 iADXWilder(NULL,0,14) 在当前品种、当前周期、周期参数 14 上建句柄。句柄小于 0 就打印错误并强制退出 OnInit,避免后面空句柄乱跑。 OnTick 里调 GetADXWilderBuffers,从 0 到 100 根 K 线把三条线填进数组;最后一个 true 表示按时间序索引。取数失败直接 return,不拿残值做判断。 开 MT5 把这段贴进 EA,编译后接 Print(Main[0],PlusDI[0],MinusDI[0]),能看到最新三根线数值。外汇和贵金属波动大,DI 交叉只反映强弱倾向,不代表趋势必然延续,实盘前先用策略测试器跑历史验证。
class="macro">#include <GetIndicatorBuffers.mqh> class=class="str">"cmt">//---- 指标数组 class="type">class="kw">double Main[]; class=class="str">"cmt">// iADXWilder指标中的MAIN_LINE对应的数组 class="type">class="kw">double PlusDI[]; class=class="str">"cmt">// iADXWilder指标中的PLUSDI_LINE对应的数组 class="type">class="kw">double MinusDI[]; class=class="str">"cmt">// iADXWilder指标中的MINUSDI_LINE对应的数组 class=class="str">"cmt">//---- handles for indicators class="type">int ADXWilder_handle; class=class="str">"cmt">// iADXWilder指标的句柄 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA初始化函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">//--- 创建iADXWilder指标 ADXWilder_handle=iADXWilder(NULL,class="num">0,class="num">14); class=class="str">"cmt">//--- 如果对象创建出错则报告 if(ADXWilder_handle<class="num">0) { Print("创建 iADXWilder 指标失败: 运行时错误 =",GetLastError()); class=class="str">"cmt">//--- 强制程序退出 class="kw">return(-class="num">1); } class="kw">return(class="num">0); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA订单函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { class=class="str">"cmt">//--- 设置数组索引方式为时间序列 class=class="str">"cmt">//--- 使用所有指标对应缓冲区的当前值填充数组 class=class="str">"cmt">//--- 如果出错则返回 if(!GetADXWilderBuffers(ADXWilder_handle,class="num">0,class="num">100,Main,PlusDI,MinusDI,true)) class="kw">return; }
用句柄把鳄鱼三线拉进EA
iAlligator 在 MT5 里返回的是指标句柄,不是直接的价格数组。上面这段把经典参数 13/8/8/5/5/3 一次性传给构造函数:颚线周期13偏移8,齿线周期8偏移5,唇线周期5偏移3,平滑用 MODE_EMA、价格取中位数。 初始化阶段若句柄小于0,说明指标创建失败,直接打印运行时错误并 return(-1) 终止 EA,避免后面空句柄去读缓冲区。 OnTick 里靠 GetAlligatorBuffers 把最近100根 K 线的 Jaws、Teeth、Lips 三个数组填好,时间序列索引打开,最新值在[0]。外汇和贵金属波动剧烈,鳄鱼线只是概率过滤,实盘前请在 MT5 策略测试器用不同品种验证参数敏感性。 把这段直接贴进 EA,改 NULL 为具体品种名就能在别的图表上复用;句柄创建一次即可,别在 OnTick 里反复调用 iAlligator,否则可能拖慢 tick 处理。
class="macro">#include <GetIndicatorBuffers.mqh> class=class="str">"cmt">//---- 指标数组 class="type">class="kw">double Jaws[]; class=class="str">"cmt">// iAlligator指标中GATORJAW_LINE对应的数组 class="type">class="kw">double Teeth[]; class=class="str">"cmt">// iAlligator指标中GATORTEETH_LINE对应的数组 class="type">class="kw">double Lips[]; class=class="str">"cmt">// iAlligator指标中GATORLIPS_LINE对应的数组 class=class="str">"cmt">//---- 指标句柄 class="type">int Alligator_handle; class=class="str">"cmt">// iAlligator指标的句柄 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA初始化函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">//--- 创建iAlligator指标 Alligator_handle=iAlligator(NULL,class="num">0,class="num">13,class="num">8,class="num">8,class="num">5,class="num">5,class="num">3,MODE_EMA,PRICE_MEDIAN); class=class="str">"cmt">//--- 如果对象创建出错则报告 if(Alligator_handle<class="num">0) { Print("创建iAlligator指标失败: 运行时错误 =",GetLastError()); class=class="str">"cmt">//--- 强制程序退出 class="kw">return(-class="num">1); } class="kw">return(class="num">0); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA订单函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { class=class="str">"cmt">//--- 设置数组索引方式为时间序列 class=class="str">"cmt">//--- 使用所有指标缓冲区当前值填充到数组中 class=class="str">"cmt">//--- 如果出错则返回 if(!GetAlligatorBuffers(Alligator_handle,class="num">0,class="num">100,Jaws,Teeth,Lips,true)) class="kw">return; }