您应当知道的 MQL5 向导技术(第 44 部分):平均真实范围(ATR)技术指标(基础篇)
「用 MQL5 向导把 ATR 塞进 EA」
MQL5 向导从 Build 2875 起支持以「技术指标」类模板直接挂接 ATR,无需手写 iATR 调用即可在 EA 初始化阶段拿到句柄。对做价格行为策略的交易者来说,这意味着把波动率阈值从硬编码改成向导参数,只改面板就能切换 14 周期与 5 周期 ATR。
实测在 MT5 终端加载一篇含 ATR 的向导 EA,日志会打印类似 ATR handle = 12345678 的句柄值;若返回 INVALID_HANDLE(0xFFFFFFFF),多半是品种没开市或时间帧不匹配。外汇与贵金属杠杆高,ATR 放大止损不等于降低风险,参数调大仅代表容忍更宽波动,爆仓概率仍随仓位上升。
想验证:开 MT5 → 文件/新建 → 智能交易系统(向导)→ 选「指标信号」→ 勾 Average True Range。生成后看 OnInit 里是否自动出现 iATR(_Symbol, _Period, 14),这就是 wizard 替你写的底层调用。
ATR 为什么被外汇圈当成准成交量
平均真实范围(ATR)在外汇交易者手里,常被当作“最接近成交量”的代理指标。它只跟踪每根价格柱的真实波幅,刻意忽略柱线内部来回的噪音,这让它比单纯的高低价差更能反映市场参与强度。 对老手来说,ATR 早已不是单纯的趋势过滤器:它既用来卡掉波动太小的假信号,也直接喂给仓位规模公式。比如波动翻倍时,同等风险下的手数通常要减半,这套逻辑在 MT5 里用 iATR 取数就能立刻验证。 本系列会沿用拆解形态的思路来拆 ATR,和之前指标文章类似,但重点会放在两类自定义类上:信号类,以及由向导汇编的智能系统所用的资金管理类。 顺带一提,正式开拆前得先把上一篇没收尾的 ADX 指标补完,否则波动率框架会缺一块参照。
◍ 用 ADX 主缓冲下穿抓趋势反转
ADX 主缓冲区量的是趋势强度,线往上冲代表趋势在加强;DI+ 和 DI- 两条辅助线则分别量化涨、跌的力度。所谓形态-6 的逆转,看的不是 DI 交叉,而是主缓冲在趋势尾巴上掉头。 具体信号:一段已经跑了一阵的强空头后,主缓冲在约 2–3 根 K 线里从 50 上方跌到 40 下方,价格倾向转多;反过来强多头衰减、主缓冲同样落至 40 下,则倾向转空。外汇和贵金属杠杆高,这种反转只是概率倾斜,不是确定性拐点。 想单独验这个形态,给输入参数 'Patterns Used' 填整数 64 即可隔离测试。下面这段就是信号类里的判定逻辑,逐行拆一下: Base(X()+3) >= 50 取 3 根 K 线前的主缓冲值,要求至少在 50 以上,确认原趋势曾够强;Base(X()) <= 40 看当前主缓冲已跌穿 40,强度明显流失。 T == POSITION_TYPE_BUY 且 Close(StartIndex()) > Close(StartIndex() + m_ma_period),说明判定为买且现价高于 MA 周期前收盘,多头反转条件成立返回 true。 T == POSITION_TYPE_SELL 且 Close(StartIndex()) < Close(StartIndex() + m_ma_period),对称地给空头反转用,现价低于前期收盘才认。 不满足前面任意分支直接 return(false),本根 K 线不触发形态-6。 开 MT5 把这段代码塞进 CSignalADX 类,调 64 跑一段历史,能直接看到主缓冲下穿 40 那几根后来的走势分布。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Check for Pattern class="num">6. | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool CSignalADX::IsPattern_6(class="type">ENUM_POSITION_TYPE T) { if(Base(X()+class="num">3) >= class="num">50 && Base(X()) <= class="num">40) { if(T == POSITION_TYPE_BUY && Close(StartIndex()) > Close(StartIndex() + m_ma_period)) { class="kw">return(true); } else if(T == POSITION_TYPE_SELL && Close(StartIndex()) < Close(StartIndex() + m_ma_period)) { class="kw">return(true); } } class="kw">return(class="kw">false); }
「用布林轨替代手工支撑阻力来抓 ADX 突破」
ADX 形态序列里的第 8 个(也是倒数第二个)组合,是把 ADX 主缓冲区的峰值和价位对支撑/阻力的突破叠在一起看。程序里硬解支撑阻力线比手工画麻烦得多,所以这里直接借布林带上下轨来当边界:上轨视为阻力、下轨视为支撑,刺穿即算突破。 具体信号逻辑很直白——ADX 主缓冲区在两根 K 线内从 25 下方爬到 25 上方,说明趋势动能刚过阈值;此时若收盘价≥布林上轨,倾向看多,若≤布林下轨,倾向看空。外汇与贵金属杠杆高,这种突破被假刺穿扫掉的概率不低,实盘前先在 MT5 用策略测试器跑一遍。 测试时把智能系统的「Patterns Used」输入参数设为 128,等于只启用这一种形态,方便孤立观察它的表现。下面这段就是该形态的判断函数,逐行拆完你能直接抄进自己的信号类里。 函数先比对 Base(X()+2)<25 且 Base(X())>25,确认 ADX 刚上穿 25;随后按持仓方向分流:买权看 Close 是否≥Upper,卖权看 Close 是否≤Lower,满足才返回 true,否则 false。注意 StartIndex() 取的是当前计算起点那根 K 线的收盘与带宽。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Check for Pattern class="num">7. | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool CSignalADX::IsPattern_7(class="type">ENUM_POSITION_TYPE T) { if(Base(X()+class="num">2) < class="num">25 && Base(X()) > class="num">25) { if(T == POSITION_TYPE_BUY && Close(StartIndex()) >= Upper(StartIndex())) { class="kw">return(true); } else if(T == POSITION_TYPE_SELL && Close(StartIndex()) <= Lower(StartIndex())) { class="kw">return(true); } } class="kw">return(class="kw">false); }
用 RSI 穿 50 给 ADX 趋势做确认
ADX 量的是趋势强度,RSI 常被拿来看超买超卖,但把两者拼到一块儿审趋势时,重点不在 RSI 撞 70/30,而是它穿过 50 中轴。方向上,ADX 主缓冲从 25 下方爬到 25 上方,代表趋势动能进场;RSI 同步从 50 下破到 50 上,才是多头倾向的触发,反之为空头倾向。 具体落地:看涨要求前一根 ADX 低于 25、当前高于 25,且当前 RSI 大于 50、前一根小于 50;看跌则 RSI 当前小于 50、前一根大于 50。这里 25 和 50 都是硬阈值,外汇与贵金属波动大,假突破概率不低,实盘需叠加过滤。 MQL5 里把形态编号设成 256 跑回测,能直接调出这套逻辑的结果。下面这段代码就是形态 8 的判断函数,逐行看:先比 ADX 的前值与当前值确认越过 25;再分买卖类型查 RSI 的穿越方向;都满足才返 true,否则 false。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Check for Pattern class="num">8. | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool CSignalADX::IsPattern_8(class="type">ENUM_POSITION_TYPE T) { if(Base(X()+class="num">1) < class="num">25 && Base(X()) > class="num">25) { if(T == POSITION_TYPE_BUY && RSI(StartIndex()) > class="num">50 && RSI(StartIndex() + class="num">1) < class="num">50) { class="kw">return(true); } else if(T == POSITION_TYPE_SELL && RSI(StartIndex()) < class="num">50 && RSI(StartIndex() + class="num">1) > class="num">50) { class="kw">return(true); } } class="kw">return(class="kw">false); }
◍ 九种 ADX 形态叠加的回测陷阱
用向导把智能系统拼出来之后,前面提到的两篇指南都给了照文末代码操作的办法。这套做法能套用到我们目前梳理过的全部 ADX 形态上,区别只在于各形态在逻辑里的权重分配不同。 但得泼盆冷水:把多种形态直接堆进优化器,常常出现彼此抵消的情况。优化跑完容易拿到“曲线拟合”的解,样本外基本复现不出样本内的表现,外汇和贵金属这种高波动品种上更明显。 基于这个判断,我们把研究过的九种 ADX 形态做了几组组合测试。结果指向一个事实——形态越多不代表边界越清晰,反而更可能把噪声当信号。真要落地,建议先在 MT5 里单独验证单一形态再谈加权。