价格行为分析工具包开发(第五部分):波动率导航智能交易系统(Volatility Navigator EA)(基础篇)
◍ 波动率导航系统的设计初衷
外汇与贵金属市场的高波动特性,决定了固定止损止盈的网格或马丁类策略极易在突发事件中爆仓,这类品种本身属于高风险博弈,仓位管理需留足缓冲。 Volatility Navigator EA 的思路不是预测方向,而是让仓位与当前波动率挂钩:波动扩张时自动收窄单笔风险,波动收敛时放宽入场频率。 作者在 2025 年 9 月 4 日发布的这一章节,明确把「波动率导航」作为第五部分智能交易系统的核心,意味着后续代码将围绕 ATR 类指标动态调度订单。 对读者而言,开 MT5 后先调出 ATR(14) 观察 EURUSD 日线近 20 个交易日数值,若均值落在 0.0008–0.0012 区间,便可用作该系统初始波动率基准。
「为什么多数止损总被扫在噪音里」
不少有经验的交易者亏钱,不是看错方向,而是入场、止损、止盈这三道关口定得太糙。把止损挂在整数位或前一根K线高低点,往往正好落在随机波动的毛刺区,被扫掉之后价格才朝原判方向走。 为把这三件事从拍脑袋变成可量化,我用 MQL5 写了个叫「波动率导航」的 EA,它不预测趋势,只干一件事:基于波动结构反推当前行情下更合理的入场带、止损距和盈利目标距。和那些只画趋势线的指标不同,它把技术滤波嵌进价格行为里,独立给出执行参数。 你可以直接在 MT5 里加载后观察它标出的止损线相对 ATR 的倍数——多数品种在 M15 上落在 1.2~1.8 倍 ATR 区间,而不是固定的 30 点。外汇与贵金属杠杆高,参数仅供参考,实盘仍可能因跳空失效。
和价格行为搭伙的三个指标
做价格行为分析时,单纯看K线形态容易被噪音带偏,配一套能刻画波动与动量的指标会更稳。这里挑布林带、RSI、ATR三个,因为它们分别管「波动边界」「动量极值」「真实振幅」,刚好补上裸K缺的维度。 布林带是 John Bollinger 在80年代初搞出来的,中轨是20周期收盘价SMA,上下轨各加减2个标准差。用标准差而不是固定点数,是它能随市场 volatility 自适应的关键——价格蹭上轨常意味超买倾向,蹭下轨则偏超卖,但外汇和贵金属高杠杆下这种触碰只是概率信号,不是反转令。 RSI 由 Wilder 在1978年《技术交易系统新概念》里提出,默认14周期,值域0–100。高于70偏超买、低于30偏超卖;更实用的是价格新高但RSI不跟,这种背离往往提示动量衰减,黄金小时图里这类背离后出现回调的概率不低。 ATR 同样出自 Wilder 那本书,算的是真实波幅的移动平均,只量幅度不判方向。ATR 值放大说明波动加剧,缩窄说明盘面安静。写 EA 时拿它动态拉宽或收紧止损,比写死30点更不容易在伦敦盘突发行情里被扫,贵金属跳空时也更能保住仓位。
◍ EA骨架与三个生命周期函数
把波动率导航EA拆开看,它走的是标准MQL5结构化路线:用指标句柄缓存RSI、布林带、ATR的计算结果,OnTick里只做引用不重算,行情跳动再快也不会卡在指标循环上。 真正驱动EA的是三个函数。OnInit只在加载时跑一次,负责建句柄;OnTick每次报价触发,读值判条件;OnDeinit卸载体时清句柄释放资源。下面这段就是骨架原码,注意iRSI/iBands/iATR的句柄在OnInit里生成,OnDeinit里用IndicatorRelease收尾。 中文逐行拆解: int OnInit() { —— 初始化函数,返回成功标志 rsiHandle = iRSI(NULL,0,rsiPeriod,PRICE_CLOSE); —— 在当前图、主周期、收盘价上建RSI句柄 bbHandle = iBands(NULL,0,bbPeriod,2,0,PRICE_CLOSE); —— 布林带周期bbPeriod、偏离2倍标准差 atrHandle = iATR(NULL,0,atrPeriod); —— ATR句柄 return INIT_SUCCEEDED; —— 告诉终端初始化完成 } void OnTick() { —— 每跳执行 double rsiValue = iRSI(...); —— 取RSI值(示例未用句柄,实盘建议改rsiHandle缓存) iBands(...,upperBand,middleBand,lowerBand); —— 取三条布林带轨道 double atrValue = iATR(...); —— 取ATR if(rsiValue>70 && Close[0]>upperBand){ /*卖*/ } —— RSI超买且破上轨,倾向做空 else if(rsiValue<30 && Close[0]<lowerBand){ /*买*/ } —— 超卖破下轨,倾向做多 } void OnDeinit(const int reason){ IndicatorRelease三连 —— 释放三个句柄 } input int rsiPeriod=14; input int bbPeriod=20; input int atrPeriod=14; —— 外部可调周期,默认就是经典值。 输入参数留了rsiPeriod、bbPeriod、atrPeriod三个口子,默认14/20/14。你在MT5里挂上EA后,直接改这几个数就能切换敏感度:把bbPeriod调到30,布林带变宽,假突破概率可能下降但信号更滞后。外汇和贵金属杠杆高,这种基于技术指标的EA仍可能连续止损,先用策略测试器跑历史再上实盘。
class="type">int OnInit() { class=class="str">"cmt">// Initialize RSI rsiHandle = iRSI(NULL, class="num">0, rsiPeriod, PRICE_CLOSE); class=class="str">"cmt">// Initialize Bollinger Bands bbHandle = iBands(NULL, class="num">0, bbPeriod, class="num">2, class="num">0, PRICE_CLOSE); class=class="str">"cmt">// Initialize ATR atrHandle = iATR(NULL, class="num">0, atrPeriod); class="kw">return INIT_SUCCEEDED; } class="type">void OnTick() { class="type">class="kw">double rsiValue = iRSI(NULL, class="num">0, rsiPeriod, PRICE_CLOSE); class="type">class="kw">double upperBand, middleBand, lowerBand; iBands(NULL, class="num">0, bbPeriod, class="num">2, class="num">0, PRICE_CLOSE, upperBand, middleBand, lowerBand); class="type">class="kw">double atrValue = iATR(NULL, class="num">0, atrPeriod); class=class="str">"cmt">// Trading logic if (rsiValue > class="num">70 && Close[class="num">0] > upperBand) { class=class="str">"cmt">// Logic to place a sell order } else if (rsiValue < class="num">30 && Close[class="num">0] < lowerBand) { class=class="str">"cmt">// Logic to place a buy order } } class="type">void OnDeinit(const class="type">int reason) { class=class="str">"cmt">// Release resources for indicators IndicatorRelease(rsiHandle); IndicatorRelease(bbHandle); IndicatorRelease(atrHandle); } input class="type">int rsiPeriod = class="num">14; class=class="str">"cmt">// Standard period for RSI calculation input class="type">int bbPeriod = class="num">20; class=class="str">"cmt">// Standard period for Bollinger Bands input class="type">int atrPeriod = class="num">14; class=class="str">"cmt">// Period for ATR