如何利用 MQL5 处理指示线(基础篇)
📘

如何利用 MQL5 处理指示线(基础篇)

第 1/2 篇

用 MQL5 抓取指标缓冲区的真实值

在 MT5 里,多数技术指标并不把画出来的线直接暴露给 EA,而是塞进「指标缓冲区」(indicator buffer)。想用代码读取某根 K 线上的指示线数值,第一步是拿到指标句柄,再用 CopyBuffer 把对应缓冲区的历史拉进数组。 以 iMA 为例,默认移动平均有且仅有一个主缓冲区,索引为 0。下面这段能在当前图表上取最近一根已闭合 K 线的 MA(20) 值,你在 MT5 策略测试器里跑一遍就能看到 Print 出来的数字。 外汇与贵金属杠杆高、滑点突兀,缓冲区数值只是行情快照,实盘信号可能随重报价偏移,务必用历史数据先验证。

MQL5 / C++
class="type">int ma_handle = iMA(_Symbol, PERIOD_CURRENT, class="num">20, class="num">0, MODE_SMA, PRICE_CLOSE);
class="type">class="kw">double ma_buf[class="num">1];
if(CopyBuffer(ma_handle, class="num">0, class="num">0, class="num">1, ma_buf) > class="num">0)
   Print("MA20 of last closed bar: ", ma_buf[class="num">0]);

◍ 用 MQL5 接管你手绘的那些关键线

手工在图上拉趋势线、支撑线、阻力线,几乎是每个外汇或贵金属交易者的日常。但线一多就乱,复盘时也很难追溯哪条线还有效。MQL5 能把这些动作程序化:识别价位、自动画线、随行情重绘,把重复劳动交给终端跑。 本文不堆概念,只挑三种最常用的指示线下手——趋势线、支撑线、阻力线。每一种都会先讲人工怎么画、挂在什么场景,再用 MQL5 在 MetaTrader 5 里写成可执行的片段。外汇与贵金属波动大、滑点频繁,自动化画线只是辅助,实盘仍需自担高风险。 具体做法依赖 MT5 内置的 MetaEditor:新建脚本或指标,调用相应的对象函数把线挂到图表上。若你还没碰过 MQL5 编辑环境,得先补一下在 MetaEditor 里建文件、编译、拖入图表这套基础流程,否则代码贴上来也跑不动。 最有效的学习方式不是抄完就走。把文里的例子改一两个参数,比如趋势线偏移点数从 10 改成 20,挂到 EURUSD 的 M15 上观察重绘频率,比纯读文档更能摸透对象生命周期。这一过程可能让你发现原逻辑在某类震荡行情里画线过密,进而逼着你写过滤条件。

「用 EA 在 MT5 里自动画趋势线」

趋势线本质是一条连接三个及以上同方向转折点的参考线:价格在同一条上升线上至少三次从下方反弹,可判定为上升趋势线;反之三次从上方反弹则倾向下降趋势。它不预测拐点,只把已发生的结构可视化,方便你挂单或观察测试。 手动连点效率低,且换周期就要重画。MT5 里可以用一小段 MQL5 让 EA 每次跳价时重算可见区间的最低点,删掉旧线、在价格下方重绘一条蓝色上升射线;下降线同理,只是改成取最高点画在上方。 下面这段是上升线系统的核心片段,编译后拖到图表、勾选“允许算法交易”即可看到右上角加载提示,价格下方出现蓝色实线。下降线只需把 CopyLow / ArrayMinimum 换成 CopyHigh / ArrayMaximum,锚点价格用 high 即可。 别把自动线当支撑铁律 外汇和贵金属波动受数据跳空影响,自动趋势线只基于可见 K 线最低/最高,遇非农类跳空可能瞬间重绘。真要据此挂单,建议叠加一根手绘周线趋势线做过滤,概率上更稳。

MQL5 / C++
class="type">int candles=ChartGetInteger(class="num">0,CHART_FIRST_VISIBLE_BAR,class="num">0);
class="type">class="kw">double pLow[];
ArraySetAsSeries(pLow,true);
CopyLow(_Symbol,_Period,class="num">0,candles,pLow);
class="type">int candleLow = ArrayMinimum(pLow,class="num">0,candles);
class="type">MqlRates pArray[];
ArraySetAsSeries(pArray,true);
class="type">int Data = CopyRates(_Symbol,_Period,class="num">0,candles,pArray);
ObjectDelete(_Symbol,"UpwardTrendline");
ObjectCreate(_Symbol,"UpwardTrendline",OBJ_TREND,class="num">0,pArray[candleLow].time,pArray[candleLow].low,pArray[class="num">0].time,pArray[class="num">0].low);
ObjectSetInteger(class="num">0,"UpwardTrendline",OBJPROP_COLOR,Blue);
ObjectSetInteger(class="num">0,"UpwardTrendline",OBJPROP_STYLE,STYLE_SOLID);
ObjectSetInteger(class="num">0,"UpwardTrendline",OBJPROP_WIDTH,class="num">3);

用最低点和最高点自动拉趋势线

把上升与下降趋势线写成两个独立的 OnTick 脚本,思路都是先抓可视区间内极值,再连到当前 K 线。下面这段上升系统每跳价就重算一次,把从最低价 K 线到最新 K 线低点连成一条向右延伸的蓝线。 代码里先取 CHART_FIRST_VISIBLE_BAR 得到可视柱数,CopyLow 把低点塞进反序数组,ArrayMinimum 返回最低点下标。注意 candleLow 是相对数组下标,不是绝对序号,所以取 pArray[candleLow].time 要用同反序的 CopyRates 结果,否则时间对不上。 下降系统对称处理:CopyHigh 配 ArrayMaximum 找最高点,连线端点是 pArray[candleHigh].high 到 pArray[0].high。两个脚本对象名分别为 UpwardTrendline 与 DnwardTrendline(后者原文拼写为 Dnward,若直接复制需留意命名一致性)。 在 MT5 里新建两个脚本分别挂 EURUSD 或 XAUUSD 的 M5 图,能直观看到价格贴着自动趋势线运行;外汇与贵金属杠杆高,极值连线只描述已发生结构,后续突破概率需结合成交量与更高周期判断。

MQL5 / C++
ObjectSetInteger(class="num">0,"UpwardTrendline",OBJPROP_RAY_RIGHT,true);
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                 UpwardTrendline System.mq5 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnTick()
  {
   class="type">int candles=ChartGetInteger(class="num">0,CHART_FIRST_VISIBLE_BAR,class="num">0);
   class="type">class="kw">double pLow[];
   ArraySetAsSeries(pLow,true);
   CopyLow(_Symbol,_Period,class="num">0,candles,pLow);
   class="type">int candleLow = ArrayMinimum(pLow,class="num">0,candles);
   class="type">MqlRates pArray[];
   ArraySetAsSeries(pArray,true);
   class="type">int Data = CopyRates(_Symbol,_Period,class="num">0,candles,pArray);
   ObjectDelete(_Symbol,"UpwardTrendline");
   ObjectCreate(_Symbol,"UpwardTrendline",OBJ_TREND,class="num">0,pArray[candleLow].time,pArray[candleLow].low,pArray[class="num">0].time,pArray[class="num">0].low);
   ObjectSetInteger(class="num">0,"UpwardTrendline",OBJPROP_COLOR,Blue);
   ObjectSetInteger(class="num">0,"UpwardTrendline",OBJPROP_STYLE,STYLE_SOLID);
   ObjectSetInteger(class="num">0,"UpwardTrendline",OBJPROP_WIDTH,class="num">3);
   ObjectSetInteger(class="num">0,"UpwardTrendline",OBJPROP_RAY_RIGHT,true);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                       DownwardTrendline System.mq5 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnTick()
  {
   class="type">int candles=ChartGetInteger(class="num">0,CHART_FIRST_VISIBLE_BAR,class="num">0);
   class="type">class="kw">double pHigh[];
   ArraySetAsSeries(pHigh,true);
   CopyHigh(_Symbol,_Period,class="num">0,candles,pHigh);
   class="type">int candleHigh = ArrayMaximum(pHigh,class="num">0,candles);
   class="type">MqlRates pArray[];
   ArraySetAsSeries(pArray,true);
   class="type">int Data = CopyRates(_Symbol,_Period,class="num">0,candles,pArray);
   ObjectDelete(_Symbol,"DnwardTrendline");
   ObjectCreate(_Symbol,"DnwardTrendline",OBJ_TREND,class="num">0,pArray[candleHigh].time,pArray[candleHigh].high,pArray[class="num">0].time,pArray[class="num">0].high);
   ObjectSetInteger(class="num">0,"DnwardTrendline",OBJPROP_COLOR,Blue);
   ObjectSetInteger(class="num">0,"DnwardTrendline",OBJPROP_STYLE,STYLE_SOLID);
   ObjectSetInteger(class="num">0,"DnwardTrendline",OBJPROP_WIDTH,class="num">3);
  }

常见问题

通过 iCustom 获取指标句柄,再用 CopyBuffer 把指定缓冲区的历史数据读到数组里,注意缓冲区位序和指标源码一致即可拿到真实值。
可以,用 ObjectCreate 按你手绘的坐标重建对象,再用 EA 定时刷新或判断触碰,就能把人工线变成可程序判断的线。
小布可基于品种页的 AIGC 分析自动识别关键位并给出线位参考,你只需确认,不必每次手动拉线。
用 iLow 和 iHigh 取对应 K 线极值,拿两个极值点坐标调 ObjectCreate 画趋势线,记得设好时间轴参数避免偏移。
多半用了价格坐标没锚定具体时间,画线时必须传入具体的 bar 时间而非当前光标,才能跨周期稳定显示。