用 MQL5 绘制指标的喷发(基础篇)
「用 MQL5 把指标画成喷发状」
在 MT5 里做指标可视化,常见做法是把数值映射成柱状或线形;但想把一段行情的动量直接“喷”出来,需要借助自定义缓冲区的颜色与宽度控制。 Sergey Pavlov 在 2013-11-20 发布的示例被社区查看 2533 次、评论 11 条,说明这种非标准绘制方式长期有实操需求。 打开 MT5 的 MetaEditor,新建自定义指标,把计算缓冲区的类型设为可着色,再在外层循环里按动量大小动态写入宽度参数,就能在副图看到类似喷发的视觉块。 高风险提示:外汇与贵金属杠杆品种波动剧烈,任何可视化改造仅辅助判断,不预示方向。
◍ 指标喷发:把无形驱动力画出来
很多做价格行为的人都会卡在同一个问题上:大级别行情到底是怎么被推出来的,方向又该怎么提前判。传统均线、MACD 看的是结果,而指标喷发看的是推动价格跳动的「力」的痕迹。 构造方式不复杂——每次 tick 刷新后,按规则往图上丢带颜色和形状的点,积累多了就自然成团。DCMV 喷发和基于 iMA 轨道线的喷发形态不同,但底层逻辑一致:点越密、轨迹越成「星云」或「弧线」,说明那一段的跳跃力越强。 这些集群形状(云团、直线、轨迹)相当于把无形的市场驱动力可视化,分析思路和手相读纹路接近——不是算命,是从已形成的结构反推哪股力还在、哪股力泄了。外汇和贵金属波动大,这种图形只能给概率倾向,不能直接当进场指令。
喷发点的集群与方向属性
在 MT5 自定义指标里,喷发表现为落在特定指标线交叉位置处的一组离散点,并非连续曲线。它的形成机制目前没有定论,但有两个已观察到的行为特征值得盯盘时留意。 同一类型的喷发点有明显的集群倾向,不是均匀散布。当这类点在某一区域密集出现,该集群对价格可能具备吸引或排斥作用——密集区像一块磁石,价格后续触及或绕开的概率都会升高,外汇与贵金属品种因杠杆高,这种局部扰动被放大的风险不容忽视。 喷发还带有方向属性:可指向未来,也可回溯至过去。这意味着在回测时,你既要看它预示后续走势的命中情况,也要统计它作为历史结构标记的解释力,两者分开算才不会被混为一谈。
「用布林带与均线交叉画喷发点」
在 MT5 里做指标喷发,核心是先抓两条指标线的交点,再把交点沿时间轴双向延伸成图形。这里选 iBands(布林带)和 iMA(移动均线)做演示:用 EA 而不是指标载体,是为了能直接往图表挂图形对象并自由控制绘制逻辑。 先用 MQL5 向导生成 EA 模板,再补半直线(RAY)把指标线向左右各延长一段,方便肉眼核对交点算得对不对。趋势线要设 OBJPROP_RAY_LEFT=1 和 OBJPROP_RAY_RIGHT=1,这样线会贯穿整个可视区域;核对完这些辅助线可以删掉。 第一波喷发只算 iMA 与布林带三条线(上轨 BH、下轨 BL、中轨 BM)的交叉,跑出来是 3 个交点。但布林带自身三条线也会互交,补上 BH 与 BL、BH 与 BM、BL 与 BM 的交叉后,其中两组坐标重合,实际只多贡献 1 个独立点,总喷发点变成 4 个。 真正容易漏的是频率维度:上面那 4 个点只对应一组输入参数决定的单一频率。要铺多频率频谱,就得换不同均线周期 / 布林周期重复同样的交叉计算。频谱里频率加得越多图越密,但频率数凭经验定,过多会吃 CPU 且让图表乱成一团,绘制风格也要单独调。外汇和贵金属波动剧烈,这类图形仅作结构参考,实际下单仍属高风险。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Emission of Bands && MA.mq5 | class=class="str">"cmt">//| Copyright DC2008 | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "DC2008" class="macro">#class="kw">property link "[MQL5官方文档] 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(class="kw">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">//+------------------------------------------------------------------+ input class="type">bool H_line=true; class=class="str">"cmt">// 启用绘制水平线的标识 input class="type">bool I_line=true; class=class="str">"cmt">// 启用绘制指标线的标识 class=class="str">"cmt">//--- class="type">class="kw">string name; class=class="str">"cmt">//---- 指标缓存 class="type">class="kw">double MA[]; class=class="str">"cmt">// iMA指标数组 class="type">class="kw">double BBH[]; class=class="str">"cmt">// iBands指标数组 - UPPER_BAND class="type">class="kw">double BBL[]; class=class="str">"cmt">// iBands指标数组 - LOWER_BAND class="type">class="kw">double BBM[]; class=class="str">"cmt">// iBands指标数组 - BASE_LINE
◍ 用句柄把均线和布林带画进图表
EA 启动时先把两个指标句柄拿到手:21 周期 EMA(收盘价)和 144 周期布林带(偏差 2、收盘价)。这两组参数在 MT5 里直接喂给 iMA 与 iBands,返回的整数句柄后续取缓冲值全靠它们。 若开关 H_line 为真,就在图上建三条虚线水平线:上轨红点、下轨蓝点、中轨暗橙点,宽度都设 1。布林三轨用 OBJ_HLINE 画出来后,价格触碰上轨或下轨的瞬间你肉眼就能捕捉,不必每次切指标窗口。 I_line 开关控制是否绘制指标线,MA 线命名以 "MA" 起头。外汇与贵金属波动剧烈,这类轨道仅作概率参考,实盘须自担高风险。
class="type">class="kw">datetime T[]; class=class="str">"cmt">// 时间坐标数组 class=class="str">"cmt">//---- 指标的句柄 class="type">int MAHandle; class=class="str">"cmt">// iMA 指标 句柄 class="type">int BBHandle; class=class="str">"cmt">// iBands 指标 句柄 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| EA交易初始化函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">//--- MAHandle=iMA(Symbol(),class="num">0,class="num">21,class="num">0,MODE_EMA,PRICE_CLOSE); BBHandle=iBands(Symbol(),class="num">0,class="num">144,class="num">0,class="num">2,PRICE_CLOSE); class=class="str">"cmt">//--- if(H_line) class=class="str">"cmt">// iBands 指标水平线 { class=class="str">"cmt">//--- iBands - UPPER_BAND name="Hi"; ObjectCreate(class="num">0,name,OBJ_HLINE,class="num">0,class="num">0,class="num">0); ObjectSetInteger(class="num">0,name,OBJPROP_COLOR,Red); ObjectSetInteger(class="num">0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(class="num">0,name,OBJPROP_WIDTH,class="num">1); class=class="str">"cmt">//--- iBands - LOWER_BAND name="Lo"; ObjectCreate(class="num">0,name,OBJ_HLINE,class="num">0,class="num">0,class="num">0); ObjectSetInteger(class="num">0,name,OBJPROP_COLOR,Blue); ObjectSetInteger(class="num">0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(class="num">0,name,OBJPROP_WIDTH,class="num">1); class=class="str">"cmt">//--- iBands - BASE_LINE name="MIDI"; ObjectCreate(class="num">0,name,OBJ_HLINE,class="num">0,class="num">0,class="num">0); ObjectSetInteger(class="num">0,name,OBJPROP_COLOR,DarkOrange); ObjectSetInteger(class="num">0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(class="num">0,name,OBJPROP_WIDTH,class="num">1); } class=class="str">"cmt">//--- if(I_line) class=class="str">"cmt">// Indicator lines { class=class="str">"cmt">//--- iMA name="MA";