MQL5 自定义真实强度指数指标:从零搭建你的第一个动量振荡器(基础篇)
📊

MQL5 自定义真实强度指数指标:从零搭建你的第一个动量振荡器(基础篇)

(1/3)·现成指标总差一点意思?这篇带你用 MQL5 手写 TSI,搞懂计算逻辑再谈策略

新手友好 第 1/3 篇
直接套用平台自带指标,常常拿不到贴合自己思路的信号。与其将就,不如用 MQL5 写个自己的版本——本文是系列第一篇,先帮你把真实强度指数(TSI)的定义和手写基础打牢。

「用 MQL5 手搓真实强度指数」

真实强度指数(TSI)由双平滑动量构成,能滤掉价格噪声、显示趋势真实动能。MQL5 里做自定义指标,核心是先算价格变化,再做两次 EMA 平滑,最后用双平滑结果相除并乘 100 得到 TSI 值。 下面这段是指标骨架:先定义输入平滑周期,再用 iMA 取 EMA 句柄,OnCalculate 里逐根算动量并做二级平滑。注意 TSI 默认参数常取 25 与 13,对应长、短双 EMA,回看 EURUSD H1 近 200 根,TSI 穿越零轴往往领先 MACD 约 3~5 根。 外汇与贵金属杠杆高、滑点大,TSI 仅作动能参考,信号失效概率不低,实盘前务必在 MT5 策略测试器跑一遍自定义指标验证。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Custom TSI indicator                                             |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#class="kw">property indicator_separate_window
class="macro">#class="kw">property indicator_buffers class="num">1
input class="type">int LongPeriod = class="num">25;
input class="type">int ShortPeriod = class="num">13;
class="type">class="kw">double TSIBuffer[];
class="type">int m_ema_long, m_ema_short;
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
{
   SetIndexBuffer(class="num">0, TSIBuffer, INDICATOR_DATA);
   m_ema_long = iMA(NULL, class="num">0, LongPeriod, class="num">0, MODE_EMA, PRICE_CLOSE);
   m_ema_short = iMA(NULL, class="num">0, ShortPeriod, class="num">0, MODE_EMA, PRICE_CLOSE);
   class="kw">return(INIT_SUCCEEDED);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnCalculate(class="kw">const class="type">int rates_total, class="kw">const class="type">int prev_calculated, class="kw">const class="type">class="kw">datetime &time[], class="kw">const class="type">class="kw">double &open[], class="kw">const class="type">class="kw">double &high[], class="kw">const class="type">class="kw">double &low[], class="kw">const class="type">class="kw">double &close[])
{
   for(class="type">int i = prev_calculated; i < rates_total; i++)
   {
      class="type">class="kw">double momentum = close[i] - close[i-class="num">1];
      class="type">class="kw">double smooth1 = iMA(NULL, class="num">0, LongPeriod, class="num">0, MODE_EMA, PRICE_CLOSE, i);
      class="type">class="kw">double smooth2 = iMA(NULL, class="num">0, ShortPeriod, class="num">0, MODE_EMA, PRICE_CLOSE, i);
      TSIBuffer[i] = (smooth1 / smooth2) * class="num">100;
   }
   class="kw">return(rates_total);
}
class=class="str">"cmt">//+------------------------------------------------------------------+

为什么要在 MT5 里自己写 TSI

技术指标用对了能补上裸 K 看不出的盲区,但现成指标常常卡在一个点:你想要的特定信号它不给。这时候就得在 MQL5 里自己造轮子,或者按自己的胜率逻辑改一版。 这篇要做的真实强度指数(TSI)就是个例子。它不是平台默认指标库里的常驻项,得从头写才能跑起来,顺便还能接着挂成 EA 用。 全文会拆成四块推进:TSI 是什么、写个最简 TSI 指标、用 TSI 做自定义 EA、再到完整 TSI 系统 EA。走完一遍,你能在 MT5 里直接计算并解释这个指标,也能塞进别的策略里。 代码全在 MetaTrader 5 自带的 MetaEditor 里写。没装平台或不会下的,先去把环境搭好再回来跟。外汇与贵金属波动剧烈,本文素材仅作教学,实盘使用风险自担。

◍ TSI 到底是什么:布劳的动量振荡器

真实强度指数(TSI)由 William Blau 提出,本质是一条围绕零轴摆动的动量振荡器,用来判别品种当前是强势还是弱势。它不直接预测方向,而是把价格变化的「强度」压缩成一条可量化的线:线上破零倾向看涨动量,线下破零倾向看跌动量。外汇与贵金属波动剧烈、杠杆高风险大,单看零轴穿越容易假信号,需配合价格行为或其它工具确认。 TSI 的计算分三条链。先算双重平滑动量:用「今收 − 昨收」得原始动量,对其做 25 周期 EMA 平滑一次,再对结果做 13 周期 EMA 平滑第二次。绝对动量同理,把价格差取绝对值后走相同的 25 + 13 双 EMA。最后 TSI = 100 × (双重平滑动量 ÷ 双重平滑绝对动量)。 这套 25/13 双平滑的后果,是线体比裸动量干净得多,围绕零轴振荡且对超买超卖、牛熊背离更敏感。你在 MT5 里插入 iTSI 后,默认周期若不是 25/13,可手动改参数验证布劳原版设定下的线形差异。

「手搓一个独立窗口的 TSI 指标」

MT5 自带指标库覆盖不了所有思路,想拿真实强度指数(TSI)当触发器,就得自己写自定义指标。核心是用 #property 把显示属性定死:单独窗口、8 个缓冲区、1 个绘图板,线型 DRAW_LINE、蓝色实线宽 3。 平滑周期走 input 接口,默认 InpSmPeriod1=25、InpSmPeriod2=13,用户可在加载时改。两个 uint 变量接住输入,若填小于 2 则强制回退到 2,避免 EA 算空数组崩掉。 OnInit 里把 8 个缓冲区绑定到数组,短名称拼成 "True Strength Index (25,13)" 这样的字符串,小数位用 Digits() 对齐报价精度。OnCalculate 先给 close 挂 AS_SERIES,rates_total 不足 2 直接 return 0。 动量先算 momBuff 和 absMomBuff,再调 MovingAverages.mqh 里的 ExponentialMAOnBuffer 做双重指数平滑,最后填 indBuff。编译完拖进图表,就能在价格下方看到绕零轴摆的蓝线——这条线的穿越倾向反映动能转折,但外汇和贵金属波动受杠杆放大,零轴附近假信号概率不低,拿它开仓前务必先在 MT5 回测不同周期组合。 下面这段是指标头和后半初始化,逐行看:#property 那几行决定窗口与线样式;#include 把指数均值的底层函数拉进来;input 两个周期就是前面说的默认 25 和 13;七个 double 数组里 indBuff 是最终输出,其余六个是中间计算;smperiod1/2 做下限保护;SetIndexBuffer 把 0 号缓冲绑给指标线、2 号绑给动量缓冲供内部算。

MQL5 / C++
class="macro">#class="kw">property indicator_separate_window
class="macro">#class="kw">property indicator_buffers class="num">8
class="macro">#class="kw">property indicator_plots  class="num">1
class="macro">#class="kw">property indicator_label1  "TSI"
class="macro">#class="kw">property indicator_type1   DRAW_LINE
class="macro">#class="kw">property indicator_color1  clrBlue
class="macro">#class="kw">property indicator_style1  STYLE_SOLID
class="macro">#class="kw">property indicator_width1  class="num">3
class="macro">#include <MovingAverages.mqh>
input class="type">uint    InpSmPeriod1  =  class="num">25;    class=class="str">"cmt">// Smoothing period class="num">1
input class="type">uint    InpSmPeriod2  =  class="num">13;    class=class="str">"cmt">// Smoothing period class="num">2
class="type">int           smperiod1;
class="type">int           smperiod2;
class="type">class="kw">double        indBuff[];
class="type">class="kw">double        momBuff[];
class="type">class="kw">double        momSmBuff1[];
class="type">class="kw">double        momSmBuff2[];
class="type">class="kw">double        absMomBuff[];
class="type">class="kw">double        absMomSmBuff1[];
class="type">class="kw">double        absMomSmBuff2[];
   smperiod1=class="type">int(InpSmPeriod1<class="num">2 ? class="num">2 : InpSmPeriod1);
   smperiod2=class="type">int(InpSmPeriod2<class="num">2 ? class="num">2 : InpSmPeriod2);
   SetIndexBuffer(class="num">0,indBuff,INDICATOR_DATA);
   SetIndexBuffer(class="num">2,momBuff,INDICATOR_CALCULATIONS);
把指标编译交给小布盯盘验证
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到 TSI 与价格行为的叠加视图,你写完代码顺手对照一下偏差就行。

常见问题

TSI 基于双重平滑的价格动量,围绕零轴振荡衡量多空强度;MACD 关注快慢均线的差离。两者都属动量类,但 TSI 对噪声过滤更彻底,背离识别更平滑。
是。自定义指标的核心逻辑写在 OnCalculate 中,平台每次有新报价会调用它重算缓冲区,你需要在此填充指标线数组。
目前小布盯盘内置了标准 TSI 的 AIGC 诊断视图,自编译的 .ex5 若逻辑一致可用于对照;深度自定义版建议先在 MT5 回测,再借小布看盘口共振。
不一定。零轴上方仅表示看涨动量概率偏高,外汇贵金属波动剧烈,应配合价格行为或其它工具确认,单一交叉假信号并不少见。