DIY 技术指标(基础篇)
📘

DIY 技术指标(基础篇)

第 1/2 篇

「自己动手写 MT5 指标并不玄」

在 MT5 里做自定义指标,本质是把价格序列喂进你自己的计算逻辑,再由平台按 tick 或柱闭合刷新。官方社区 2022-12-15 那篇示例文拿到 2616 次查看、3 条评论,说明手动造轮子的需求一直都在。 很多交易者以为必须懂 C++ 才能碰 MQL5,其实它的数组和循环写法更靠近交易直觉。先想清楚你要算什么——均线偏离、波动率阈值还是自定义摆动带,再决定用 OnCalculate 还是独立函数。 开 MT5 按 F4 进编辑器,新建 Indicator 模板,把下面这段最小骨架跑通,你就已经越过「只会加载 ex5」的门槛。外汇与贵金属波动剧烈,自写指标仅作辅助判断,信号出现不代表概率占优。

◍ 指标本质是一条价格函数

任何技术指标背后都是一套处理市场信息的算法,绝大多数直接把价格作为初始输入。用数学视角看,指标就是一个把价格映射成某种输出的函数,输入是报价序列,输出是你图表上看到的曲线或数值。 在 MT5 里做自定义指标,最先要厘清的就是这个函数关系。本文系列聚焦其中一类——线性函数,也就是输出和输入价格之间满足叠加性和齐次性的变换,典型如加权移动平均、线性回归斜率。 外汇与贵金属市场高杠杆、高波动,线性指标只是降噪工具,对拐点判断只具备概率倾向,不能当作方向保证。

线性指标其实就是比率游戏

任何挂在主图上的线性指标,底层逻辑都能拆成四步:取若干根价格读数、各自乘一个比率、加总、画出来。决定它长什么样的,不是价格本身,而是那组比率。 把比率记作整数再转成实数,约束条件只有一条——所有比率之和必须等于 1。写成方程就是各期价格乘对应权重后求和,权重总和为 1。 用字符串传参就能快速试不同序列。等权 1,1,1,1,1 就是普通 MA5;五条周期 1~5 的均线再平均,得到比率 137,77,47,27,12;平移一步取均线平均则形成 1,2,3,4,5,4,3,2,1 的三角形窗。 斐波那契(34,21,13,8,5,3,2,1,1)、对称斐波那契(1,1,2,3,5,3,2,1,1)、帕斯卡三角(1,8,28,56,70,56,28,8,1)都能直接套。甚至把 MetaTrader 5 字母序号 13,5,20,1,20,18,1,4,5,18,5 当权重也能跑出一条线。 权重中心决定指标性格。设 period 为周期、center 为加权重心序号:center < period/3 偏趋势;period/3 ~ 2*period/3 偏平滑;大于 2*period/3 则逆势。外汇与贵金属波动剧烈,这类自定义指标仅作概率参考,实盘前务必在 MT5 用历史数据验证。 下面这段 OnInit 里的处理,就是把逗号分隔的字符串拆成权重数组、归一化、顺手算出 center 位置,方便你直接抄去改序列。

MQL5 / C++
input class="type">class="kw">string InpCoefficient="class="num">1,class="num">1,class="num">1,class="num">1,class="num">1";class=class="str">"cmt">//variable for indicator ratios
  class="type">class="kw">string s[];                                                                   class=class="str">"cmt">//array for substrings with ratios
  size=StringSplit(InpCoefficient,StringGetCharacter(",",class="num">0),s);class=class="str">"cmt">//get substrings and their number
  
  ArrayResize(coeff,size);  class=class="str">"cmt">//prepare the array for indicator ratios
  class="type">class="kw">double denom=class="num">0,center=class="num">0;  class=class="str">"cmt">//variables for normalizing values and calculating the center of the indicator
  for(class="type">int i=class="num">0; i<size; i++) class=class="str">"cmt">// set the ratios
    {
      coeff[i]=StringToDouble(s[i]);
      denom=denom+coeff[i];
    }
  if(denom==class="num">0) class=class="str">"cmt">//if the normalization term is class="num">0, then something is wrong
    {
      Alert("Wrong odds!");
      class="kw">return(INIT_FAILED);
    }
  for(class="type">int i=class="num">0; i<size; i++) class=class="str">"cmt">//normalize the ratios and calculate the indicator center
    {
      coeff[i]=coeff[i]/denom;
      center=center+coeff[i]*(i+class="num">1);
    }
  Print((class="type">int)MathRound(center));class=class="str">"cmt">//display the count closest to the center of the indicator

「负权重会扯断均线的稳定性」

规则 #1 保证指标能跑通,但权重里一旦出现负数,就要额外过一道关:任意比率的绝对值之和,必须仍小于所有比率的合计。写成式子就是w_i的累加要小于 Σw_i,这条限制直接决定指标会不会发疯。

拿线性加权移动平均的权重序列做对照最直观:5,4,3,2,1 是蓝线,5,4,3,2,-1 是绿线,5,4,3,-2,-1 是黄线,5,4,-3,-2,-1 是红线。后三条都含负权重,越往后负得越多。 图上能明显看到,红线相比前几个选项走势非常随意,原本平滑的跟踪特性被破坏,指标失去稳定性。外汇与贵金属市场本身高杠杆、高波动,加载这类失稳指标容易给出误导性信号。 所以只要你的自定义指标权重里混了负数,先手算一遍绝对值和与合计的关系,不满足规则 1a 就别往 MT5 里挂。

常见问题

可以,从改现有指标的常数项开始,比如把均线周期从14改成20,先跑通再谈重写。
线性指标本质是比率游戏,分母接近零时比值会爆裂,需加平滑或限定分母下限。
小布可以读取你的指标说明,对照历史行情指出权重设置是否会导致信号失真,省去手动回测。
负权重会扯断均线的稳定性,相当于让旧价格反向拉扯当前值,参数稍偏就易发散。
多半是函数对价格噪声过于敏感,可引入ATR过滤或提高采样窗口,减少毛刺触发。