从基础到中级:指标(四)(基础篇)
📘

从基础到中级:指标(四)(基础篇)

第 1/2 篇

◍ MT5 示例文章的冷启动数据

MetaTrader 5 客户端里有一类面向指标教学的示例文章,定位在从基础到中级的过渡带,用具体代码带读者理解指标运行机制。 这类内容在平台内的初始曝光并不高:一篇发布于 4 月 7 日 10:12 的示例帖,截至统计时仅 295 次浏览、0 条评论,说明纯代码型教学在没有社区推送的情况下,自然流量相当有限。 对外汇与贵金属交易者而言,这类材料的高风险属性不变——指标只是概率工具,任何从历史 K 线跑出的逻辑都不能直接等同于未来胜率,开 MT5 自己复跑才是验证的第一步。

「静态实现的边界与动态需求」

上一节里我们用编译指令把指标类型写死在代码里,这在 MQL5 里叫静态实现:编译后用户没法切换渲染方式。对多数常规盯盘场景,写死一种画法已经够用,但外汇和贵金属的高波动环境里,分析视角经常要换,硬改代码重编译太低效。 实际交易中,沟通观点或跑自动形态识别时,往往需要在同一个窗口里切到不同指标。本文要做的,是抽出一个简单概念,让你不重编译就能派生出多种指标——MT5 打开任意品种右键添加指标时,这种灵活度直接决定复盘速度。 外汇与贵金属属高风险品种,指标只是概率辅助,切来切去不代表信号更准。先从最基础、也最容易忽略的一个思路说起:用统一接口封装指标创建,后面几种变体都从这一根上长出来。

内含线指标的缓冲区顺序坑

内含线是指完全落在前一根 K 线高低点范围内的烛形,但不少交易者会把「未突破某根更老 K 线边界」的连续多根 K 线都算作内含线。新手常想给这类形态做颜色标记,却在 MT5 里卡在指标声明这一步。 最典型的坑是指缓冲区顺序写错。下面这段代码声明了 5 个缓冲区、用 DRAW_COLOR_CANDLES 画彩色 K 线,但把 High 放在索引 0、Open 放在 1、Close 在 2、Low 在 3。编译能通过,可图表上 K 线颜色变了,实体格式也跟着畸变——因为 MT5 按特定顺序消费缓冲区,顺序不对就画出非预期形态。 [CODE] //+------------------------------------------------------------------+

//代码 01:错误缓冲区顺序示例

//+------------------------------------------------------------------+ #property copyright "Daniel Jose" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrRed, clrRoyalBlue, clrGreen #property indicator_buffers 5 #property indicator_plots 1 double gl_Buff_High[], gl_Buff_Open[], gl_Buff_Close[], gl_Buff_Low[], gl_Buff_Color[]; int OnInit() { SetIndexBuffer(0, gl_Buff_High, INDICATOR_DATA); 修正只需把索引顺次改成 Open=0、High=1、Low=2、Close=3,颜色缓冲放最后。改动后 MT5 才能正确识别每根蜡烛的绘制方式,颜色模式不再破坏 K 线结构。 循环从第 29 行起扫历史柱,到第 38 行定期查内含线条件。注意:只能在 K 线收盘后判定内含线,盘中若出现又消失的结构,会在下一tick因条件失效而不再标示。若想支持「多根 K 线同处一个老 K 线边界内」的宽定义,可在 OnCalculate 里加静态变量记录边界,第 42–44 行查高低突破、第 45 行在无内含线时清边界重搜。外汇与贵金属波动快,这种形态识别失效概率不低,实盘前务必在 MT5 历史数据里验证。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 代码 class="num">01:错误缓冲区顺序示例
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property copyright "Daniel Jose"
class="macro">#class="kw">property indicator_type1 DRAW_COLOR_CANDLES
class="macro">#class="kw">property indicator_color1 clrRed, clrRoyalBlue, clrGreen
class="macro">#class="kw">property indicator_buffers class="num">5
class="macro">#class="kw">property indicator_plots class="num">1
class="type">class="kw">double gl_Buff_High[], gl_Buff_Open[], gl_Buff_Close[], gl_Buff_Low[], gl_Buff_Color[];
class="type">int OnInit()
{
   SetIndexBuffer(class="num">0, gl_Buff_High, INDICATOR_DATA);

◍ 缓冲区绑定与K线重绘的颜色判定

指标初始化收尾要把四个价格序列和一个颜色索引绑到图表缓冲区。SetIndexBuffer 的第二个参数接全局数组,第三个参数用 INDICATOR_DATA 标价格、INDICATOR_COLOR_INDEX 标调色板序号,漏掉颜色索引那根线就不会跟着涨跌变色。 OnCalculate 里只跑增量:prev_calculated 大于 0 时从上一根减 1 的位置接着写,避免每 tick 重算全历史。High/Low/Open/Close 直接搬进自定义缓冲,方便后续做形态比对而不是读原数组。 颜色赋值先看当根开收:Open 大于 Close 给 0 号色(通常指阴线),否则给 2 号色。若前一根存在且 High[c-1] > High[c] 同时 Low[c-1] < Low[c],说明价格被前一根完全包住,就把该根改成 1 号色标成包含关系——这是价格行为里看多空博弈压缩的直接可视信号,外汇与贵金属波动下这种包含棒出现频率可能偏高,杠杆品种风险大,仅作结构参考。 返回 rates_total 告诉终端算到哪根,终端依此决定下次从哪起步。复制下面片段到 MT5 指标工程,改调色板 0/1/2 对应的具体 RGB 就能立刻看出包含棒分布。

MQL5 / C++
SetIndexBuffer(class="num">1, gl_Buff_Open, INDICATOR_DATA);
SetIndexBuffer(class="num">2, gl_Buff_Close, INDICATOR_DATA);
SetIndexBuffer(class="num">3, gl_Buff_Low, INDICATOR_DATA);
SetIndexBuffer(class="num">4, gl_Buff_Color, INDICATOR_COLOR_INDEX);
class="kw">return INIT_SUCCEEDED;

class="type">int OnCalculate(const class="type">int rates_total, const class="type">int prev_calculated, const class="type">class="kw">datetime &Time[], const class="type">class="kw">double &Open[], const class="type">class="kw">double &High[], const class="type">class="kw">double &Low[], const class="type">class="kw">double &Close[], const class="type">long &TickVolume[], const class="type">long &Volume[], const class="type">int &Spread[])
{
   for (class="type">int c = (prev_calculated > class="num">0 ? prev_calculated - class="num">1 : class="num">0); c < rates_total; c++)
   {
      gl_Buff_High[c] = High[c];
      gl_Buff_Open[c] = Open[c];
      gl_Buff_Close[c] = Close[c];
      gl_Buff_Low[c] = Low[c];
      gl_Buff_Color[c] = (Open[c] > Close[c] ? class="num">0 : class="num">2);
      if ((c - class="num">1) > class="num">0)
         gl_Buff_Color[c] = ((High[c - class="num">1] > High[c]) && (Low[c - class="num">1] < Low[c]) ? class="num">1 : gl_Buff_Color[c]);
   }
   class="kw">return rates_total;
}

常见问题

多数新文章前 3~7 天靠站内推荐和搜索长尾词缓慢起量,先补 2~3 条具体场景问答更容易被搜到。
静态实现不响应 K 线重绘,跳空时旧 K 线重组会导致缓冲区颜色错位,需改为动态重算或加重绘过滤。
小布可自动汇总各品种页的浏览与诊断数据,打开对应页就能看哪些内容被反复调出,省去手动统计。
顺序错会导致线画到错误缓冲位,常见表现是主线和信号线颠倒或只显示一根,需按文档严格对齐索引。
多因重绘事件未触发颜色重算或绑定的是只读缓冲,检查 OnCalculate 里是否对重绘分支重设了颜色数组。