下载MetaTrader 5

William Blau 的 MQL5 指标与交易系统。第一部分:指标

6 一月 2014, 11:57
Andrey F. Zelinsky
0
2 119

有好工具,才能充分发掘技术交易的潜力。
而经验、判断力以及好的交易计算机程序所提供的数学层级,则是杰出交易者不可或缺的工具。
William Blau

简介

本文的第一部分 - <William Blau 的 MQL5 指标与交易系统。第一部分:指标>,是对技术指标与摆动指标的描述,详见 William Blau 下述书中内容 《动量、方向和背离》

本文中所述之技术指标与摆动指标,均作为 MQL5 语言中的源代码呈现,且已附到归档文件 "Blau_Indicators_MQL5_en.zip" 中。

William Blau 提出的关键分析理念

William Blau 的技术分析由四个阶段构成:

  1. 利用价格系列数据(q 柱)计算指标并绘于图表。指标并不反映价格变动的总体趋势,亦不可确定趋势反转点。
  2. 指标会利用 EMA 方法平滑多次:第一次(周期为 r)、第二次(周期为 s),以及第三次(周期为 u);一个平滑的指标绘制完毕。平滑指标相当精确,会重现出最小延迟的价格波动。它允许确定价格变化的趋势和反转点,并会消除价格噪声。
  3. 将平滑指标标准化,再绘制标准化的平滑指标。标准化允许指标值被解释为市场的超买或超卖状态。
  4. 利用 EMA 方法将标准化的平滑指标平滑一次(周期 ul);构造一个摆动指标 - 添加指标柱与信号线、市场的超买与超卖水平。摆动指标允许我们区分市场的超买/超卖状态、反转点以及趋势结束。

指标

本文讲解下述几组指标:

  1. 基于动量的指标
  2. 基于随机动量的指标:
  3. 基于随机动量的指标:
  4. 基于市场趋势平均偏差的指标:
  5. 基于平滑/异同移动平均线的指标:
  6. 基于烛形动量的指标:
  7. 基于复合高低动量的指标:

针对每组指标如下显示:

  • 平滑指数指标;
  • 标准化平滑指标指数;
  • 基于标准化平滑指标指数的摆动指标。

真实强弱指数部分包含:

  • 对于 William Blau 就价格图表技术分析方面方法的详尽分析;
  • 对于基于动量的指标组中每个指标算法与代码的详尽描述。

William Blau 将指数平滑移动平均线 (EMA) 作为平滑方法使用。而“指数移动平均线”则通过向移动平均线的前一值添加当前价的特定百分比计算得出。

使用 EMA 时,最新价格的权重较大。

EMA 的计算函数:

EMA(k,n) = EMA(k-1,n) + 2/(n+1) * (price(k) - EMA(k-1,n))
         = price(k) * 2/(n+1) + EMA(k-1,n) * (1 - 2/(n+1))

其中:

  • EMA(k,n) - 周期 k 时周期 n 的指数平滑移动平均线;
  • price(k) - 周期 k 时的价格。

四种移动平均线类型及其在技术分析中使用方法的描述(亦见 iMA),请见《MetaTrader 5 帮助》(“分析/技术指标/趋势指标/移动平均线)。

函数库

移动平均线计算函数的库位于 "MovingAverages.mqh"。我们关心的是 ExponentialMAOnBuffer(),它会用输入数组 price[] 的 EMA 值填写输出数组 buffer[]。但是,"MovingAverages.mqh" 中所示的 ExponentialMAOnBuffer() 的实施有一个缺点,那就是在周期 n = 1 时不运行。

参见源代码:

if(period<=1 || rates_total-begin<period) return(0);

但是,William Blau 在书中是用平滑周期 n = 1 表示没有平滑。

由此,ExponentialMAOnBuffer() 函数的代码出现了一些变化:

if(period<1 || rates_total-begin<period) return(0);

而我们则得到了 ExponentialMAOnBufferWB()。此函数的代码位于 "WilliamBlau.mqh" 文件中。

"WilliamBlau.mqh" 文件中亦包含下述函数:

  • PriceName() 函数会作为一个字符串返回价格类型:
string PriceName(
                 const int applied_price // 价格类型
                )
  • CalculatePriceBuffer() 函数会计算此价格类型的价格数组:
int CalculatePriceBuffer(
                         const int applied_price,   // 价格类型
                         const int rates_total,     // 柱形数量
                         const int prev_calculated, // 最近一次调用计算的柱形
                         const double &Open[],      // Open[]
                         const double &High[],      // High[]
                         const double &Low[],       // Low[]
                         const double &Close[],     // Close[]
                         double &Price[]           // 计算价格数组
                        )

价格图表应用的价格类型及时间表

William Blau 考虑到了日时间表的收盘价。本文中制定的指标允许您选择价格类型(参见价格常量),并根据指标的时间表选择价格图表的时间表(参见图表时间表)。

 

1. 真实强弱指数

要探讨的指标(参见附件):

  1. Blau_Mtm.mq5 - 率指标(q 周期动量;平滑 q 周期动量);
  2. Blau_TSI.mq5 - 真实强弱指数(标准化平滑 q 周期动量);
  3. Blau_Ergodic.mq5 - 遍历摆动指标(基于“真实强弱指数”)。

1.1. 动量

内置技术指标动量的相关描述及其技术分析用途,均载于“分析/技术指标/摆动指标/动量” 《MetaTrader 5 帮助》部分(亦见 iMomentum)。与标准的动量 (iMomentum) 相比,William Blau 动量会将动量作为绝对价格变化进行计算。

《MQL5:创建自己的指标》一文中,有 William Blau 关于“真实强弱指标” (TSI) MQL5 实施的一个示例。


1.1.1. 利用动量指标进行的技术分析

技术分析的对象,即金融工具的价格图表。图表中的每个元素都是一个价格。价格柱具备下述特性:开盘时间开盘价最高价最低价收盘价交易量其它。价格柱会形成并体现某特定离散时间周期(图表时间表)内的价格行为。

价格图表技术分析的任务,就是确定价格变化的当前趋势,揭示价格峰值底值,并预测未来时间周期内的价格变化走向。这里复杂的地方在于价格 - 在其基本走向的限制内移动的同时,生成了多个方向的波动,从而形成了所谓的价格噪声。

William Blau 的主张内容。第一项差异:动量。William Blau 将动量作为每 [日] 价格变化 [收盘] 的相对值进行计算;而且创建了动量指标。从数学的角度来看,该动量函数是价格的一阶导数。

图 1.1.动量指标(q 周期动量)

图 1.1.动量指标(q 周期动量)

动量会显示一天周期内的价格波动,呈现整个周期内价格变化的速度(量级)和方向,但它不会体现价格变动的整体趋势,也不会确定趋势反转点。

第二种差异在于平滑。动量移动平均线(日价格波动的累积和)几乎是曲线价格主变量与局部变量两者的精确重现。子窗口 I、 II 中的图 1.2 (a) 所示即为平滑动量(分别是周期为 20 和 300 的移动平均线)。

移动平均线的周期越高,平滑动量就越能精确地接近(重现)价格曲线的波动。从数学的角度来看,动量的平滑函数是动量的整函数,或是价格的恢复函数。

图 1.2 (a).动量指标(平滑 q 周期动量)

图 1.2 (a).动量指标(平滑 q 周期动量)


图 1.2 (b).动量指标(平滑 q 周期动量)

图 1.2 (b).动量指标(平滑 q 周期动量)


在图 1.2 (a) 的主窗口中,展示的是平滑 EMA (周期为 5, 20, 100)指标。移动平均线周期内一个轻微的增加导致了一次延迟,而移动平均线实际上已经不能再重现价格曲线的波动了。

第三个差异是再平滑。 动量的第一次平滑定义了价格变动的总体趋势和反转点,但未能消除噪声。要消除价格噪声,就需要针对移动平均线的一个 周期执行再平滑。

图 1.2 (b) 子窗口 I 中展示的是平滑动量指标(移动平均线周期为 20),子窗口 II 和 III 中展示的是双平滑与三平滑动量(移动平均线周期为 5, 3)。重复平滑会消除价格噪声,但也会向曲线添加少许平移(延迟)。

第四项差异:走向变化信号方面的差异。带有一个小平均线周期的动量平滑,可能会导致平滑动量于价格曲线趋势的背离。

图 1.2 (a) 的子窗口 I 以及图 1.2 (b) 的子窗口 I、II、III 中可见差异(价格变动的方向,与平滑动量中的变化方向有所背离)。这种差异往往意味着走向变化。从数学的角度来看,该背离是平滑周期的一个函数。

我们只要考量超买或超卖区域的背离,就能改善作为趋势改变信号的上述差异解释的可靠性(参见 п. 1.2.1)。


1.1.2. 动量的定义

动量是指一种相对的价格变动。

动量的标志会指明价格变动的方向:正动量 - 整个周期价格上涨;负动量 - 整个周期价格下滑。动量的量级 - 价格变动的相对速度(价格的一阶导数)。

图 1.3.动量的定义

图 1.3.动量的定义

动量公式

mtm(price) = price - price[1]

其中:

  • price - 当前周期的价格 [收盘];
  • price [1] - 前一周期的价格 [收盘]。

William Blau 将动量作为当前周期价格 [收盘] 与前一周期价格 [收盘] 的差异进行检查。William Blau 在其周期动量的计算过程中,采用的是两个周期的价格(当前周期与前一周期)。

我们引入公式以计算某一周期指标的动量,q - 指计算中涉及的时间周期的数量(按 William Blau 的设置,q = 2)。

q 周期动量公式

mtm(price,q) = price - price[q-1]

其中:

  • q - 动量计算中使用的柱数;
  • price - 当前周期的价格 [收盘];
  • price [q-1] - 此前 (q-1) 周期的价格 [收盘] 。

在生成的公式中,我们的两个周期动量对应的是 William Blau 的单周期相对动量。

平滑 q 周期动量公式

Mtm(price,q,r,s,u) = EMA(EMA(EMA( mtm(price,q) ,r),s),u)

其中:

  • price - [收盘] 价 - 价格图表的价格基础;
  • q - 动量计算中使用的柱数;
  • mtm(price,q)=price-price[q-1] - q-周期动量;
  • EMA (mtm (price, q), r) - 第一次平滑 - 应用于 q 周期动量的 EMA(r);
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(u)。

1.1.3. Mtm(price,q,r,s,u) - 率指标(动量)。规范
  • 文件名称Blau_Mtm.mq5
  • 名称:William Blau 的动量(q 周期动量;平滑 q 周期动量)。
  • 输入参数
    • q - 动量计算的周期(默认 q = 2);
    • r -应用于动量的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则不采用 EMA 平滑。比如说,如果您设置 Mtm (price, 2,20,5,1),我们会得到一个双平滑动量;但如果您设置 Mtm (price, 2,1,1,1),则会得到一个非平滑动量;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

1.2. 真实强弱指数

1.2.1. 利用“真实强弱指数”进行技术分析

:参见章节 1.1.1 的开头。

第五:标准化。通过平滑动量值的标准化实现单一标度(映射至区间 [-1, +1]),允许我们确定市场的超买或超卖状态。利用标准化平滑动量的值重复乘以系数 100,就能将数值系列转换为百分比范围(映射至区间 [-100, 100])。

图 1.4.标准化平滑动量

图 1.4.标准化平滑动量


如果标准化的平滑动量处于超买或超卖状态,则作为走向变动信号的背离可被视为可靠。


1.2.2. “真实强弱指数”的定义

真实强弱指数 (TSI) - 是标准化动量的一个指标(标准化 q 周期动量)。将平滑动量的值加到单标度(映射至区间 [-1, +1]),再配以平滑动量每个值的标准化(平滑 q 周期价格波动的累积和) - 利用平滑动量值,取绝对值。

乘以系数 100,显示区间变为 [-100, +100] (百分比)。标准化允许将 TSI 值解释为超买(积极)或超卖(消极)市场的量。

“真实强弱指数”公式

                     100 * EMA(EMA(EMA( mtm(price,q) ,r),s),u)         100 * Mtm(price,q,r,s,u)
TSI(price,q,r,s,u) = –––––––––––––––––––––––––------–––––––––– = ––––––––––––––––------–––––––––––––––
                       EMA(EMA(EMA( |mtm(price,q)| ,r),s),u)     EMA(EMA(EMA( |mtm(price,q)| ,r),s),u)
if EMA(EMA(EMA(|mtm(price,q)|,r),s),u)=0, then TSI(price,q,r,s,u)=0

其中:

  • price - [收盘] 价 - 价格图表的价格基础;
  • q - 动量的周期;
  • mtm(price,q)=price-price[q-1] - q-周期动量;
  • | Mtm (price, q) | - q 周期动量的绝对值;
  • Mtm (price, q, r, s, u) - 三次平滑 q 周期动量;
  • EMA (..., r) - 第一次平滑 - r 周期 EMA,应用于:
    1) q 周期动量;
    2) q 周期动量绝对值;
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(u)。

1.2.3. TSI(price,q,r,s,u) - 真实强弱指数。规范
  • 文件名称Blau_TSI.mq5
  • 名称:William Blau 的“真实强弱指数”(标准化平滑 q 周期相对动量)。
  • 输入参数
    • q - 动量计算的周期(默认 q = 2);
    • r -应用于动量的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
    • (可选)两级(默认为 -25 和 +25) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

1.3. 遍历摆动指标

1.3.1. 利用遍历摆动指标进行技术分析

:参见下述章节开头 1.1.1, 1.2.1.

第六:超买与超卖市场区域。单位区间 [-1, +1] 或百分比区间 [-100.100],标准化平滑动量值在上述区间内的变化,允许您定义超买或超卖市场区域。

而表现超买或超卖市场状态特征的技术分析指数类,被称为摆动指标。 每个摆动指标的水平,都在接收到一个超买或超卖市场信号时被确定。摆动指标于趋势市场无效,因为该市场可能处于任意长度周期的某种超买/超卖状况下。

第七:信号线。要获取某个趋势结束或价格变动反转点的相关信号,就要用到信号线。如果主线由下到上穿越了信号线,则会收到买入信号。如果主线由上到下穿越了信号线,则会收到买入信号。如果有条主线 - 则为遍历(真实强弱指数),那么遍历的再平滑则会形成一条信号线。该再平滑流程等同于遍历平滑的最后一次过程。

第八:价格变动的走向。如果主线(遍历)从信号线上方通过,则价格变动的走向为上行(上涨趋势)。如果主线(遍历)从信号线下方通过,则价格变动的走向为下行(下滑趋势)。

图 1.5.遍历摆动指标

图 1.5.遍历摆动指标


1.3.2. 遍历摆动指标的定义

Ergodic(price,q,r,s,u) = TSI(price,q,r,s,u)
SignalLine(price,q,r,s,u,ul) = EMA( Ergodic(price,q,r,s,u) ,ul)

其中:

  • Ergodic() - 遍历 - 真实强弱指数 TSI(price,q,r,s,u);
  • SignalLine() - 单线 - 应用于遍历的 EMA(ul);
  • ul - EMA 周期单线 - 根据 William Blau ,ul 必须等于 EMA 遍历最后一个有效周期 (>1)。比如说,如果您要使用一个双平滑 Ergodic (price, q, r, s, u) = Ergodic (price, 2,20,5,1),则根据 William Blau,ul = s = 5。

1.3.3. Ergodic (price, q,r,s,u,ul) - 遍历摆动指标。规范
  • 文件名称Blau_Ergodic.mq5
  • 名称:William Blau 基于真实强弱指数的遍历摆动指标。
  • 输入参数
    • graphic plot #0 - 遍历(真实强弱指数):
      • q - 动量计算的周期(默认 q = 2);
      • r -应用于动量的第一次 EMA 的周期(默认 r = 20);
      • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
      • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • 图形标绘 #1 - 信号线:
      • ul - 周期 EMA 信号线,应用于遍历(默认 ul = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 每个图形绘制渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡);
    • 两级(默认为 -25 和 +25) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则不采用 EMA 平滑;
    • ul>0。如果 ul = 1,则信号线与遍历线相同;
    • 价格数组最小尺寸 = (q-1 + r + s + u + ul-4 +1)。

1.4. 代码(详述)

1.4.1. "Blau_Mtm.mq5" - 指标 Mtm(price,q,r,s,u) - 动量

指标 Mtm (price,q,r,s,u) 的代码:

//+------------------------------------------------------------------
//|                                                     Blau_Mtm.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------
#property copyright "Copyright 2011, MetaQuotes Software Corp." // 版权
#property link      "http://www.mql5.com"                       // url
#property description "q-period Momentum (William Blau)"        // 描述
#include <WilliamBlau.mqh>              // 包含文件 (terminal_data_folder\MQL5\Include)
//--- 指标设置
#property indicator_separate_window     // 指标显示在独立窗口
#property indicator_buffers 5           // 使用的缓存数量
#property indicator_plots   1           // 绘图图形个数
//--- 绘制 #0主图形
#property indicator_label1  "Mtm"       // #0绘图图形的标签
#property indicator_type1   DRAW_LINE   // 画线
#property indicator_color1  Blue        // 颜色
#property indicator_style1  STYLE_SOLID // 线形 - 实线
#property indicator_width1  1           // 线宽
//--- 输入参数
input int    q=2;  //  Momentum 的周期q 
input int    r=20; // r - 1st EMA,应用于Momentum
input int    s=5;  // s - 2nd EMA,应用于 1st EMA
input int    u=3;  // u - 3rd EMA,应用于 2nd EMA
input ENUM_APPLIED_PRICE AppliedPrice=PRICE_CLOSE; // AppliedPrice - 价格类型
//--- 动态数组
double MainBuffer[];     // u-周期 3rd EMA(绘制#0图形)
double PriceBuffer[];    // 价格数组
double MtmBuffer[];      // q-周期动量
double EMA_MtmBuffer[];  // r-周期1st EMA
double DEMA_MtmBuffer[]; // s-周期 2nd EMA
//--- 全局变量
int    begin1, begin2, begin3, begin4; // 数据的起始索引
int    rates_total_min; // 最小柱形数量
//+------------------------------------------------------------------
//| 自定义指标初始化函数                                                         |
//+------------------------------------------------------------------
int OnInit()
  {
//--- 指标缓存
   // plot buffers
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);             //  u-周期的 3rd EMA
   //  缓存,用于计算的中间过程
   SetIndexBuffer(1,PriceBuffer,INDICATOR_CALCULATIONS);    // 价格缓存
   SetIndexBuffer(2,MtmBuffer,INDICATOR_CALCULATIONS);      // q-周期动量
   SetIndexBuffer(3,EMA_MtmBuffer,INDICATOR_CALCULATIONS);  // r-周期 1st EMA
   SetIndexBuffer(4,DEMA_MtmBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA
/*
//--- 图形绘制 #0 (主)
   PlotIndexSetString(0,PLOT_LABEL,"Mtm");             // 标签
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);    // 画线
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,Blue);        // 线的颜色
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID); // 线形
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);           // 线宽
*/
//--- 精度
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//---
   begin1=q-1;        //                             - MtmBuffer[]
   begin2=begin1+r-1; // 或 =(q-1)+(r-1)             - EMA_MtmBuffer[]
   begin3=begin2+s-1; // 或 =(q-1)+(r-1)+(s-1)       - DEMA_MtmBuffer[]
   begin4=begin3+u-1; // 或 =(q-1)+(r-1)+(s-1)+(u-1) - MainBuffer[]
   //
   rates_total_min=begin4+1; // 最小数量
//---绘制#0图形的开始索引
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin4);
//--- 指标简称
   string shortname=PriceName(AppliedPrice)+","+string(q)+","+string(r)+","+string(s)+","+string(u);
   IndicatorSetString(INDICATOR_SHORTNAME,"Blau_Mtm("+shortname+")");
//--- 初始化完成
   return(0);
  
}
//+------------------------------------------------------------------
//| 自定义指标迭代函数                                                 |
//+------------------------------------------------------------------
int OnCalculate(
                const int rates_total,     // 柱形数量
                const int prev_calculated, // 前一次调用时计算的柱形
                const datetime &Time[],    // 时间
                const double &Open[],      // 开盘价
                const double &High[],      // 最高价
                const double &Low[],       // 最低价
                const double &Close[],     // 收盘价
                const long &TickVolume[],  // Tick成交量
                const long &Volume[],      // 真实成交量
                const int &Spread[]        // 点差
               )
  {
   int i,pos;
//--- 检查柱形
   if(rates_total<rates_total_min) return(0);
//---  计算PriceBuffer[]
   CalculatePriceBuffer(
                        AppliedPrice,        // 应用的价格
                        rates_total,         // 所有柱形数量
                        prev_calculated,     // 前一次计算的柱形
                        Open,High,Low,Close, // Open[], High[], Low[], Close[] 数组
                        PriceBuffer          // 价格缓存
                       );
//--- 计算q-周期动量
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin1;              // 从begin1开始计算所有值
      for(i=0;i<pos;i++)       // pos 值
         MtmBuffer[i]=0.0;     // 置零值
     
}
   else pos=prev_calculated-1; // 否则仅重算最近一个值
   // 计算MtmBuffer[]
   for(i=pos;i<rates_total;i++)
      MtmBuffer[i]=PriceBuffer[i]-PriceBuffer[i-(q-1)];
//--- EMA 平滑
   //  r-周期 1st EMA
   ExponentialMAOnBufferWB(
                           rates_total,     // 所有柱形
                           prev_calculated, // 前一次计算的柱形
                           begin1,          // 起始索引
                           r,               // 平滑周期
                           MtmBuffer,       // 输入数组
                           EMA_MtmBuffer    // 输出数组
                          );
   //  s-周期 2nd EMA
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin2,s,EMA_MtmBuffer,DEMA_MtmBuffer);
   // u-周期 3rd EMA(绘制#0图形)
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin3,u,DEMA_MtmBuffer,MainBuffer);
//--- OnCalculate函数结束。返回prev_calculated的值用于下一次调用
   return(rates_total);
  
}
//+------------------------------------------------------------------

我们更仔细地讲讲它们。


1.4.1.1. 指标设置 Mtm (price,q,r,s,u)

参考文献

《MQL5 参考》中有哪些要读的指标设置相关内容:

  1. 自定义指标》部分。
  2. 指标属性与对应函数之间的关系(参见《自定义指标》)。
  3. 程序属性 (# property)(参见《语言基础/预处理程序》)。
  4. 渲染风格(图形绘制属性) (参见《标准常量、枚举及结构/指标常量》部分)。
  5. 自定义指标属性 (参见《标准常量、枚举及结构/指标常量》部分)。
版权。指标描述
#property copyright "Copyright 2011, MetaQuotes Software Corp." // 版权
#property link      "http://www.mql5.com"                       // url
#property description "q-period Momentum (William Blau)"        // 描述

仅通过 #property 预处理程序指令进行的设置。版本(copyrightlink 参数)、版本(version 参数)和 mql5 程序的描述(description 参数),均显示于指标窗口的 "Properties" 中("Properties" 选项卡、"Additional" 选框)。

包含文件
#include <WilliamBlau.mqh>              // 包含文件 (terminal_data_folder\MQL5\Include)

预处理程序会利用 "WilliamBlau.mqh" 文件中的内容,替换 #Include <WilliamBlau.mqh> 行。尖括号表明 "WilliamBlau.mqh" 文件要从终端数据文件处获取。更多详情,请见包含文件

根据 "WilliamBlau.mqh" 文件的目录查看介绍。

指标设置(综述)

自定义指标 - 几种图形绘制。指标的图形绘制,既可以显示于价格图表的主窗口,亦可单独窗口显示。每个图形绘制都有特定的绘图方法、颜色、风格和粗细。

图形标绘渲染所用的数据,来自指标缓冲区(每个图形标绘都对应着一到五个指标缓冲区)。我们利用一个指标数组作为一个指标缓冲区。

要设置指标,则有必要(参见图 1.6):

  1. 指定显示指标的窗口。
  2. 指定图形标绘的数量。
  3. 指定指标缓冲区的数量。
  4. 指标数组的声明。
  5. 设置一个链接:指标数组 ->指标缓冲区 -> 图形标绘。
  6. 描述每个图形标绘的属性。
  7. 指定指标值的显示精度。
  8. 指定每个作图法初始柱的数量(未渲染图形标绘的情况下)。
  9. 设置水平等级,并描述每个水平等级的属性(不存在。)
  10. 设置独立指标窗口的大小限制(不存在。)
  11. 指定指标的短名称。

图 1.6.动量指标 Mtm (price,q,r,s,u)

图 1.6.动量指标 Mtm (price,q,r,s,u)


指标设置的执行:

更多详情,请参见《指标属性与对应函数之间的关系》

设置指标的两种方法的区别在于,如果通过 #property  指令,在指标附至价格图表之前就可以使用;而通过专用函数则要等到指标附至价格图表之后才可以。设置的配置由指标的 "Properties" 窗口执行。

设置:指标显示窗口 (1)
#property indicator_separate_window     // 指标显示在独立窗口

配置为强制填写,而且只能通过 #property 预处理程序指令。指标显示有两个选项:

  1. 在价格图表的主窗口中 - indicator_chart_window
  2. 在独立的窗口中 - indicator_separate_window
设置:缓冲区的数量 (3) 和图形标绘的数量 (2)
#property indicator_buffers 5           // 使用的缓存数量
#property indicator_plots   1           // 绘图图形个数

配置为强制填写,而且只能通过 #property 预处理程序指令。指标缓冲区的数量(indicator_buffers 参数)和图形标绘的数量(indicator_plots 参数)没有限制。

设置:指标数组 (4)
//--- 动态数组
double MainBuffer[];     // u-周期 3rd EMA(绘制#0图形)
double PriceBuffer[];    // 价格数组
double MtmBuffer[];      // q-周期动量
double EMA_MtmBuffer[];  // r-周期1st EMA
double DEMA_MtmBuffer[]; // s-周期 2nd EMA

指标数组会在全局层面作为一维的双精度类型动态数组声明。

设置:设置指标数组、指标缓冲区与图形标绘之间的链接 (5) 。
// 绘制 #0图形
SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);             //  u-周期的 3rd EMA
// 缓存,用于计算的中间过程
SetIndexBuffer(1,PriceBuffer,INDICATOR_CALCULATIONS);    // 价格缓存
SetIndexBuffer(2,MtmBuffer,INDICATOR_CALCULATIONS);      // q-周期动量
SetIndexBuffer(3,EMA_MtmBuffer,INDICATOR_CALCULATIONS);  // r-周期 1st EMA
SetIndexBuffer(4,DEMA_MtmBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA

此代码被写入事件处理程序 Init()OnInit() 函数中。

而指标缓冲区与对应一维数组的链接,则利用 SetIndexBuffer() 函数进行设置:

bool SetIndexBuffer(
   int                 index,    // 指标缓存索引(从0开始)
   double              buffer[], // 动态数组
   ENUM_INDEXBUFFER_TYPE data_type // 数据类型,保存在指标数组中
   );

指标缓冲区是一种一维双精度类型 动态数组,大小由客户端控制,以使其始终与指标计算所依据的柱数相符。指标缓冲区的索引从 0 开始。

指标缓冲区可以存储三种数据类型INDICATOR_DATA, INDICATOR_COLOR_INDEX, INDICATOR_CALCULATIONS。据其显示方法,每个图形标绘都可以对应一到五个指标缓冲区:一到四为指标缓冲区值(数据类型 INDICATOR_DATA),还有一个颜色缓冲区(数据类型 INDICATOR_COLOR_INDEX。)

带有 INDICATOR_CALCULATIONS 类型数据的指标缓冲区,专为中间计算而设计。绑定后,指标数组的索引就和传统数组差不多了(参见下文 1.4.1.2 部分)。

设置:图形标绘的属性 (6)

针对每组图形标绘的配置,指定下述事项:

  1. 标签;
  2. 绘图类型(于 ENUM_DRAW_TYPE 枚举中查看全部 18 种类型);
  3. 线条颜色;
  4. 线条风格(于ENUM_LINE_STYLE 枚举中查看可能风格);
  5. 线宽。

配置方式有两种可能:

1) 通过 #property 预处理程序指令(实施如下):

//--- 图形绘制 #0 (主)
#property indicator_label1  "Mtm"       // #0图形的标签
#property indicator_type1   DRAW_LINE   // 绘图类型: DRAW_LINE - 线条
#property indicator_color1  Blue        // 线的颜色 - Blue
#property indicator_style1  STYLE_SOLID // 线风格:STYLE_SOLID - 实线
#property indicator_width1  1           // 线宽

2) 利用图形标绘属性设置的一组函数 - PlotIndexSetDouble()PlotIndexSetInteger()PlotIndexSetString()

//--- 图形绘制 #0 (主)
   PlotIndexSetString(0,PLOT_LABEL,"Mtm");            // 标签
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);    // 画线
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,Blue);       // 线的颜色
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID); // 线形
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);          // 线宽

此代码被写入事件处理程序 Init()OnInit() 函数中。PlotIndexSet *() 函数的指定:

bool PlotIndexSetDouble|Integer|String(
   int                             plot_index, // 绘图图形的索引
   int                             prop_id,    // 图形属性的标识符
   double|int,char,bool,color|string  prop_value  // 属性的新值
   );

为改进选定类型图标标绘的显示,我们采用 ENUM_PLOT_PROPERTY 枚举中列出的图形标绘属性 ID。

图形标绘的索引从 0 开始。至于通过 #property 指令进行配置有何益处,请参见上文的《指标参数设置》部分。有些图形标绘属性(颜色、风格、线宽)可通过指标的 "Properties" 窗口("Colors" 选项卡)进行更改。

设置:指标值的显示精度 ​​(7)
//--- 精度
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

此代码被写入事件处理程序 Init()OnInit() 函数中。指标设置配置函数 IndicatorSet * () 的指定:

bool IndicatorSetDouble|Integer|String(
   int                    prop_id,   // 指标属性的ID
   double|int,color|string  prop_value // 属性的新值
   );

指标属性的标识符,均于 ENUM_CUSTOMIND_PROPERTY 枚举中列出。

指标值的显示精度只能通过 IndicatorSetInteger() 函数、INDICATOR_DIGITS 指标属性的 ID 以及 ENUM_CUSTOMIND_PROPERTY_INTEGER 枚举指定。

在一个指标缓冲区正要渲染、值已显示的示例中:邻近指标的短名称、在一个弹出消息中、当鼠标指针置于指标线上方时 - 将被取整为位数 - 该指标所附的工具价格小数点后的位数。

设置:未经渲染下的初始柱数 (8)

渲染 William Blau q 周期动量的数据,分四步形成:

第 1 步,根据来自 PriceBuffer[] 价格数组的数据计算出动量(周期 q)。q 周期动量的值被存放于 MtmBuffer[] 数组中。因为价格数组的索引从 0 开始,价格数组中的有效数据亦由索引 0 开始,所以,MtmBuffer[] 数组中的有效数据会从索引 (q-1) 开始。

第 2 步,平滑 MtmBuffer[] 数组中的有效数据(平滑周期 r)。q 周期动量的平滑值被存放于 EMA_MtmBuffer[] 数组中。因为 MtmBuffer[] 数组的索引从 0 开始,MtmBuffer[] 数组中的有效数据从索引 (q-1) 开始,所以 EMA_MtmBuffer[] 数组中的有效数据会从索引 (q-1) + (r-1) 开始。

第 3 步和第 4 步,完成类似上述的考量,确定 DEMA_MtmBuffer[] 数组(平滑周期 s)以及 MainBuffer[] 数组(平滑周期 u)中的有意义数据从哪个柱开始。参见图 1.7。

图 1.7.Mtm (price,q,r,s,u) 指标的有意义数据

图 1.7.Mtm (price,q,r,s,u) 指标的有意义数据


全局层面声明这些变量:

//--- 全局变量
int    begin1, begin2, begin3, begin4; // 数据的起始索引

变量的值 - 是柱的索引,从此开始即为有意义数据,对应变量指标数组。变量值于函数 OnInit() (事件处理程序 Init)中计算,且会被用于 Calculate 事件处理程序的 OnCalculate() 函数中。

//---
   begin1=q-1;        //                             - MtmBuffer[]
   begin2=begin1+r-1; // 或 =(q-1)+(r-1)             - EMA_MtmBuffer[]
   begin3=begin2+s-1; // 或 =(q-1)+(r-1)+(s-1)       - DEMA_MtmBuffer[]
   begin4=begin3+u-1; // 或 =(q-1)+(r-1)+(s-1)+(u-1) - MainBuffer[]
   //
   rates_total_min=begin4+1; // 最小数量
//---绘制#0图形的开始索引
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin4);

利用 PlotIndexSetInteger() 函数、指标属性 PLOT_DRAW_BEGIN 枚举 ENUM_PLOT_PROPERTY_INTEGER 标识符指定图形标绘不显示的初始柱的数量。

配置:指标的短名称 (11)
//--- 指标简称
   string shortname=PriceName(AppliedPrice)+","+string(q)+","+string(r)+","+string(s)+","+string(u);
   IndicatorSetString(INDICATOR_SHORTNAME,"Blau_Mtm("+shortname+")");

此代码被写入事件处理程序 Init()OnInit() 函数中。只能利用 IndicatorSetString() 函数、指标属性 INDICATOR_SHORTNAME  (ENUM_CUSTOMIND_PROPERTY_STRING 枚举)的标识符,来指定指标的短名称。PriceName () 函数会返回价格类型的名称 - 根据 AppliedPrice 输入参数的值。PriceName ()  函数的代码位于 "WilliamBlau.mqh" 文件中(参见《简介》)。

输入参数
//--- 输入参数
input int    q=2;  //  Momentum 的周期q 
input int    r=20; // r - 1st EMA,应用于Momentum
input int    s=5;  // s - 2nd EMA,应用于 1st EMA
input int    u=3;  // u - 3rd EMA,应用于 2nd EMA
input ENUM_APPLIED_PRICE AppliedPrice=PRICE_CLOSE; // AppliedPrice - 价格类型

更多详情,请见输入变量。输入参数可通过指标的 "Properties" 窗口("Inputs" 选项卡)进行更改。


1.4.1.2. 指标 Mtm (price,q,r,s,u) 的计算

计算:算法

计算指标 Mtm(price,q,r,s,u) 的算法:

  1. 检查是否有足够的数据来计算指标。
  2. 依据指定价格类型计算价格数组 - PriceBuffer[] 数组的形成
  3. 索引柱的确定 - 由此开始/继续 q 周期动量的计算。
  4. q 周期动量的计算 - MtmBuffer[] 数组的填充。
  5. EMA 方法的第一次平滑(周期 r) - EMA_MtmBuffer[] 数组的填充。
  6. EMA 方法的第二次平滑(周期 s) - DEMA_MtmBuffer[] 数组的填充。
  7. EMA 方法的第三次平滑(周期 u) - MainBuffer[] 数组的填充。 - #0 图形标绘渲染值的计算。
计算:OnCalculate() 函数

指标值的计算,在 Calculate 事件处理程序的 OnCalculate() 函数中执行。我们采用第二种形式的 OnCalculate() 函数调用

int OnCalculate(
                const int rates_total,     // 柱形数量
                const int prev_calculated, // 前一次调用时计算的柱形
                const datetime &Time[],    // 时间
                const double &Open[],      // 开盘价
                const double &High[],      // 最高价
                const double &Low[],       // 最低价
                const double &Close[],     // 收盘价
                const long &TickVolume[],  // Tick成交量
                const long &Volume[],      // 真实成交量
                const int &Spread[]        // 点差
               )
  {
//---
//--- OnCalculate函数结束。返回prev_calculated的值用于下一次调用
   return(rates_total);
  
}

rates_total 自变量是价格图表会被渲染且可供指标处理的柱数。prev_calculated - 是当前OnCalculate() 函数开始调用时该指标处理的价格图表的柱数。

OnCalculate() - 函数返回该指标在当前调用结束时处理的价格图表的柱数。此函数会返回 rates_total 参数且必须如此构建,即,在第一次调用时,价格图表所有未被处理的柱都要被处理。

也就是说,如果第一次调用 OnCalculate() 函数时,prev_calculated 参数等于 0,那么到第二次调用时,prev_calculated 参数或者等于 rates_total、或者等于 rates_total +1,而且从第二次调用开始,OnCalculate() 函数处理(计入)最后一个柱。想要更加深入的例证解析,请看这里

指标缓冲区与 Time[]、Open[]、High[]、Low[]、Close[]、TickVolume[]、Volume[] 及 Spread[]  数组,都默认从左到右、从数组开头到结尾、从最老到最新数据的索引方向。第一个元素的索引等于 0。指标缓冲区的大小由客户端控制,以使其始终与指标计算所依柱数相符。

计算:检查是否有足够的数据来计算指标 (1)
//--- 检查柱形
   if(rates_total<rates_total_min) return(0);

全局变量 rates_total_min  是指标输入时间序列的最小值,通过 Init 事件处理程序的 OnInit() 函数计算得出。

   rates_total_min=begin4+1; // 指标输入数组的最小尺寸
计算:PriceBuffer[] 价格数组 (2)
//--- 计算价格数组PriceBuffer[]
   CalculatePriceBuffer(
                        AppliedPrice,        // 价格类型
                        rates_total,         // 输入时间序列的尺寸
                        prev_calculated,     // 前次调用时计算的柱形
                        Open,High,Low,Close, // Open[], High[], Low[], Close[]
                        PriceBuffer          // 计算价格数组
                       );

要填充 PriceBuffer[] 价格数组,则使用 CalculatePriceBuffer() 函数。CalculatePriceBuffer()  函数的代码位于 "WilliamBlau.mqh" 文件中(参见《简介》)。价格类型于输入参数 AppliedPrice 中指定。

计算:柱索引的定义 - 由此开始/继续 q 周期动量的计算 (3)

pos  局部变量 是指标会根据当前调用的 OnCalculate() 函数从此开始的柱索引。我们将带有 MtmBuffer[] 数组准备阶段的 pos  变量的计算,与 MtmBuffer[] 数组非有效元素归零阶段的计算合并起来。

计算:q 周期动量 (4)
//--- 计算q-周期动量
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin1;              // 从begin1开始计算所有值
      for(i=0;i<pos;i++)       // pos 值
         MtmBuffer[i]=0.0;     // 置零值
     
}
   else pos=prev_calculated-1; // 否则仅重算最近一个值
   // 计算MtmBuffer[]
   for(i=pos;i<rates_total;i++)
      MtmBuffer[i]=PriceBuffer[i]-PriceBuffer[i-(q-1)];

q 周期动量是作为当前周期 PriceBuffer[i] 与前面各周期 PriceBuffer[i-(q-1)] 的 price(q-1) 之间的差异进行计算的。

计算:EMA 方法平滑 (5-7)

//--- EMA 平滑
   //  r-周期 1st EMA
   ExponentialMAOnBufferWB(
                           rates_total,     // 所有柱形
                           prev_calculated, // 前一次计算的柱形
                           begin1,          // 起始索引
                           r,               // 平滑周期
                           MtmBuffer,       // 输入数组
                           EMA_MtmBuffer    // 输出数组
                          );
   //  s-周期 2nd EMA
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin2,s,EMA_MtmBuffer,DEMA_MtmBuffer);
   // u-周期 3rd EMA(绘制#0图形)
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin3,u,DEMA_MtmBuffer,MainBuffer);

ExponentialMAOnBuffer() 函数在简介中已经讲过。根据 r 周期移动第一次 EMA 的计算示例:ExponentialMAOnBuffer() 函数会利用 MtmBuffer[] 输入数组的 EMA (r) 值来填充 EMA_MtmBuffer[] 输出数组;而且直到索引 (begin1-1) (含)的非有效数据,均用零值填充。

 

1.4.2. "Blau_TSI.mq5" - 指标 TSI(price,q,r,s,u) - 真实强弱指数

TSI (price,q,r,s,u) 指标代码(基于代码 "Blau_Mtm.mq5" 的变更与添加构建):

//+------------------------------------------------------------------
//|                                                     Blau_TSI.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------
#property copyright "Copyright 2011, MetaQuotes Software Corp." // 版权
#property link      "http://www.mql5.com"                       // URL
#property description "True Strength Index (William Blau)"      // 描述
#include <WilliamBlau.mqh>               // 包含文件 (terminal_data_folder\MQL5\Include)
//--- 指标设置
#property indicator_separate_window      // 指标显示在独立窗口
#property indicator_buffers 10           // 使用的缓存数量
#property indicator_plots   1            // 绘图图形个数
//--- 水平级别
#property indicator_level1 -25           // 水平 #0 (垂直坐标)
#property indicator_level2 25            // 水平 #1 (垂直坐标)
#property indicator_levelcolor Silver    // 级别颜色
#property indicator_levelstyle STYLE_DOT // 水平线类型
#property indicator_levelwidth 1         // 宽度
//--- 指标的最小/最大值
#property indicator_minimum -100         // 最小
#property indicator_maximum 100          // 最大
//--- 图形绘制 #0 (主)
#property indicator_label1  "TSI"        // #0图形的标签
#property indicator_type1   DRAW_LINE    // 画线
#property indicator_color1  Blue         // 线的颜色
#property indicator_style1  STYLE_SOLID  // 线形
#property indicator_width1  1            // 线宽
//--- 输入参数
input int    q=2;  //  Momentum 的周期q 
input int    r=20; // r - 1st EMA,应用于Momentum
input int    s=5;  //  s - 2nd EMA,应用于首次平滑
input int    u=3;  // u - 3rd EMA,应用于二次平滑
input ENUM_APPLIED_PRICE AppliedPrice=PRICE_CLOSE; // AppliedPrice - 价格类型
//--- 动态数组
double MainBuffer[];        // TSI(#0绘图图形)
double PriceBuffer[];       // 价格数组
double MtmBuffer[];         // q-周期动量
double EMA_MtmBuffer[];     // r-周期1st EMA
double DEMA_MtmBuffer[];    // s-周期 2nd EMA
double TEMA_MtmBuffer[];    // u-周期 3rd EMA
double AbsMtmBuffer[];      // q-周期蜡烛线动量(绝对值)
double EMA_AbsMtmBuffer[];  // r-周期1st EMA(绝对值)
double DEMA_AbsMtmBuffer[]; // s-周期 2nd EMA(绝对值)
double TEMA_AbsMtmBuffer[]; // u-周期 3rd EMA (绝对值)
//--- 全局变量
int    begin1, begin2, begin3, begin4; // 起始索引
int    rates_total_min; // 最小柱形数量
//+------------------------------------------------------------------
//| 自定义指标初始化函数                                               |
//+------------------------------------------------------------------
int OnInit()
  {
//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);                // TSI
   //  用于计算的中间过程的缓存(不是用来绘图的)
   SetIndexBuffer(1,PriceBuffer,INDICATOR_CALCULATIONS);       // 价格数组
   SetIndexBuffer(2,MtmBuffer,INDICATOR_CALCULATIONS);         //  q-周期动量
   SetIndexBuffer(3,EMA_MtmBuffer,INDICATOR_CALCULATIONS);     // r-周期 1st EMA
   SetIndexBuffer(4,DEMA_MtmBuffer,INDICATOR_CALCULATIONS);    // s-周期 2nd EMA
   SetIndexBuffer(5,TEMA_MtmBuffer,INDICATOR_CALCULATIONS);    // u-周期 3rd EMA
   SetIndexBuffer(6,AbsMtmBuffer,INDICATOR_CALCULATIONS);      // q-周期动量(绝对值)
   SetIndexBuffer(7,EMA_AbsMtmBuffer,INDICATOR_CALCULATIONS);  // r-周期1st EMA(绝对值)
   SetIndexBuffer(8,DEMA_AbsMtmBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA(绝对值)
   SetIndexBuffer(9,TEMA_AbsMtmBuffer,INDICATOR_CALCULATIONS); // u-周期 3rd EMA (绝对值)
/*
//--- 图形绘制 #0 (主)
   PlotIndexSetString(0,PLOT_LABEL,"TSI");             // #0图形的标签
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);    // 画线
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,Blue);        // 线的颜色
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID); // 线形
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);           // 线宽
*/
//--- 精度
   IndicatorSetInteger(INDICATOR_DIGITS,2);
/*
//--- 水平级别
   IndicatorSetInteger(INDICATOR_LEVELS,2);                // 指标水平的数量
   IndicatorSetDouble(INDICATOR_LEVELVALUE,0,-25);         // 水平 #0
   IndicatorSetDouble(INDICATOR_LEVELVALUE,1,25);          // 水平 #1
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,Silver);       // 水平颜色
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,STYLE_DOT);    // 水平线形
   IndicatorSetInteger(INDICATOR_LEVELWIDTH,1);            // 线宽
   IndicatorSetString(INDICATOR_LEVELTEXT,0,"Oversold");   // #0 水平线的描述“超卖”
   IndicatorSetString(INDICATOR_LEVELTEXT,1,"Overbought"); // #1 水平线的描述“超买”
//--- 指标范围
   IndicatorSetDouble(INDICATOR_MINIMUM,-100); // 最小
   IndicatorSetDouble(INDICATOR_MAXIMUM,100);  // 最大
*/
//---
   begin1=q-1;        //                             - MtmBuffer[], AbsMtmBuffer[]
   begin2=begin1+r-1; // 或者 =(q-1)+(r-1)             - EMA_...[]
   begin3=begin2+s-1; // 或者 =(q-1)+(r-1)+(s-1)       - DEMA_...[]
   begin4=begin3+u-1; // 或者 =(q-1)+(r-1)+(s-1)+(u-1) - TEMA_...[], MainBuffer[]
   //
   rates_total_min=begin4+1; // 最小柱形数量
//---绘制#0图形的开始索引
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin4);
//--- 指标简称
   string shortname=PriceName(AppliedPrice)+","+string(q)+","+string(r)+","+string(s)+","+string(u);
   IndicatorSetString(INDICATOR_SHORTNAME,"Blau_TSI("+shortname+")");
//--- 初始化完成
   return(0);
  
}
//+------------------------------------------------------------------
//| 自定义指标迭代函数                                                 |
//+------------------------------------------------------------------
int OnCalculate(
                const int rates_total,     // 柱形数量
                const int prev_calculated, // 前一次调用时计算的柱形
                const datetime &Time[],    // 时间
                const double &Open[],      // 开盘价
                const double &High[],      // 最高价
                const double &Low[],       // 最低价
                const double &Close[],     // 收盘价
                const long &TickVolume[],  // Tick成交量
                const long &Volume[],      // 真实成交量
                const int &Spread[]        // 点差
               )
  {
   int i,pos;
   double value1,value2;
//--- 检查柱形
   if(rates_total<rates_total_min) return(0);
//---  计算PriceBuffer[]
   CalculatePriceBuffer(
                        AppliedPrice,        // 价格类型
                        rates_total,         // 所有柱形数量
                        prev_calculated,     // 前一次计算的柱形
                        Open,High,Low,Close, // Open[], High[], Low[], Close[]
                        PriceBuffer          // 价格缓存
                       );
//--- 计算 HLM 和 |HLM|
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin1;              // 从begin1开始计算所有值
      for(i=0;i<pos;i++)       // pos
        {
         MtmBuffer[i]=0.0;     // 置零值
         AbsMtmBuffer[i]=0.0;  //
        
}
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   // 计算 MtmBuffer[] 和 AbsMtmBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      MtmBuffer[i]=PriceBuffer[i]-PriceBuffer[i-(q-1)];
      AbsMtmBuffer[i]=MathAbs(MtmBuffer[i]);
     
}
//--- EMA 平滑
   //  r-周期 1st EMA
   ExponentialMAOnBufferWB(
                           rates_total,     // 所有柱形
                           prev_calculated, // 前一次计算的柱形
                           begin1,          // 起始索引
                           r,               // 平滑周期
                           MtmBuffer,       // 输入数组
                           EMA_MtmBuffer    // 输出数组
                          );
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin1,r,AbsMtmBuffer,EMA_AbsMtmBuffer);
   //  s-周期 2nd EMA
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin2,s,EMA_MtmBuffer,DEMA_MtmBuffer);
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin2,s,EMA_AbsMtmBuffer,DEMA_AbsMtmBuffer);
   // u-周期 3rd EMA
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin3,u,DEMA_MtmBuffer,TEMA_MtmBuffer);
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin3,u,DEMA_AbsMtmBuffer,TEMA_AbsMtmBuffer);
//--- TSI 计算 (绘制 #0图形)
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin4;              // 从begin4开始计算所有值
      for(i=0;i<pos;i++)       // 
         MainBuffer[i]=0.0;    // 零值
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   // 计算 MainBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      value1=100*TEMA_MtmBuffer[i];
      value2=TEMA_AbsMtmBuffer[i];
      MainBuffer[i]=(value2>0)?value1/value2:0;
     
}
//--- OnCalculate函数结束。返回prev_calculated的值用于下一次调用
   return(rates_total);
  
}
//+------------------------------------------------------------------

下面我们只是仔细研究一下代码 "Blau_Mtm.mq5" 的修改与添加。

1.4.2.1. 指标 TSI (price,q,r s,u) 的配置(代码 "Blau_Mtm.mq5" 的变更与添加)

指标设置(综述)

指标 TSI(price,q,r,s,u) 的配置与指标 Mtm(price,q,r,s,u) 的配置有所区别(见图 1.8):

  1. 指定指标显示窗口(无变化
  2. 指定图形结构的数量(无变化
  3. 指定指标缓冲区数量(缓冲区数量增加。)
  4. 声明指标数组(添加到数组。)
  5. 分配数组/缓冲区/标绘:指标数组 ->指标缓冲区 -> 图形标绘(重组)。
  6. 描述每个图形标绘的属性(标签已更改
  7. 指定指标值的显示精度(精度已改变
  8. 为每个图形标绘指定初始柱的数量(且不显示于图形标绘上)(无变化
  9. 设置水平等级,并描述每个水平等级的属性(
  10. 设置独立指标窗口标度的限制(
  11. 指定短的指标名称(名称已改变。)

图 1.8.真实强弱指数 TSI (price,q,r,s,u) 指标

图 1.8.真实强弱指数 TSI (price,q,r,s,u) 指标


配置(变化)

在代码 "Blau_Mtm.mq5" 中完成下述细微修改。

1. mql5 程序的简短描述有变化:

#property description "True Strength Index (William Blau)"      // 描述

2. (配置 6 中)图形标绘的数量未增长,绘制方法(DRAW_LINE - 线)、线条颜色(蓝)、线条风格(STYLE_SOLID - 实线)及线宽 (1) 都保留不变,#0 图形标绘的标签已变:

#property indicator_label1  "TSI"        // #0图形的标签

3. (配置 7 中)指标值的显示精度已有变化:

   IndicatorSetInteger(INDICATOR_DIGITS,2);

4. (配置 11 中)指标的短名称已变:

   IndicatorSetString(INDICATOR_SHORTNAME,"Blau_TSI("+shortname+")");
配置:水平等级 (9)

要配置水平等级,必须针对每一等级指定下述内容:

  1. 纵轴上的值;
  2. 等级描述(可选)。水平层级有单一的渲染风格:
    1. 线条的显示颜色;
    2. 线条风格(于ENUM_LINE_STYLE 枚举中查看可能风格);
    3. 线条粗细。

配置方式有两种可能:

1) 利用 #property 预处理程序指令(实施如下)。

//--- 水平级别
#property indicator_level1 -25           // 水平 #0 (垂直坐标)
#property indicator_level2 25            // 水平 #1 (垂直坐标)
#property indicator_levelcolor Silver    // 级别颜色
#property indicator_levelstyle STYLE_DOT // 水平线类型
#property indicator_levelwidth 1         // 宽度

2) 利用一组 IndicatorSet *() 函数:

//--- 水平级别
   IndicatorSetInteger(INDICATOR_LEVELS,2);                // 指标水平的数量
   IndicatorSetDouble(INDICATOR_LEVELVALUE,0,-25);         // 水平 #0
   IndicatorSetDouble(INDICATOR_LEVELVALUE,1,25);          // 水平 #1
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,Silver);       // 水平颜色
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,STYLE_DOT);    // 水平线类型
   IndicatorSetInteger(INDICATOR_LEVELWIDTH,1);            // 水平宽度
   IndicatorSetString(INDICATOR_LEVELTEXT,0,"Oversold");   // #0 水平线的描述“超卖”
   IndicatorSetString(INDICATOR_LEVELTEXT,1,"Overbought"); // #1 水平线的描述“超买”

此代码被写入事件处理程序 Init()OnInit() 函数中。水平等级的索引从 0 开始。要改进水平等级的显示,就要用到 INDICATOR_LEVEL * 指数属性的标识符 - 均于 ENUM_CUSTOMIND_PROPERTY 枚举中列出。

每个等级的描述,都只利用 IndicatorSetString() 函数、INDICATOR_LEVELTEXT 指标属性标识符(ENUM_CUSTOMIND_PROPERTY_STRING 枚举)来设定。等级描述直接置于等级左上方。

通过指标的 "Properties" 窗口("Levels" 选项卡),您可以添加/移除水平等级、更改每个等级的值和描述,以及等级渲染的风格。

配置:独立指标窗口的标度限制 (10)

配置方式有两种可能:

1) 利用 #property 预处理程序指令(实施如下)。

//--- 指标的最小/最大值
#property indicator_minimum -100         // 最小
#property indicator_maximum 100          // 最大

2) 利用 IndicatorSetDouble() 函数、INDICATOR_MINIMUM 指标属性的标识符以及 INDICATOR_MAXIMUM  (ENUM_CUSTOMIND_PROPERTY_DOUBLE 枚举)。

//--- 指标范围
   IndicatorSetDouble(INDICATOR_MINIMUM,-100); // 最小
   IndicatorSetDouble(INDICATOR_MAXIMUM,100);  // 最大

此代码被写入事件处理程序 Init()OnInit() 函数中。独立指标窗口标度的上限和下限,可通过指标 "Properties" 窗口("Scale" 选项卡)进行更改。

配置(变化):指标缓冲区 (3-5)

配置中的变化“指标数组 -> 指标缓冲区 -> 图形标绘”:

1. (配置 3 中)缓冲区数量有增长:

#property indicator_buffers 10           // 用于指标计算的缓存区数量

2. (配置 4)计算 q 周期动量绝对值所需的指标数组添加:

double AbsMtmBuffer[];      // q-周期蜡烛线动量(绝对值)
double EMA_AbsMtmBuffer[];  // r-周期1st EMA(绝对值)
double DEMA_AbsMtmBuffer[]; // s-周期 2nd EMA(绝对值)
double TEMA_AbsMtmBuffer[]; // u-周期 3rd EMA (绝对值)

MainBuffer[] 数组的目的有改变:

double MainBuffer[];        // TSI(#0绘图图形)
double TEMA_MtmBuffer[];    // u-周期 3rd EMA

3. (配置 5 中)“指标数组 -> 指标缓冲区 -> 图形标绘”的连接有变化:

   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);                // TSI
   //  用于计算的中间过程的缓存(不是用来绘图的)
   SetIndexBuffer(1,PriceBuffer,INDICATOR_CALCULATIONS);       // 价格数组
   SetIndexBuffer(2,MtmBuffer,INDICATOR_CALCULATIONS);         //  q-周期动量
   SetIndexBuffer(3,EMA_MtmBuffer,INDICATOR_CALCULATIONS);     // r-周期 1st EMA
   SetIndexBuffer(4,DEMA_MtmBuffer,INDICATOR_CALCULATIONS);    // s-周期 2nd EMA
   SetIndexBuffer(5,TEMA_MtmBuffer,INDICATOR_CALCULATIONS);    // u-周期 3rd EMA
   SetIndexBuffer(6,AbsMtmBuffer,INDICATOR_CALCULATIONS);      // q-周期动量(绝对值)
   SetIndexBuffer(7,EMA_AbsMtmBuffer,INDICATOR_CALCULATIONS);  // r-周期1st EMA(绝对值)
   SetIndexBuffer(8,DEMA_AbsMtmBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA(绝对值)
   SetIndexBuffer(9,TEMA_AbsMtmBuffer,INDICATOR_CALCULATIONS); // u-周期 3rd EMA (绝对值)


1.4.2.2. 指标 TSI (price,q,r s,u) 的计算(代码 "Blau_Mtm.mq5" 的变更与添加)

计算:算法

计算指标 TSI (price,q,r,s,u) 的算法:

  1. 检查是否有足够的数据来计算指标。
  2. 依据指定价格类型计算价格数组 - PriceBuffer[] 数组的形成.
  3. 索引柱的确定 - 由此开始/继续 q 周期动量的计算。
  4. q 周期动量及其绝对值的计算 - MtmBuffer[] 与 AbsMtmBuffer[] 数组的填充。
  5. EMA 方法的第一次平滑(周期 r) - EMA_MtmBuffer[] 与 EMA_AbsMtmBuffer[] 数组的填充。
  6. EMA 方法的第二次平滑(周期 s) - DEMA_MtmBuffer[] 与 DEMA_AbsMtmBuffer[] 数组的填充。
  7. EMA 方法的第三次平滑(周期 u) - TEMA_MtmBuffer[] 与 TEMA_AbsMtmBuffer[] 数组的填充。
  8. 索引柱的确定 - 由此开始/继续真实强弱指数的计算。
  9. 真实强弱指数的计算 - MainBuffer[] 数组的填充 - #0 标绘值的计算。

算法变化的本质(简述):

  • a) (参见段落 4-7)q 周期动量绝对值(*AbsMtmBuffer[] 数组群)的计算,与 q 周期动量(数组群 * MtmtBuffer[])的计算并行执行;
  • b) (参见 8-9 部分)已添加 TSI 的计算。
计算:q 周期动量绝对值 (3-7)
//--- 计算 HLM 和 |HLM|
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin1;              // 从begin1开始计算所有值
      for(i=0;i<pos;i++)       // pos
        {
         MtmBuffer[i]=0.0;     // 置零值
         AbsMtmBuffer[i]=0.0;  //
        
}
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   // 计算 MtmBuffer[] 和 AbsMtmBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      MtmBuffer[i]=PriceBuffer[i]-PriceBuffer[i-(q-1)];
      AbsMtmBuffer[i]=MathAbs(MtmBuffer[i]);
     
}
//--- EMA 平滑
   //  r-周期 1st EMA
   ExponentialMAOnBufferWB(
                           rates_total,     // 所有柱形
                           prev_calculated, // 前一次计算的柱形
                           begin1,          // 起始索引
                           r,               // 平滑周期
                           MtmBuffer,       // 输入数组
                           EMA_MtmBuffer    // 输出数组
                          );
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin1,r,AbsMtmBuffer,EMA_AbsMtmBuffer);
   //  s-周期 2nd EMA
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin2,s,EMA_MtmBuffer,DEMA_MtmBuffer);
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin2,s,EMA_AbsMtmBuffer,DEMA_AbsMtmBuffer);
   // u-周期 3rd EMA
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin3,u,DEMA_MtmBuffer,TEMA_MtmBuffer);
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin3,u,DEMA_AbsMtmBuffer,TEMA_AbsMtmBuffer);

计算:真实强弱指数 (8-9)

//--- TSI 计算 (绘制 #0图形)
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin4;              // 从begin4开始计算所有值
      for(i=0;i<pos;i++)       // 
         MainBuffer[i]=0.0;    // 零值
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   // 计算 MainBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      value1=100*TEMA_MtmBuffer[i];
      value2=TEMA_AbsMtmBuffer[i];
      MainBuffer[i]=(value2>0)?value1/value2:0;
     
}

1.4.3. "Blau_Ergodic.mq5" - Ergodic(price,q,r,s,u,ul) - 遍历摆动指标

Ergodic (price,q,r,s,u,ul) 指标的代码基于 "Blau_TSI.mq5" 代码的变化:

//+------------------------------------------------------------------
//|                                                 Blau_Ergodic.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------
#property copyright "Copyright 2011, MetaQuotes Software Corp." // 版权
#property link      "http://www.mql5.com"                       // URL
#property description "Ergodic Oscillator (William Blau)"       // 描述
#include <WilliamBlau.mqh>                 // 包含文件 (terminal_data_folder\MQL5\Include)
//--- 指标设置
#property indicator_separate_window        // 指标显示在独立窗口
#property indicator_buffers 11             // 缓存数量
#property indicator_plots   2              // 指标绘图图形个数
//--- 水平级别
#property indicator_level1 -25             // 水平 #0
#property indicator_level2 25              // 水平 #1
#property indicator_levelcolor Silver      // 水平颜色
#property indicator_levelstyle STYLE_DOT   // 水平类型
#property indicator_levelwidth 1           // 宽度
//--- 最小/最大值
#property indicator_minimum -100           // 最小
#property indicator_maximum 100            // 最大
//--- 图形绘制 #0 (主)
#property indicator_label1  "Ergodic"      // 绘制#0图形
#property indicator_type1   DRAW_HISTOGRAM // 画直方图
#property indicator_color1  Silver         // 直方图颜色
#property indicator_style1  STYLE_SOLID    // 线形
#property indicator_width1  2              // 线宽
//--- 绘制 #1图形(信号线) 
#property indicator_label2  "Signal"       // 绘制#1图形
#property indicator_type2   DRAW_LINE      // 画线
#property indicator_color2  Red            // 线的颜色
#property indicator_style2  STYLE_SOLID    // 线形
#property indicator_width2  1              // 线宽
//--- 输入参数
input int    q=2;  //  Momentum 的周期q 
input int    r=20; // r - 1st EMA,应用于Momentum
input int    s=5;  //  s - 2nd EMA,应用于首次平滑
input int    u=3;  // u - 3rd EMA,应用于二次平滑
input int    ul=3; // 信号线的ul - 周期
input ENUM_APPLIED_PRICE AppliedPrice=PRICE_CLOSE; // AppliedPrice - 价格类型
//--- 动态数组
double MainBuffer[];        // Ergodic(#0绘图图形)
double SignalBuffer[];      // 信号线:ul-周期 EMA,应用于Ergodic(#1绘图图形)
double PriceBuffer[];       // 价格数组
double MtmBuffer[];         // q-周期动量
double EMA_MtmBuffer[];     // r-周期 1st EMA
double DEMA_MtmBuffer[];    // s-周期 2nd EMA
double TEMA_MtmBuffer[];    //  u-周期 3rd EMA
double AbsMtmBuffer[];      // q-周期蜡烛线动量(绝对值)
double EMA_AbsMtmBuffer[];  //  r-周期1st EMA(绝对值)
double DEMA_AbsMtmBuffer[]; // s-周期 2nd EMA(绝对值)
double TEMA_AbsMtmBuffer[]; // u-周期 3rd EMA (绝对值)
//--- 全局变量
int    begin1, begin2, begin3, begin4, begin5; // 起始索引
int    rates_total_min; // 最小柱形数量
//+------------------------------------------------------------------
//| 自定义指标初始化函数                                               |
//+------------------------------------------------------------------
int OnInit()
  {
//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);                 // Ergodic指标
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);               // 信号线:ul-周期 EMA,应用于Ergodic
   //  缓存,用于计算的中间过程
   SetIndexBuffer(2,PriceBuffer,INDICATOR_CALCULATIONS);        // 价格数组
   SetIndexBuffer(3,MtmBuffer,INDICATOR_CALCULATIONS);          // q-周期动量
   SetIndexBuffer(4,EMA_MtmBuffer,INDICATOR_CALCULATIONS);      // r-周期 1st EMA 
   SetIndexBuffer(5,DEMA_MtmBuffer,INDICATOR_CALCULATIONS);     // s-周期 2nd EMA
   SetIndexBuffer(6,TEMA_MtmBuffer,INDICATOR_CALCULATIONS);     //u-周期 3rd EMA
   SetIndexBuffer(7,AbsMtmBuffer,INDICATOR_CALCULATIONS);       // q-周期蜡烛线动量(绝对值)
   SetIndexBuffer(8,EMA_AbsMtmBuffer,INDICATOR_CALCULATIONS);   //  r-周期1st EMA(绝对值)
   SetIndexBuffer(9,DEMA_AbsMtmBuffer,INDICATOR_CALCULATIONS);  // s-周期 2nd EMA(绝对值)
   SetIndexBuffer(10,TEMA_AbsMtmBuffer,INDICATOR_CALCULATIONS); // u-周期 3rd EMA (绝对值)
/*
//--- 图形绘制 #0 (主)
   PlotIndexSetString(0,PLOT_LABEL,"Ergodic");           // #0图形的标签
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_HISTOGRAM); //  画直方图
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,Silver);        // 线的颜色
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);   // 线形
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);             // 线宽
//--- 绘制 #1图形(信号线) 
   PlotIndexSetString(1,PLOT_LABEL,"Signal");            // #1绘图图形标签
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);      // 画线
   PlotIndexSetInteger(1,PLOT_LINE_COLOR,Red);           // 线的颜色
   PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_SOLID);   // 线形
   PlotIndexSetInteger(1,PLOT_LINE_WIDTH,1);             // 线宽
*/
//--- 精度
   IndicatorSetInteger(INDICATOR_DIGITS,2);
/*
//--- 水平级别
   IndicatorSetInteger(INDICATOR_LEVELS,2);                // 指标水平的数量
   IndicatorSetDouble(INDICATOR_LEVELVALUE,0,-25);         // 水平 #0
   IndicatorSetDouble(INDICATOR_LEVELVALUE,1,25);          // 水平 #1
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,Silver);       // 水平颜色
   IndicatorSetInteger(INDICATOR_LEVELSTYLE,STYLE_DOT);    // 水平线形
   IndicatorSetInteger(INDICATOR_LEVELWIDTH,1);            // 线宽
   IndicatorSetString(INDICATOR_LEVELTEXT,0,"Oversold");   // #0 水平线“超卖”
   IndicatorSetString(INDICATOR_LEVELTEXT,1,"Overbought"); // #1 水平线“超买”
//--- 最小/最大值
   IndicatorSetDouble(INDICATOR_MINIMUM,-100); // 最小
   IndicatorSetDouble(INDICATOR_MAXIMUM,100);  // 最大
*/
//---
   begin1=q-1;         //                                    - MtmBuffer[], AbsMtmBuffer[]
   begin2=begin1+r-1;  //  或者=(q-1)+(r-1)                    - EMA_...[]
   begin3=begin2+s-1;  // 或者 =(q-1)+(r-1)+(s-1)              - DEMA_...[]
   begin4=begin3+u-1;  // 或者 =(q-1)+(r-1)+(s-1)+(u-1)        - TEMA_...[], MainBuffer[]
   begin5=begin4+ul-1; // 或者 =(q-1)+(r-1)+(s-1)+(u-1)+(ul-1) - SignalBuffer[]
   //
   rates_total_min=begin5+1; // 最小柱形数量
//---绘制#0图形的开始索引
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin4);
//--- 绘制#1图形的开始索引
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,begin5);
//--- 指标简称
   string shortname=PriceName(AppliedPrice)+","+string(q)+","+string(r)+","+string(s)+","+string(u)+","+string(ul);
   IndicatorSetString(INDICATOR_SHORTNAME,"Blau_Ergodic("+shortname+")");
//--- 初始化完成
   return(0);
  
}
//+------------------------------------------------------------------
//| 自定义指标迭代函数                                                 |
//+------------------------------------------------------------------
int OnCalculate(
                const int rates_total,     // 柱形数量
                const int prev_calculated, // 前一次调用时计算的柱形
                const datetime &Time[],    // 时间
                const double &Open[],      // 开盘价
                const double &High[],      // 最高价
                const double &Low[],       // 最低价
                const double &Close[],     // 收盘价
                const long &TickVolume[],  // Tick成交量
                const long &Volume[],      // 真实成交量
                const int &Spread[]        // 点差
               )
  {
   int i,pos;
   double value1,value2;
//--- 所有柱形数量
   if(rates_total<rates_total_min) return(0);
//--- 计算PriceBuffer[]
   CalculatePriceBuffer(
                        AppliedPrice,        // 价格类型
                        rates_total,         // 所有柱形数量
                        prev_calculated,     // 前次调用时计算的柱形
                        Open,High,Low,Close, // Open[], High[], Low[], Close[]
                        PriceBuffer          // 价格数组
                       );
//--- 计算 HLM 和 |HLM|
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin1;              // 从begin1开始
      for(i=0;i<pos;i++)       // pos
        {
         MtmBuffer[i]=0.0;     // 置零值
         AbsMtmBuffer[i]=0.0;  //
        
}
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   // 计算 MtmBuffer[] 和 AbsMtmBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      MtmBuffer[i]=PriceBuffer[i]-PriceBuffer[i-(q-1)];
      AbsMtmBuffer[i]=MathAbs(MtmBuffer[i]);
     
}
//--- EMA 平滑
   // r-周期 1st EMA
   ExponentialMAOnBufferWB(
                           rates_total,     // 所有柱形
                           prev_calculated, // 前一次计算的柱形
                           begin1,          // 起始索引
                           r,               // 平滑周期
                           MtmBuffer,       // 输入数组
                           EMA_MtmBuffer    // 输出数组
                          );
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin1,r,AbsMtmBuffer,EMA_AbsMtmBuffer);
   //  s-周期 2nd EMA
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin2,s,EMA_MtmBuffer,DEMA_MtmBuffer);
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin2,s,EMA_AbsMtmBuffer,DEMA_AbsMtmBuffer);
   // u-周期 3rd EMA
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin3,u,DEMA_MtmBuffer,TEMA_MtmBuffer);
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin3,u,DEMA_AbsMtmBuffer,TEMA_AbsMtmBuffer);
//---计算Ergodic( 绘制#0图形)
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin4;              // 从begin4开始
      for(i=0;i<pos;i++)       // pos
         MainBuffer[i]=0.0;    // 零值
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一个柱形
   // 计算 MainBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      value1=100*TEMA_MtmBuffer[i];
      value2=TEMA_AbsMtmBuffer[i];
      MainBuffer[i]=(value2>0)?value1/value2:0;
     
}
//--- 计算信号线( 绘制#1图形)
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin4,ul,MainBuffer,SignalBuffer);
//--- OnCalculate函数结束。返回prev_calculated的值用于下一次调用
   return(rates_total);
  
}
//+------------------------------------------------------------------

下面我们只是仔细研究一下代码 "Blau_TSI.mq5" 的修改与添加。

1.4.3.1. 指标 Ergodic (price,q,r,s,u,ul) 的配置(代码 "Blau_TSI.mq5" 的变更与添加)

指标设置(综述)

指标 Ergodic (price,q,r,s,u,ul) 的配置与指标 TSI (price,q,r,s,u) 的配置有所区别(见图 1.9):

  1. 指定指标显示窗口(无变化
  2. 指定图形标绘的数量(添加了一个图形标绘
  3. 指定指标缓冲区数量(缓冲区数量增加。)
  4. 声明指标数组(添加到数组
  5. 设置一个关联:指标数组 ->指标缓冲区 -> 图形标绘(重组)。
  6. 描述每个图形标绘的属性(属性有更改,添加了一个图形标绘。)
  7. 指定指标值的显示精度(无变化。)
  8. 为每个图形结构指明初始柱的数量(且不显示于图形标绘)(添加了一个图形标绘。)
  9. 设置水平等级,并描述每个水平等级的属性(无变化。)
  10. 设置指标窗口独立标度的限制(无变化。)
  11. 指定短的指标名称(名称已改变。)

图 1.9.遍历 (price,q,r,s,u,ul) 指标

图 1.9.遍历 (price,q,r,s,u,ul) 指标


配置(变化)

"Blau_TSI.mq5" 代码已有如下更改。

1. mql5 程序的简短描述有变化:

#property description "Ergodic Oscillator (William Blau)"       // 描述

2. 添加了一个输入参数:

input int    ul=3; // 信号线的ul - 周期

3. (配置 11 中)指标的短名称已变:

//--- 指标简称
   string shortname=PriceName(AppliedPrice)+","+string(q)+","+string(r)+","+string(s)+","+string(u)+","+string(ul);
   IndicatorSetString(INDICATOR_SHORTNAME,"Blau_Ergodic("+shortname+")");
配置(变化):图形标绘 (2, 6)

1. (配置 2 中)又添加了一个图形标绘(信号线):

#property indicator_plots   2              // 指标绘图图形个数

2. (配置 6 中) a) 改变了第一个图形标绘 #0 "Ergodic" 的属性。

此前,我们使用(标识符 DRAW_LINE)作为行显示的一种方式,现在我们则用来自零线的一个直方图(DRAW_HISTOGRAM,源于 ENUM_DRAW_TYPE 枚举)

更改了线条的显示颜色和线宽:

//--- 图形绘制 #0 (主)
#property indicator_label1  "Ergodic"      // 绘制#0图形
#property indicator_type1   DRAW_HISTOGRAM // 画直方图
#property indicator_color1  Silver         // 直方图颜色
#property indicator_style1  STYLE_SOLID    // 线形
#property indicator_width1  2              // 线宽

b) 添加了一个图形标绘 #1 "Signal" (信号线):

//--- 绘制 #1图形(信号线) 
#property indicator_label2  "Signal"       // 绘制#1图形
#property indicator_type2   DRAW_LINE      // 画线
#property indicator_color2  Red            // 线的颜色
#property indicator_style2  STYLE_SOLID    // 线形
#property indicator_width2  1              // 线宽

配置(变化):指标缓冲区 (3-5)

配置中的变化“指标数组 -> 指标缓冲区 -> 图形结构”:

1. (配置 3 中)缓冲区数量有增长:

#property indicator_buffers 11             // 缓存数量

2. (配置 4 中)添加了一个计算和渲染信号线值所需的指标数组:

double SignalBuffer[];      // 信号线:ul-周期 EMA,应用于Ergodic(#1绘图图形)

3. (配置 5 中)“指标数组 -> 指标缓冲区 -> 图形标绘”的关系有变化:

//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);                 // Ergodic指标
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);               // 信号线:ul-周期 EMA,应用于Ergodic
   //  缓存,用于计算的中间过程
   SetIndexBuffer(2,PriceBuffer,INDICATOR_CALCULATIONS);        // 价格数组
   SetIndexBuffer(3,MtmBuffer,INDICATOR_CALCULATIONS);          // q-周期动量
   SetIndexBuffer(4,EMA_MtmBuffer,INDICATOR_CALCULATIONS);      // r-周期 1st EMA 
   SetIndexBuffer(5,DEMA_MtmBuffer,INDICATOR_CALCULATIONS);     // s-周期 2nd EMA
   SetIndexBuffer(6,TEMA_MtmBuffer,INDICATOR_CALCULATIONS);     //u-周期 3rd EMA
   SetIndexBuffer(7,AbsMtmBuffer,INDICATOR_CALCULATIONS);       // q-周期蜡烛线动量(绝对值)
   SetIndexBuffer(8,EMA_AbsMtmBuffer,INDICATOR_CALCULATIONS);   //  r-周期1st EMA(绝对值)
   SetIndexBuffer(9,DEMA_AbsMtmBuffer,INDICATOR_CALCULATIONS);  // s-周期 2nd EMA(绝对值)
   SetIndexBuffer(10,TEMA_AbsMtmBuffer,INDICATOR_CALCULATIONS); // u-周期 3rd EMA (绝对值)

设置:未经渲染下的初始柱数 (8)
  • 图形标绘 #0 "Ergodic" 未经渲染的初始柱数量没有变化。计算方法列于 1.4.1.1 部分。
  • 图形标绘 #1 "Signal" 未经渲染的初始柱数量的计算方法相同。SignalBuffer[] 数组是 MainBuffer[] 数组有效数据平滑(周期 ul)的结果。

因为 MainBuffer[] 数组的索引从 0 开始,所以 MainBuffer[] 数组的有效数据从索引 (q-1)+(r-1)+(s-1)+(u-1) 开始,SignalBuffer[] 数组的有效数据从索引 (q-1)+(r-1)+(s-1)+(u-1)+(ul-1) 开始。

声明了全局变量 begin5

int    begin1, begin2, begin3, begin4, begin5; // 起始索引

计算(完成,更多内容请见 1.4.1.1 部分):

//---
   begin1=q-1;         //                                    - MtmBuffer[], AbsMtmBuffer[]
   begin2=begin1+r-1;  //  或者=(q-1)+(r-1)                    - EMA_...[]
   begin3=begin2+s-1;  // 或者 =(q-1)+(r-1)+(s-1)              - DEMA_...[]
   begin4=begin3+u-1;  // 或者 =(q-1)+(r-1)+(s-1)+(u-1)        - TEMA_...[], MainBuffer[]
   begin5=begin4+ul-1; // 或者 =(q-1)+(r-1)+(s-1)+(u-1)+(ul-1) - SignalBuffer[]
   //
   rates_total_min=begin5+1; // 最小柱形数量
//---绘制#0图形的开始索引
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin4);
//--- 绘制#1图形的开始索引
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,begin5);


1.4.3.2. Ergodic (price,q,r,s,u,ul) 指标的计算(代码 "Blau_TSI.mq5" 的变更与添加)

计算:算法

计算指标 Ergodic (price,q,r,s,ul) 的算法:

  1. 检查是否有足够的数据来计算指标。
  2. 依据指定价格类型计算价格数组 - PriceBuffer[] 数组的填充.
  3. 索引柱的确定 - 由此开始/继续 q 周期动量的计算。
  4. q 周期动量及其绝对值的计算 - MtmBuffer[] 与 AbsMtmBuffer[] 数组的填充。
  5. EMA 方法的第一次平滑(周期 r) - EMA_MtmBuffer[] 与 EMA_AbsMtmBuffer[] 数组的填充。
  6. EMA 方法的第二次平滑(周期 s) - DEMA_MtmBuffer[] 与 DEMA_AbsMtmBuffer[] 数组的填充。
  7. EMA 方法的第三次平滑(周期 u) - TEMA_MtmBuffer[] 与 TEMA_AbsMtmBuffer[] 数组的填充。
  8. 索引柱的确定 - 由此开始/继续真实强弱指数的计算。
  9. 遍历(真实强弱指数)的计算 - MainBuffer[] 数组的填充 - #0 图形标绘渲染值的计算。
  10. 信号线的计算 - 利用 EMA 方法进行的遍历平滑(周期 ul) - SignalBuffer[] 数组的填充 - 图形标绘 #1 渲染值的计算。

算法中的本质变化(简述) a) (参见第 1 部分)指标输入时间序列最小值要求已变更;b) (参见段落 10)信号线计算已变更。

计算(变更):检查是否有足够的数据来计算指标 (1)

算法中没有变化:

//--- 所有柱形数量
   if(rates_total<rates_total_min) return(0);

全局变量 rates_total_min  的值已变更,(指标输入时间序列的最小值,通过 Init 事件处理程序的 OnInit() 函数计算得出):

   rates_total_min=begin5+1; // 指标输入数组的最小尺寸
计算:信号线 (10)
//--- 计算信号线( 绘制#1图形)
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin4,ul,MainBuffer,SignalBuffer);

2. 随机动量

将探讨过的指标(参见附件)划分为两个组。

I. 基于随机变量的指标:

  1. Blau_TStoch.mq5 - 随机变量(q 周期随机变量;平滑 q 周期随机变量);
  2. Blau_TStochI.mq5 - 随机指数(标准化平滑 q 周期随机变量);
  3. Blau_TS_Stochastic.mq5 - 随机 TS 摆动指标(基于随机变量指数)。

II.基于随机动量的指标:

  1. Blau_SM.mq5 - 随机动量(q 周期随机动量;平滑 q 周期随机动量);
  2. Blau_SMI.mq5 - 随机动量指数(标准化平滑 q 周期动量);
  3. Blau_SM_Stochastic.mq5 - 随机 SM 摆动指标(基于随机动量指数)。


2.1. 基于随机变量的指标

"分析/技术指标/摆动指标/随机摆动指标"部分的《MetaTrader 客户端用户指南》,讲述了内置于MetaTrader 5 客户端的随机摆动指标的技术指标,及其在技术分析中的应用方式(亦请参见 iStochastic。)

 

2.1.1. George Lane 的随机摆动指标

随机变量随机摆动指标 (Stochastic, Stochastic Oscillator) - 是一个显示与之前 q 周期价格波动相关价格的指标。而 George Lane 则是该指标的创造者和推广者。

区别:

  • 快随机指标,有时被称为 %K;
  • 慢随机指标(信号线),有时被称为 %D。

George Lane 提出的随机指标公式:

           price - LL(q)
%K = 100 * -------------
           HH(q) - LL(q)
%D = SMA(%k, ul)

其中:

  • % K - 快随机指标;
  • % D - 慢随机指标(信号线);
  • price - 当前周期的价格 [收盘];
  • q - 随机指标计算中使用的价格图表时间周期的数量;
  • HH (q) - q 周期最高价之前 q 周期最大值;
  • LL (q) - q 周期最低价之前 q 周期最大值;
  • SMA (% K, ul) - 应用于快随机指标 (% K) 的订单 ul 的简单移动平均线。

根据 George Lane 的解释,基础理念即为:在某个价格上涨趋势期间(上行走势),价格倾向于靠近之前的最大值停止。如果是在某个价格下滑期间(下行走势),则价格倾向于靠近之前最小值停止。

 

2.1.2. William Blau 的随机摆动指标


图 2.1.William Blau 基于随机变量的指标

图 2.1.William Blau 基于随机变量的指标

 

2.1.2.1. 随机变量


随机变量 - 是当前周期的价格 [收盘] 与之前 q 周期价格波动范围最低点的距离。q 周期随机变量的值会显示为价格平移量 - 相对于 q 周期价格波动范围最低点。q 周期随机变量值为正数或等于零。

图 2.2.随机变量的定义

图 2.2.随机变量的定义

q 周期随机变量公式

stoch(price,q) = price - LL(q)

其中:

  • price - 当前周期的价格 [收盘];
  • q - 随机变量计算中涉及到的价格图表时间周期的数量;
  • LL (q) - q 周期最低价之前 q 周期最大值。

q 周期随机变量公式

TStoch(price,q,r,s,u) = EMA(EMA(EMA( stoch(price,q) ,r),s),u)

其中:

  • price - [收盘] 价 - 价格图表的价格基础;
  • q - 随机变量计算中使用的柱数;
  • stoch(price,q)=price-LL(q) - q-周期随机变量;
  • EMA (stoch (price,q),r) - 第一次平滑 - 应用于 q 周期随机变量的周期 r 的 EMA;
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的周期 s 的 EMA;
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的周期 u 的 EMA。

TStoch(price,q,r,s,u) - 随机变量。规范

  • 文件名称Blau_TStoch.mq5
  • 名称:依 William Blau,随机指标(q-周期随机;平滑 q-周期随机)。
  • 输入参数
    • q - 随机指标计算的周期(默认 q = 5);
    • r -应用于随机指标的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则不采用 EMA 平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

2.1.2.2. 随机指数

随机指数指标是标准化的平滑 q-周期随机变量。

平滑 q-周期随机变量的值,被映射至某个百分比格式(区间 [0, 100])。平滑 q-周期随机变量的每个值,均按 q-周期价格范围的值标准化。标准化允许将平滑标准化 q-周期随机变量的值,解释为市场超买/超卖状态的程度。

随机指数公式

                         100 * EMA(EMA(EMA( price-LL(q) ,r),s),u)       100 * TStoch(price,q,r,s,u)
TStochI(price,q,r,s,u) = ---------------------------------------- = ----------------------------------
                            EMA(EMA(EMA( HH(q)-LL(q) ,r),s),u)      EMA(EMA(EMA( HH(q)-LL(q) ,r),s),u)
if EMA(EMA(EMA(HH(q)-LL(q),r),s),u)=0, then TStochI(price,q,r,s,u)=0

其中:

  • price - [收盘] 价 - 价格图表的价格基础;
  • q - 随机变量计算中使用的柱数;
  • LL (q) - q 周期最低价格的最小值;
  • HH (q) - q 周期最高价格的最大值;
  • stoch(q)=price-LL(q) - q-周期随机变量;
  • TStoch(price,q,r,s,u) - 三次平滑 q-周期随机变量;
  • HH(q)-LL(q) - q-周期价格范围;
  • EMA (..., r) - 第一次平滑 - EMA(r),应用于:
    1. q-周期随机变量;
    2. q-周期价格范围;
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(u)。

TStochI(price,q,r,s,u) - 随机指数。规范

  • 文件名称Blau_TStochI.mq5
  • 名称:依 William Blau,随机指数(标准化平滑 q-周期随机变量)。
  • 输入参数
    • q - 随机指标计算的周期(默认 q = 5);
    • r -应用于随机指标的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 图形标绘渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡);
    • (可选)两级(默认为 40 和 60) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改独立指标窗口标度的下限(默认 0)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

2.1.2.3. 随机摆动指标

随机摆动指标的定义:

TS_Stochastic(price,q,r,s,u) = TStochI(price,q,r,s,u)
SignalLine(price,q,r,s,u,ul) = EMA( TS_Stochastic(price,q,r,s,u) ,ul)

其中:

  • TS_Stochastic() - 快随机指标,%k - 随机指数 TStochI(price,q,r,s,u);
  • SignalLine() - 慢随机指标(信号线),% d - 应用于快随机指标 (% k) 的 ul 周期 EMA;
  • ul - EMA 周期信号线 - 根据 William Blau,ul 值必须等于 EMA 快随机指标最后一个有效周期 (>1)。

TS_Stochastic(price,q,r,s,u,ul) - 随机摆动指标。规范

  • 文件名称Blau_TS_Stochastic.mq5
  • 名称:依 William Blau,随机摆动指标(基于随机指数)。
  • 输入参数
    • 图形标绘 #0 - 快随机指标(随机指数),% k:
      • q - 随机指标计算的周期(默认 q = 5);
      • r -应用于随机指标的第一次 EMA 的周期(默认 r = 20);
      • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
      • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • 图形标绘 #1 - 慢随机指标(信号线),% d:
      • ul - 周期 EMA 信号线,应用于快随机指标(默认 ul = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 每个图形标绘渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡);
    • 可选)两级(默认为 40 和 60) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改独立指标窗口标度的下限(默认 0)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则不采用 EMA 平滑;
    • ul>0。如果 ul = 1,则慢随机指标(信号线)与快随机指标线相同;
    • 价格数组最小尺寸 = (q-1 + r + s + u + ul-4 +1)。

 

2.1.2.4. 连续性


William Blau' 的随机摆动指标包括 George Lane 的随机摆动指标。要在 MetaTrader 5 中实现 TS_Stochastic (William Blau) 与标准随机摆动指标 (George Lane) 的对应,必须指定下述内容:

TS_Stochastic( price=Close, q=KPeriod, r=1, s=1, u=1, ul=DPeriod )
Stochastic( KPeriod=q, DPeriod=ul, Slowing=1, price="Low/High", method="Exponential" )

图 2.3.William Blau 随机摆动指标包含 George Lane 的随机摆动指标

图 2.3.William Blau 随机摆动指标包含 George Lane 的随机摆动指标

 

2.1.2.5. 随机摆动指标的代码


基于 TS_Stochastic (price,q,r,s,u,ul) 指标示例:

1) 指标数组、指标缓冲区与图形标绘之间的关联:

//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);              // 快速随机
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);            // 慢速随机:快速随机的ul-周期 EMA
   // 缓存,用于计算的中间过程
   SetIndexBuffer(2,PriceBuffer,INDICATOR_CALCULATIONS);      // 价格数组
   SetIndexBuffer(3,LLBuffer,INDICATOR_CALCULATIONS);         // 最小值(q个柱形)
   SetIndexBuffer(4,HHBuffer,INDICATOR_CALCULATIONS);         //  最大值(q个柱形)
   SetIndexBuffer(5,StochBuffer,INDICATOR_CALCULATIONS);      // q-周期随机指数
   SetIndexBuffer(6,EMA_StochBuffer,INDICATOR_CALCULATIONS);  //  r-周期 1st EMA 
   SetIndexBuffer(7,DEMA_StochBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA
   SetIndexBuffer(8,TEMA_StochBuffer,INDICATOR_CALCULATIONS); // u-周期 3rd EMA
   SetIndexBuffer(9,HHLLBuffer,INDICATOR_CALCULATIONS);       // q-周期价格波动范围
   SetIndexBuffer(10,EMA_HHLLBuffer,INDICATOR_CALCULATIONS);  // r-周期 1st EMA (价格范围)
   SetIndexBuffer(11,DEMA_HHLLBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA(价格范围)
   SetIndexBuffer(12,TEMA_HHLLBuffer,INDICATOR_CALCULATIONS); // u-周期 3rd EMA(价格范围)

2) q-周期随机指标与 q-周期价格范围的计算算法:

   // 计算StochBuffer[], HHLLBuffer[], LLBuffer[], HHBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      // LLBuffer[] - 搜索最低价(q个柱形)
      // HHBuffer[] - 搜索最高价(q个柱形)
      min=1000000.0;
      max=-1000000.0;
      for(k=i-(q-1);k<=i;k++)
        {
         if(min>Low[k])  min=Low[k];
         if(max<High[k]) max=High[k];
        
}
      LLBuffer[i]=min;
      HHBuffer[i]=max;
      // StochBuffer[] - q-周期随机指数
      StochBuffer[i]=PriceBuffer[i]-LLBuffer[i];
      // HHLLBuffer[] - q-周期价格范围
      HHLLBuffer[i]=HHBuffer[i]-LLBuffer[i];
     
}


2.2. 基于随机动量的指标

图 2.4.William Blau 基于随机动量的指标

图 2.4.William Blau 基于随机动量的指标

 

2.2.1. 随机动量

随机动量(随机动量,SM) - 是指当前周期价格与之前整个 q 周期的价格范围中间位置的距离。q-周期随机动量的值会呈现价格在价格范围中的位置。

q-周期随机动量的标志会呈现价格相对于 q-周期价格范围中间位置的位置:正随机动量 - 价格在中间点以上;负随机动量 - 价格在中间点以下。

图 2.5.随机动量的定义

图 2.5.随机动量的定义

q-周期随机动量公式

sm(price,q) = price - 1/2 * [LL(q) + HH(q)]

其中:

  • price - 当前周期的价格 [收盘];
  • q - 随机动量计算中使用的柱数;
  • LL (q) - q 周期最低价格的最小值;
  • HH (q) - q 周期最高价格的最大值;
  • 1/2* [LL(q)+HH (q)] - q-周期价格范围的中间位置。

平滑 q-周期随机动量公式

SM(price,q,r,s,u) = EMA(EMA(EMA( sm(price,q) ,r),s),u)

其中:

  • price - [收盘] 价 - 价格图表的价格基础;
  • q - 随机动量计算中使用的柱数;
  • sm(price,q)=price-1/2*[LL(q)+HH(q)] - q-周期随机动量;
  • EMA (mtm (price, q), r) - 第一次平滑 - 应用于 q-周期随机动量的 EMA(r);
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA(EMA(EMA(sm(q),r),s),u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(u)。


2.2.1.2. SM(price,q,r,s,u) - 随机动量。规范

  • 文件名称Blau_SM.mq5
  • 名称:依 William Blau,随机动量指标(q-周期随机动量;平滑 q-周期随机动量)。
  • 输入参数
    • q - 随机动量指标计算的周期(默认 q = 5);
    • r -应用于随机动量的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则不采用 EMA 平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

2.2.2. 随机动量指数

随机动量指数 (SMI) - 是一个标准化的随机率指标(标准化平滑 q-周期随机动量)。平滑 q-周期随机动量的值,以百分比格式给出(区间 [-100, 100])。

平滑 q-周期随机动量的每个值,均按 q-周期价格波动范围的半数值标准化。标准化允许将 SMI 的值解释为市场的超买水平(正值)或超卖水平(负值)的程度。

随机动量指数公式

                     100 * EMA(EMA(EMA( price-1/2*[LL(q)+HH(q)] ,r),s),u)           100 * SM(price,q,r,s,u)
SMI(price,q,r,s,u) = ---------------------------------------------------- = ----------------------------------------
                           EMA(EMA(EMA( 1/2*[HH(q)-LL(q)] ,r),s),u)         EMA(EMA(EMA( 1/2*[HH(q)-LL(q)] ,r),s),u)
if EMA(EMA(EMA(1/2*[HH(q)-LL(q)],r),s),u)=0, then SMI(price,q,r,s,u)=0

其中:

  • price - [收盘] 价 - 价格图表的价格基础;
  • LL (q) - q 周期最低价格的最小值;
  • HH (q) - q 周期最高价格的最大值;
  • sm(price,q)=price-1/2*[LL(q)+HH(q)] - q-周期随机动量;
  • SM(price,q,r,s,u) - 三次平滑 q-周期随机动量;
  • HH(q)-LL(q) - q-周期价格范围;
  • 1/2* [LL(q)+HH (q)] - q-周期价格范围的中间位置;
  • 1/2*[HH(q)-LL(q)] - q-周期价格范围的一半位置;
  • EMA (..., r) - 第一次平滑 - EMA(r),应用于:
    1) q-周期随机动量
    2) q-周期价格范围的一半位置;
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(u)。


2.2.2.2. SM(price,q,r,s,u) - 随机动量指标。规范

  • 文件名称Blau_SMI.mq5
  • 名称:依 William Blau,随机动量指数(标准化平滑 q-周期随机动量)。
  • 输入参数
    • q - 随机动量指标计算的周期(默认 q = 5);
    • r -应用于随机动量的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
    • (可选)两级(默认为 -40 和 +40) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

2.2.3. 随机摆动指标

随机摆动指标的定义:
SM_Stochastic(price,q,r,s,u) = SMI(price,q,r,s,u)
SignalLine(price,q,r,s,u,ul) = EMA( SM_Stochastic(price,q,r,s,u) ,ul)

其中:

  • SM_Stochastic() - 随机动量指数 SMI(price,q,r,s,u);
  • SignalLine() - 信号线 - 应用于随机动量指数的 ul 周期 EMA;
  • ul - EMA 周期信号线 - 根据 William Blau,ul 值必须等于 EMA 随机率指数最后一个有效周期 (>1)。


2.2.3.1. SM_Stochastic(price,q,r,s,u,ul) - 随机摆动指标。规范

  • 文件名称Blau_SM_Stochastic.mq5
  • 名称:依 William Blau,随机摆动指标(基于随机动量)。
  • 输入参数
    • 图形标绘 #0 - 随机动量指数:
      • q - 随机动量指标计算的周期(默认 q = 5);
      • r -应用于随机动量的第一次 EMA 的周期(默认 r = 20);
      • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
      • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • 图形标绘 #1 - 信号线:
      • ul - 周期 EMA 信号线,关于随机率的指数(默认 ul = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 每个图形标绘渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡);
    • 两级(默认为 -40 和 +40) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • ul>0。如果 ul = 1,则信号线与随机率指数一致;
    • 价格数组最小尺寸 = (q-1 + r + s + u + ul-4 +1)。

 

2.2.4. 随机摆动指标的代码

SM_Stochastic (price, q, r, s, u, ul):

1) 指标数组、指标缓冲区与图形标绘之间的关联:

//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);                   // 随机动量指数
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);                 // 信号线:ul-周期 EMA,应用于随机动量指数
   // 用于计算的中间过程的缓存(不是用来绘图的)
   SetIndexBuffer(2,PriceBuffer,INDICATOR_CALCULATIONS);          // 价格数组
   SetIndexBuffer(3,LLBuffer,INDICATOR_CALCULATIONS);             // 最低价(q个柱形)
   SetIndexBuffer(4,HHBuffer,INDICATOR_CALCULATIONS);             // 最高价(q个柱形)/s3>
   SetIndexBuffer(5,SMBuffer,INDICATOR_CALCULATIONS);             // q-周期随机动量
   SetIndexBuffer(6,EMA_SMBuffer,INDICATOR_CALCULATIONS);         // r-周期 1st EMA 
   SetIndexBuffer(7,DEMA_SMBuffer,INDICATOR_CALCULATIONS);        // s-周期 2nd EMA
   SetIndexBuffer(8,TEMA_SMBuffer,INDICATOR_CALCULATIONS);        //  u-周期 3rd EMA
   SetIndexBuffer(9,HalfHHLLBuffer,INDICATOR_CALCULATIONS);       // 价格范围的一半(q个柱形)
   SetIndexBuffer(10,EMA_HalfHHLLBuffer,INDICATOR_CALCULATIONS);  // r-周期1st EMA(价格范围的一半)
   SetIndexBuffer(11,DEMA_HalfHHLLBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA (价格范围的一半)
   SetIndexBuffer(12,TEMA_HalfHHLLBuffer,INDICATOR_CALCULATIONS); // u-周期 3rd EMA (价格范围的一半)

2) q-周期随机动量与 q-周期价格范围一半位置的计算算法:

//--- 计算q-周期随机动量和价格波动范围的一半(q个柱形)
   if(prev_calculated==0)       // 首次调用
     {
      pos=begin1;               // 从0开始
      for(i=0;i<pos;i++)        // pos 值
        {
         SMBuffer[i]=0.0;       // 零值
         HalfHHLLBuffer[i]=0.0; //
         LLBuffer[i]=0.0;       //
         HHBuffer[i]=0.0;       //
        
}
     
}
   else pos=prev_calculated-1;  // 否则仅计算最近一次的值
   //计算SMBuffer[], HalfHHLLBuffer[], LLBuffer[], HHBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      // 计算LLBuffer[] - 查找最低价格(q个柱形)
      // 计算HHBuffer[] - 查找最高价格(q个柱形)
      min=1000000.0;
      max=-1000000.0;
      for(k=i-(q-1);k<=i;k++)
        {
         if(min>Low[k])  min=Low[k];
         if(max<High[k]) max=High[k];
        
}
      LLBuffer[i]=min;
      HHBuffer[i]=max;
      // 计算SMBuffer[] - q-周期随机动量
      SMBuffer[i]=PriceBuffer[i]-0.5*(LLBuffer[i]+HHBuffer[i]);
      // 计算 HalfHHLLBuffer[] - 价格波动范围的一半(q个柱形)
      HalfHHLLBuffer[i]=0.5*(HHBuffer[i]-LLBuffer[i]);
     
}


3. 趋势偏离指标

将探讨过的指标(参见附件)划分为两个组。

I. 基于市场趋势偏差的指标。

  1. Blau_MDI.mq5- 趋势平均偏差指标(平均偏差、移动平均线偏差);
  2. Blau_Ergodic_MDI.mq5- 遍历 MDI 摆动指标(基于平均偏差)。

II.基于平滑/异同移动平均线的指标。

  1. Blau_MACD.mq5- 平滑/异同移动平均线(MACD;平滑 MACD);
  2. Blau_Ergodic_MACD.mq5- 遍历 MACD 摆动指标(基于 MACD 指标)。


3.1. 基于市场趋势偏差的指标。

图 3.1.William Blau 基于市场趋势偏差的指标

图 3.1.William Blau 基于市场趋势偏差的指标

 

3.1.1. 平均偏差指标

趋势平均偏差是指价格与应用于价格的 r 周期 EMA (指数平滑移动平均线)的距离。

市场发展的趋势:应用于价格的 EMA(r) 用于确定价格的上升趋势(指数增长)或下滑趋势(指数下降)。

移动平均线会平滑价格曲线,但移动平均线周期的少许增长会导致延迟,且在价格反转点清晰可见(参见附加的 1.1.1 和图 1.2)。与趋势的平均偏差值会呈现出应用于价格的 EMA(r) 的距离。

与趋势的平均偏差标志会呈现出应用到价格的相对于 EMA(r) 的价格位置:与趋势的正偏差 - 价格高于指数;负偏差 - 价格低于指数。

与趋势平均偏差的公式

md(price,r) = price - EMA(price,r)

其中:

  • price - 当前周期的价格;
  • EMA (price,r) - 市场趋势 - 应用于价格的 r 周期 EMA。

参见“分析/技术指标/趋势指标”部分中的《客户端 MetaTrader 用户指南》:

  1. 双指数移动平均线,DEMA;
  2. 三指数移动平均线,TEMA。

Alexander Elder 在其“熊市力量指标”与“牛市力量指标”中使用了类似的指数。参见“分析/技术指标/摆动指标”部分中的《客户端 MetaTrader 用户指南》:

  1. 熊市力量;
  2. 牛市力量。

与趋势平均偏差指标(平均偏差指数,MDI) - 是一种与市场趋势的平滑平均偏差。

与趋势平均偏差指标的公式

MDI(price,r,s,u) = EMA(EMA( md(price,r) ,s),u) = EMA(EMA( price-EMA(price,r) ,s),u)

其中:

  • price - [收盘] 价 - 价格图表的价格基础;
  • EMA (price, r) - 市场趋势 - EMA(r) 第一次平滑,应用于价格;
  • md (price,r) = price-EMA (price,r) - 与趋势的平均偏差 - 与应用于价格的 EMA(r) 的价格偏差;
  • EMA (md (price, r), s) - 第二次平滑 - EMA(s),应用于与趋势的平均偏差;
  • EMA (EMA (md(price,r),s),u) - 第三次平滑 -EMA(u),应用于第二次平滑的结果。


3.1.1.3. MDI(price,r,s,u) - 平均偏差指数。规范

  • 文件名称Blau_MDI.mq5
  • 名称:依 William Blau,与市场平均偏差的指标(平均偏差;平滑平均偏差)。
  • 输入参数
    • r -应用于价格的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于平均偏差的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
  • 限制
    • r>1;
    • s>0, u>0。如果 s 或 u 等于 1,则不采用 EMA 平滑;
    • 价格数组的最小尺寸 = (r+s+u-3+1)。

 

3.1.2. 遍历 MDI 摆动指标

遍历 MDI 摆动指标的定义:
Ergodic_MDI(price,r,s,u) = MDI(price,r,s,u)
SignalLine(price,r,s,u,ul) = EMA( Ergodic_MDI(price,r,s,u) ,ul)

其中:

  • Ergodic_MDI() - 遍历 - 平均偏差指数 MDI(price,r,s,u);
  • SignalLine() - 信号线 - 应用于遍历的 ul 周期 EMA;
  • ul - EMA 信号线周期 - 根据 William Blau,ul 值必须等于 EMA 遍历最后一个有效周期 (>1)。


3.1.2.2. Ergodic_MDI(price,r,s,u,ul) - 遍历 MDI 摆动指标。规范

  • 文件名称Blau_Ergodic_MDI.mq5
  • 名称:依 William Blau 的遍历 MDI 摆动指标(基于平均偏差指数)。
  • 输入参数
    • 图形标绘 #0 - 遍历(与趋势平均偏差的指标):
      • r -应用于价格的第一次 EMA 的周期(默认 r = 20);
      • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
      • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • 图形标绘 #1 - 信号线:
      • ul - 周期 EMA 信号线,应用于遍历(默认 ul = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 每个图形结构渲染风格的更改 - 颜色、宽度、线型( "Colors" 选项卡)。
  • 限制
    • r>1;
    • s>0, u>0。如果 s 或 u 等于 1,则不采用 EMA 平滑;
    • ul>0。如果 ul = 1,则信号线与遍历线相同;
    • 价格数组的最小尺寸 = (r+s+u+ul-4+1)。

 

3.1.3. 遍历摆动指标的代码

作为示例,我们来研究研究 Ergodic_MDI (price,r,s,u,ul) 指标:

1) 指标数组、指标缓冲区与图形标绘之间的关联:

//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);              // Ergodic:u-周期 3rd EMA
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);            // 信号线:ul-周期 EMA,应用于Ergodic
   // 用于计算的中间过程的缓存;不是用来绘图的
   SetIndexBuffer(2,PriceBuffer,INDICATOR_CALCULATIONS);     // 价格数组
   SetIndexBuffer(3,EMA_PriceBuffer,INDICATOR_CALCULATIONS); // r-周期 1st EMA (价格)
   SetIndexBuffer(4,MDBuffer,INDICATOR_CALCULATIONS);        // 
   SetIndexBuffer(5,DEMA_MDBuffer,INDICATOR_CALCULATIONS);   // s-周期 2nd EMA

2) 平均偏差计算的算法:

//---计算标准偏差
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin2;              // 从0开始
      for(i=0;i<pos;i++)       // pos 数据
         MDBuffer[i]=0.0;      // 零值
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一个柱形
   // r-周期 1st EMA:计算EMA1_PriceBuffer[]
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin1,r,PriceBuffer,EMA_PriceBuffer);
   // 计算MDBuffer[]
   for(i=pos;i<rates_total;i++)
      MDBuffer[i]=PriceBuffer[i]-EMA_PriceBuffer[i];



3.2. 基于平滑/异同移动平均线的指标

图 3.2.William Blau 的指标基于平滑/异同移动平均线

图 3.2.William Blau 的指标基于平滑/异同移动平均线

 

3.2.1. 平滑/异同移动平均线的指标

平滑/异同移动平均线平滑/异同移动平均线,MACD) - 是两个指数平滑移动平均线之间的区别:应用于价格的快 EMA(s) 和慢 EMA(r)。

MACD 标志会显示快 EMA(s) 相对 EMA(r) 的位置:正 MACD - EMA(s) 在 EMA(r) 上方;负 MACD - EMA(s) 在 EMA(r) 下方。按绝对值更改 MACD:|MACD| 增长表明移动平均线之间有背离,而 |MACD| 下降则表明移动平均线之间有会聚。

平滑/异同移动平均线的公式:

macd(price,r,s) = EMA(price,s) - EMA(price,r)
s < r

其中:

  • price - 当前周期的价格 [收盘];
  • EMA(price,r) - 慢 EMA(r),应用于价格;
  • EMA(price,s) - 快 EMA(r),应用于价格。

MACD 指标会显示快慢指数平均线(平滑/异同移动平均线)之间的关系。

MACD 指标的公式

MACD(price,r,s,u) = EMA( macd(price,r,s) ,u) = EMA( EMA(price,s)-EMA(price,r) ,u)
s < r

其中:

  • price - [收盘] 价 - 价格图表的价格;
  • EMA (price,r) - 第一次平滑 - 应用于价格的 EMA(r) 慢指数;
  • EMA(price,s) - 第二次平滑 - 快 EMA(s),应用于价格;
  • macd(r,s)=EMA(price,s)-EMA (price,r) - MACD;
  • EMA(macd (r,s),u) - 第三次平滑 - 应用于 MACD 的 EMA(u):一个快 EMA (price,s) 和一个慢 EMA (price,r)。

3.2.1.1. MACD(price,r,s,u) - 平滑/异同移动平均线指标。规范

  • 文件名称Blau_MACD.mq5
  • 名称:依 William Blau 的 MACD 指标(MACD;平滑 MACD)。
  • 输入参数
    • r -应用于价格的第一次 EMA (慢) 的周期(默认 r = 20);
    • s - 应用于价格的第二次 EMA (快)的周期(默认 s = 5);
    • u - 应用于平滑/异同移动平均线的第三次 EMA 周期(默认 u = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
  • 限制
    • r>1, s>1;
    • s <r (受该理论要求限制,不在程序层面检查);
    • u>0。如果 u = 1,则不执行平滑。
    • 价格数组的最小尺寸 = ([max(r,s)]+u-2+1)。

 

3.2.2. 遍历 MACD 摆动指标

遍历 MACD 摆动指标的定义:
Ergodic_MACD(price,r,s,u) = MACD(price,r,s,u)
SignalLine(price,r,s,u,ul) = EMA( Ergodic_MACD(price,r,s,u) ,ul)

其中:

  • Ergodic_MACD () - 遍历 - 是平滑/异同移动平均线 MACD(price,r,s,u) 的一个指标;
  • SignalLine() - 信号线 - 应用于遍历的 EMA(ul);
  • ul - EMA 信号线周期 - 根据 William Blau,ul 必须等于 EMA 遍历最后一个有效周期 (>1)。

“分析/技术指标/摆动指标/MACD”部分的《MetaTrader 客户端用户指南》中,讲述的是内置于 MetaTrader 5 客户端中的平滑/异同移动平均线 (MACD),以及其在技术分析中的使用方式(亦见 iMACD。)

对比标准 MACD,William Blau 会采用指数平滑移动平均线(标准 MACD 中采用的是简单移动平均线)。

3.2.2.1. Ergodic_MACD(price,r,s,u,ul) - 遍历 MACD 摆动指标。规范

  • 文件名称Blau_Ergodic_MACD.mq5
  • 名称:依 William Blau 的遍历 MACD 摆动指标(基于平滑/异同移动平均线指标)。
  • 输入参数
    • 图形标绘 #0 - 遍历(平滑/异同移动平均线):
      • r -应用于价格的第一次 EMA (慢) 的周期(默认 r = 20);
      • s - 应用于价格的第二次 EMA (快)的周期(默认 s = 5)
      • u - 应用于平滑/异同移动平均线的第三次 EMA 周期(默认 u = 3);
    • 图形标绘 #1 - 信号线:
      • ul - 周期 EMA 信号线,应用于遍历(默认 ul = 3);
    • AppliedPrice - 价格类型(默认 AppliedPrice=PRICE_CLOSE)。
  • 此外
    • 于独立窗口中显示;
    • 每个图形结构渲染风格的更改 - 颜色、宽度、线型( "Colors" 选项卡)。
  • 限制
    • r>1, s>1;
    • s <r (受该理论要求限制,不在程序层面检查);
    • u>0。如果 u = 1,则不执行平滑。
    • ul>0。如果 ul = 1,则信号信与遍历一致;
    • 价格数组的最小尺寸 = ([max(r,s)]+u+ul-3+1)。

 

3.2.3. 遍历 MACD 摆动指标的代码

作为示例,我们来研究研究 Ergodic_MACD (price,r,s,u,ul) 指标:

1) 指标数组、指标缓冲区与图形标绘之间的关联:

//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);               // Ergodic:u-周期 3rd EMA
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);             // 信号线:ul-周期 EMA,应用于Ergodic
   //  缓存,用于计算的中间过程
   SetIndexBuffer(2,PriceBuffer,INDICATOR_CALCULATIONS);      // 价格数组
   SetIndexBuffer(3,EMA1_PriceBuffer,INDICATOR_CALCULATIONS); //  r - 1st EMA(慢速),应用于价格
   SetIndexBuffer(4,EMA2_PriceBuffer,INDICATOR_CALCULATIONS); // s - 2nd EMA(快速),应用于价格
   SetIndexBuffer(5,MACDBuffer,INDICATOR_CALCULATIONS);       // 移动平均的收敛/发散

2) 平滑/异同移动平均线的算法:

//--- 计算移动平均的收敛/发散
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin2;              // 
      for(i=0;i<pos;i++)       // pos
         MACDBuffer[i]=0.0;    // 零值
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   //  r-周期 1st EMA:计算EMA1_PriceBuffer[]
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin1,r,PriceBuffer,EMA1_PriceBuffer);
   // s-周期 2nd EMA: 计算EMA2_PriceBuffer[]
   ExponentialMAOnBufferWB(rates_total,prev_calculated,begin1,s,PriceBuffer,EMA2_PriceBuffer);
   // 计算MACDBuffer[]
   for(i=pos;i<rates_total;i++)
      MACDBuffer[i]=EMA2_PriceBuffer[i]-EMA1_PriceBuffer[i];


3.3. 增加

在根据 William Blau 计算 MDI 摆动指标与 MACD 摆动指标时,不能采用标准化(请参考页面1.2.1, 1.3.1). 因此,遍历 MDI 摆动指标与 MACD 摆动指标不能用于解释市场的超买或超卖程度

比如说,建议采用 “分析/技术指标/摆动指标/MACD”部分《MetaTrader 客户端用户指南》的 MACD 指标信息:

MACD 亦可用作一个超买/超卖指标。如果较短的移动平均线明显远离较长的移动平均线(即 MACD 升高),则很可能是安全价格过多放开,很快就会返回更加合理的水平。

本例中是通过技术分析的角度。


4. 烛形动量

将探讨过的指标(参见附件)划分为两个组。

  1. Blau_CMtm.mq5- 是烛形动量指标(q-周期烛形动量;平滑 q-周期烛形动量);
  2. 指数(标准化平滑 q-周期烛形动量):
    • Blau_CMI.mq5- 烛形动量指数(按 q-周期烛形动量的绝对值标准化);
    • Blau_CSI.mq5- 烛形指数(按 q-周期烛形长度标准化);
  3. 烛形的遍历摆动指标
    • Blau_Ergodic_CMI.mq5- 遍历 CMI 摆动指标(基于烛形动量指数);
    • Blau_Ergodic_CSI.mq5- 遍历 CSI 摆动指标(基于烛形指数)。

图 4.1.William Blau 基于烛形动量的指标(按 q-周期烛形动量绝对值标准化)

图 4.1.William Blau 基于烛形动量的指标(按 q-周期烛形动量绝对值标准化)

 

图 4.2.William Blau 基于烛形动量的指标(按 q-周期烛形的长度标准化)

图 4.2.William Blau 基于烛形动量的指标(按 q-周期烛形的长度标准化)

 

4.1. 烛形动量

4.1.1. 烛形动量的定义

动量(参阅段落 1.1) - 是当前价格(通常是今日收盘价)与之前价格(通常是昨天收盘价)之间的差别。该动量可以体现出价格图中任意时间周期的价格变动。

烛形动量(依 William Blau) - 是同一周期内(一个烛形内),收盘价与开盘价之间的差异。烛形动量的标志会指明价格变动的方向:正烛形动量 - 整个周期价格上涨;负烛形动量 - 整个周期价格下滑。

烛形动量的公式

cmtm = close - open

其中:

  • close - (烛形)[当前] 周期的收盘价;
  • open - (烛形)[当前] 周期的开盘价;

从通用性的角度考虑,我们来展开一下烛形动量的定义

  1. 烛形动量可以体现出价格图表中任意时间周期的价格变动;
  2. 价格基础(收盘价、开盘价)可任意设定。

图 4.3.q-周期烛形的定义

图 4.3.q 周期烛形的定义


q-周期烛形动量公式

cmtm(price1,price2,q) = price1 - price2[q-1]

其中:

  • q - 是烛形动量计算中用到的价格图表的柱数;
  • price1 - q 周期结束时的 [收盘] 价;
  • price2[q-1] - q 周期开始时的 [开盘] 价。

平滑 q-周期烛形动量公式

CMtm(price1,price2,q,r,s,u) = EMA(EMA(EMA( cmtm(price1,price2,q) ,r),s),u)

其中:

  • q - 是烛形动量 q-周期计算中用到的价格图表的柱数;
  • price1 - q 周期结束时的 [收盘] 价;
  • price2 - q 周期开始时的 [开盘] 价;
  • cmtm(price1,price2,q)=price1-price2[q-1] - q-周期烛形动量;
  • EMA (cmtm (price1, price2, q), r) - 第一次平滑 - EMA(r),应用于 q-周期烛形动量;
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(u)。


4.1.2. CMtm(price1,price2,q,r,s,u) - 烛形动量指标。规范
  • 文件名称Blau_CMtm.mq5
  • 名称:依 William Blau,烛形动量指标(平滑 q-周期烛形动量)。
  • 输入参数
    • q - 烛形动量的周期(默认 q = 1);
    • r -应用于 q-周期烛形动量的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • +u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice1 - 价格类型 [收盘] (默认 AppliedPrice=PRICE_CLOSE)。
    • AppliedPrice2 - 价格类型 [开盘] (默认 AppliedPrice=PRICE_OPEN)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则不采用 EMA 平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。


4.2. 标准化烛形动量

4.2.1. 烛形动量指数

烛形动量指数 (CMI) - 是指标准化 q-周期烛形动量。

平滑 q-周期烛形动量的值作为一个百分比给出(映射区间 [-100, 100])。q-周期烛形平滑动量的每个值,均按平滑 q-周期烛形动量的值标准化,取绝对值。标准化允许将 CMI 值解释为市场超买(正值)或超卖(负值)的程度。

烛形动量指数的公式

                             100 * EMA(EMA(EMA( cmtm(price1,pric2,q) ,r),s),u)          100 * CMtm(price1,pric2,q,r,s,u)
CMI(price1,price2,q,r,s,u) = –––––––––––-------------––––––––-–––––––––––––––– = –––––––––––––––-------------–––-–––––––––––––
                               EMA(EMA(EMA( |cmtm(price1,pric2,q)| ,r),s),u)     EMA(EMA(EMA( |cmtm(price1,pric2,q)| ,r),s),u)
if EMA(EMA(EMA(|cmtm(price1,pric2,q)|,r),s),u)=0, then CMI(price1,price2,q,r,s,u)=0

其中:

  • q - 烛形 q-周期动量计算过程中涉及到的价格图的时间周期数量;
  • price1 - q 周期结束时的 [收盘] 价;
  • price2 - q 周期开始时的 [开盘] 价;
  • cmtm(price1,pric2,q)=price1-pric2[q-1], - q-周期烛形动量;
  • |cmtm(price1,pric2,q)| - q-周期烛形动量的绝对值;
  • CMtm (price,q,r,s,u) - 三次平滑 q-周期烛形动量;
  • EMA (..., r) - 第一次平滑 - EMA(r),应用于
    1) q-周期烛形动量
    2) q-周期烛形动量的绝对值;
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(u)。


4.2.1.1. CMI(price1,price2,q,r,s,u) - 烛形动量指数。规范

  • 文件名称Blau_CMI.mq5
  • 名称:依 William Blau 的 q-周期烛形动量指数(标准化平滑 q-周期烛形动量;按 q-周期烛形动量绝对值标准化)。
  • 输入参数
    • q - 烛形动量的周期(默认 q = 1);
    • r -应用于 q-周期烛形动量的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice1 - 价格类型 [收盘] (默认 AppliedPrice=PRICE_CLOSE)。
    • AppliedPrice2 - 价格类型 [开盘] (默认 AppliedPrice=PRICE_OPEN)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
    • (可选)两级(默认为 -25 和 +25) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

4.2.2. 烛形指数

烛形指数 (CSI) - 是标准化 q-周期烛形动量(标准化平滑 q-周期烛形动量)标准化的一个指标。平滑 q-周期烛形动量的值作为一个标度百分比给出(映射区间 [-100, 100])。

平滑 q-周期烛形动量的每个值,都按 q-周期价格范围(或按 q-周期烛形的长度)的值标准化。标准化允许将 CSI 值解释为市场超买(正值)或超卖(负值)的程度。

烛形指数的公式

                             100 * EMA(EMA(EMA( cmtm(price1,pric2,q) ,r),s),u)    100 * CMtm(price1,pric2,q,r,s,u)
CSI(price1,price2,q,r,s,u) = –––––––––––––––––––-–––-------------––––––––––––– = ––––––––––––––––--––-–––––––––––––
                                    EMA(EMA(EMA( HH(q)-LL(q) ,r),s),u)           EMA(EMA(EMA( HH(q)-LL(q) ,r),s),u)
if EMA(EMA(EMA(HH(q)-LL(q),r),s),u)=0, then CSI(price1,price2,q,r,s,u)=0

其中:

  • q - 是烛形动量 q-周期计算中用到的价格图表的柱数;
  • price1 - q 周期结束时的 [收盘] 价;
  • price2 - q 周期开始时的 [开盘] 价;
  • cmtm(price1,pric2,q)=price1-price2[q-1] - q-周期烛形动量;
  • LL (q) - q 周期最低价格的最小值;
  • HH(q) - q 周期最高价格的最高值
  • HH(q)-LL(q) - q-周期价格范围(q-周期烛形的长度);
  • CMtm(price1,pric2,q,r,s,u) - 三次平滑 q-周期烛形动量;
  • EMA (..., r) - 第一次平滑 - EMA(r),应用于
    1) q-周期烛形动量
    2) q-周期价格范围(或 q-周期烛形的长度);
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(s)。

4.2.2.1. CSI(price1,price2,q,r,s,u) - 烛形指数。规范

  • 文件名称Blau_CSI.mq5
  • 名称:依 William Blau 的 q-周期烛形指数(标准化平滑 q-周期烛形动量;按 q-周期烛形长度标准化)。
  • 输入参数
    • q - q-周期烛形动量指标计算的周期(默认 q = 1);
    • r -应用于 q-周期烛形动量的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • AppliedPrice1 - 价格类型 [收盘] (默认 AppliedPrice=PRICE_CLOSE)。
    • AppliedPrice2 - 价格类型 [开盘] (默认 AppliedPrice=PRICE_OPEN)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
    • (可选)两级(默认为 -25 和 +25) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则不采用 EMA 平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

4.3. 烛形的遍历摆动指标

4.3.1. 遍历 CMI 摆动指标

遍历 CMI 摆动指标的定义:
Ergodic_CMI(price1,pric2,q,r,s,u) = CMI(price1,pric2,q,r,s,u)
SignalLine(price1,pric2,q,r,s,u,ul) = EMA( Ergodic_CMI(price1,pric2,q,r,s,u) ,ul)

其中:

  • Ergodic_CMI() - 遍历 - 烛形动量指数 CMI(price1,price2,q,r,s,u);
  • SignalLine() - 信号线 - 应用于遍历的 EMA(ul);
  • ul - EMA 信号线周期 - 根据 William Blau,ul 必须等于 EMA 遍历最后一个有效周期 (>1)。

Ergodic_CMI(price1,pric2,q,r,s,u,ul) - 遍历 CMI 摆动指标。规范

  • 文件名称Blau_Ergodic_CMI.mq5
  • 名称:依 William Blau 的遍历 CMI 摆动指标(基于烛形动量指数)。
  • 输入参数
    • 图形标绘 #0 - 遍历(烛形动量指数):
      • q - 烛形动量的周期(默认 q = 1);
      • r -应用于 q-周期烛形动量的第一次 EMA 的周期(默认 r = 20);
      • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
      • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • 图形标绘 #1 - 信号线:
      • ul - 应用于遍历的信号线周期(默认 ul = 3);
    • AppliedPrice1 - 价格类型 [收盘] (默认 AppliedPrice=PRICE_CLOSE)。
    • AppliedPrice2 - 价格类型 [开盘] (默认 AppliedPrice=PRICE_OPEN)。
  • 此外
    • 于独立窗口中显示;
    • 每个图形标绘渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡);
    • 两级(默认为 -25 和 +25) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • ul>0。如果 ul = 1,则信号信与遍历一致;
    • 价格数组最小尺寸 = (q-1 + r + s + u + ul-4 +1)。


遍历 CMI 摆动指标的代码:


作为示例,我们来研究研究 Ergodic_CMI (price1,price2,r,s,u,ul) 指标:

1) 指标数组、指标缓冲区与图形标绘之间的关联:

//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);                  // Ergodic
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);                // 信号线: EMA(ul),应用于Ergodic
   //  缓存,用于计算的中间过程
   SetIndexBuffer(2,Price1Buffer,INDICATOR_CALCULATIONS);        // 价格数组【收盘价】
   SetIndexBuffer(3,Price2Buffer,INDICATOR_CALCULATIONS);        // 价格数组【开盘价】
   SetIndexBuffer(4,CMtmBuffer,INDICATOR_CALCULATIONS);          // q-周期 蜡烛线动量
   SetIndexBuffer(5,EMA_CMtmBuffer,INDICATOR_CALCULATIONS);      // r-周期 1st EMA
   SetIndexBuffer(6,DEMA_CMtmBuffer,INDICATOR_CALCULATIONS);     // s-周期 2nd EMA
   SetIndexBuffer(7,TEMA_CMtmBuffer,INDICATOR_CALCULATIONS);     // u-周期 3rd EMA
   SetIndexBuffer(8,AbsCMtmBuffer,INDICATOR_CALCULATIONS);       // q-周期蜡烛线动量(绝对值)
   SetIndexBuffer(9,EMA_AbsCMtmBuffer,INDICATOR_CALCULATIONS);   //r-周期1st EMA(绝对值)
   SetIndexBuffer(10,DEMA_AbsCMtmBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA(绝对值)
   SetIndexBuffer(11,TEMA_AbsCMtmBuffer,INDICATOR_CALCULATIONS); // u-周期 3rd EMA (绝对值)

2) 计算 cmtm 与 |cmtm| 的算法:

//--- 计算Price1Buffer[] 和 Price2Buffer[]
   CalculatePriceBuffer(
                        AppliedPrice1,       // 应用的价格【收盘价】
                        rates_total,         // 所有柱形数量
                        prev_calculated,     // 前一次调用时计算的柱形编号
                        Open,High,Low,Close, // Open[], High[], Low[], Close[]
                        Price1Buffer         // 目标数组
                       );
   CalculatePriceBuffer(AppliedPrice2,rates_total,prev_calculated,Open,High,Low,Close,Price2Buffer);
//--- 计算 cmtm 和 |cmtm|
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin1;              // 
      for(i=0;i<pos;i++)       // 
        {
         CMtmBuffer[i]=0.0;    // 零值
         AbsCMtmBuffer[i]=0.0; //
        
}
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   // 计算CMtmBuffer[] and AbsCMtmBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      CMtmBuffer[i]=Price1Buffer[i]-Price2Buffer[i-(q-1)];
      AbsCMtmBuffer[i]=MathAbs(CMtmBuffer[i]);
     
}


4.3.2. 遍历 CSI 摆动指标

遍历 CSI 摆动指标定义如下:

Ergodic_CSI(price1,pric2,q,r,s,u) = CSI(price1,pric2,q,r,s,u)
SignalLine(price1,pric2,q,r,s,u,ul) = EMA( Ergodic_CSI(price1,pric2,q,r,s,u) ,ul)

其中:

  • Ergodic_CSI() - 遍历 - 烛形指数 CSI(price1,price2,q,r,s,u);
  • SignalLine() - 信号线 - 应用于遍历的 EMA(ul);
  • ul - EMA 信号线周期 - 根据 William Blau,ul 值必须等于 EMA 遍历最后一个有效周期 (>1)。


4.3.2.1. Ergodic_CSI(price1,pric2,q,r,s,u,ul) - 遍历 CSI 摆动指标。规范

  • 文件名称Blau_Ergodic_CSI.mq5
  • 名称:依 William Blau 的遍历 CSI 摆动指标(基于烛形指数)。
  • 输入参数
    • 图形标绘 #0 - 遍历(烛形指数):
      • q - q-周期烛形动量指标计算的周期(默认 q = 1);
      • r -应用于 q-周期烛形动量的第一次 EMA 的周期(默认 r = 20);
      • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
      • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • 图形标绘 #1 - 信号线:
      • ul - 周期 EMA 信号线,应用于遍历(默认 ul = 3);
    • AppliedPrice1 - 价格类型 [收盘] (默认 AppliedPrice=PRICE_CLOSE)。
    • AppliedPrice2 - 价格类型 [开盘] (默认 AppliedPrice=PRICE_OPEN)。
  • 此外
    • 于独立窗口中显示;
    • 每个图形标绘渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡);
    • 两级(默认为 -25 和 +25) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • ul>0。如果 ul = 1,则信号信与遍历一致;
    • 价格数组最小尺寸 = (q-1 + r + s + u + ul-4 +1)。


4.3.2.2. 遍历 CSI 摆动指标的代码:


基于 Ergodic_CSI (price1, price2,r,s,u,ul) 指标示例:

1) 指标数组、指标缓冲区与图形标绘之间的关联:

//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);               // Ergodic
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);             // 信号线: EMA(ul),应用于Ergodic
   // 缓存,用于计算的中间过程
   SetIndexBuffer(2,Price1Buffer,INDICATOR_CALCULATIONS);     // 价格数组【收盘价】
   SetIndexBuffer(3,Price2Buffer,INDICATOR_CALCULATIONS);     // 价格数组【开盘价】
   SetIndexBuffer(4,LLBuffer,INDICATOR_CALCULATIONS);         // 最低价(q个柱形)
   SetIndexBuffer(5,HHBuffer,INDICATOR_CALCULATIONS);         // 最高价(q个柱形)
   SetIndexBuffer(6,CMtmBuffer,INDICATOR_CALCULATIONS);       // q-周期 蜡烛线动量
   SetIndexBuffer(7,EMA_CMtmBuffer,INDICATOR_CALCULATIONS);   // r-周期 1st EMA
   SetIndexBuffer(8,DEMA_CMtmBuffer,INDICATOR_CALCULATIONS);  // s-周期 2nd EMA
   SetIndexBuffer(9,TEMA_CMtmBuffer,INDICATOR_CALCULATIONS);  // u-周期 3rd EMA
   SetIndexBuffer(10,HHLLBuffer,INDICATOR_CALCULATIONS);      // 价格范围(q个柱形)
   SetIndexBuffer(11,EMA_HHLLBuffer,INDICATOR_CALCULATIONS);  // r-周期 1st EMA (价格范围)
   SetIndexBuffer(12,DEMA_HHLLBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA(价格范围)
   SetIndexBuffer(13,TEMA_HHLLBuffer,INDICATOR_CALCULATIONS); //  u-周期 3rd EMA(价格范围)

2) cmtm 与 q-周期价格范围计算的算法:

//--- 计算Price1Buffer[] 和 Price2Buffer[]
   CalculatePriceBuffer(
                        AppliedPrice1,       // 价格类型【收盘价格】
                        rates_total,         // 所有柱形数量
                        prev_calculated,     // 前一次调用时计算的柱形编号
                        Open,High,Low,Close, // Open[], High[], Low[], Close[]
                        Price1Buffer         // 目标数组
                       );
   CalculatePriceBuffer(AppliedPrice2,rates_total,prev_calculated,Open,High,Low,Close,Price2Buffer);
//--- 计算cmtm 和 价格范围(q个柱形)
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin1;              // 
      for(i=0;i<pos;i++)       // 
        {
         CMtmBuffer[i]=0.0;    // 零值
         HHLLBuffer[i]=0.0;    //
         LLBuffer[i]=0.0;      //
         HHBuffer[i]=0.0;      //
        
}
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   // 计算CMtmBuffer[], HHLLBuffer[], LLBuffer[], HHBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      // CMtmBuffer[] - q-周期蜡烛线动量
      CMtmBuffer[i]=Price1Buffer[i]-Price2Buffer[i-(q-1)];
      // LLBuffer[] - 搜索最低价(q个柱形)
      // HHBuffer[] - 搜索最高价(q个柱形)
      min=1000000.0;
      max=-1000000.0;
      for(k=i-(q-1);k<=i;k++)
        {
         if(min>Low[k])  min=Low[k];
         if(max<High[k]) max=High[k];
        
}
      LLBuffer[i]=min;
      HHBuffer[i]=max;
      // HHLLBuffer[] - 价格范围(q个柱形)
      HHLLBuffer[i]=HHBuffer[i]-LLBuffer[i];
     
}

5. 方向趋势

要探讨的指标(参见附件):

  1. Blau_HLM.mq5- 是一个虚拟平仓指标(q-周期复合高低动量;平滑 q-周期复合高低动量);
  2. Blau_DTI.mq5- 方向趋势指数(标准化平滑 q-周期复合高低动量);
  3. Blau_Ergodic_DTI.mq5- 遍历 DTI 摆动指标(基于方向趋势指数)。

图 5.1.方向趋势指数指标

图 5.1.方向趋势指数指标

 

5.1. 复合高低动量

5.1.1. 上涨趋势与下降趋势动量的定义

趋势定义之一。 如果最高价格的值有增长,则有一个上涨趋势。如果最低价格的值有下降,则有一个下降趋势

第 1 部分中讨论过的一组动量指标,则可被用于计算价格最大值动量:

Mtm( price=High, q, r, s, u )
TSI( price=High, q, r, s, u )
Ergodic( price=High, q, r, s, u )

亦可用于最低价格的计算:

Mtm( price=Low, q, r, s, u )
TSI( price=Low, q, r, s, u )
Ergodic( price=Low, q, r, s, u )

上涨趋势动量高动量上行  (HMU) 是当前周期最高价格与 q-周期价格范围开头最高价格之间的差异。q-周期上涨趋势动量的值,会呈现当前周期最高价格对比 q-周期价格波动范围开头最高价格的相对增长速率。

q-周期上涨趋势动量公式

HMU(q) = High - High[q-1], if High - High[q-1] > 0
HMU(q) = 0, if High - High[q-1] <= 0

其中:

  • q - 上涨趋势动量计算中涉及到的价格图表时间周期的数量;
  • High - 当前周期的最高价格;
  • High[q–1] - (q-1) 周期以前的最高价格。

下降趋势动量低动量下行  (LMD) 是当前周期最低价格与 q-周期价格波动范围开头最低价格之间的差异。q-周期下降趋势动量的值,会呈现当前周期最低价格对比 q-周期价格范围开头最低价格的相对下降速率。

q-周期下降趋势动量公式

LMD(q) = -(Low - Low[q-1]), if Low - Low[q-1] < 0
LMD(q) = 0, if Low - Low[q-1] >= 0

其中:

  • q - 下降趋势动量计算中涉及到的价格图表时间周期的数量;
  • Low - 当前周期的最低价格;
  • Low[q-1] - (q-1) 周期以前的最低价格。

复合高低动量(高低动量,HLM) - 是 q-周期上涨趋势动量与 q-周期下降趋势动量之间的差异。复合高低动量的标志表明价格变动的趋势:正 HLM - 价格增长趋势(上涨趋势);而负 HLM - 则是价格降低趋势(下降趋势)。

公式

HLM(q) = HMU(q) - LMD(q)

其中:

  • q - 上涨趋势与下降趋势动量计算中涉及到的价格图表时间周期的数量;
  • HMU(q) - q 周期上涨趋势动量;
  • LMD(q) - q 周期下降趋势动量。

q-周期复合高低动量公式(虚拟平仓):

HLM(q,r,s,u) = EMA(EMA(EMA( HLM(q) ,r),s),u) = EMA(EMA(EMA( HMU(q)-HMD(q) ,r),s),u)

其中:

  • q - 上涨趋势与下降趋势动量计算中涉及到的价格图表时间周期的数量;
  • HMU(q) - q 周期上涨趋势动量;
  • LMD(q) - q 周期下降趋势动量;
  • HLM(q) = HMU(q)-LMD(q) - q-周期复合高低动量;
  • EMA (HLM (q), r) - 第一次平滑 - 应用于 q-周期复合高低动量的 EMA(r);
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s)
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(u)。

最大值与最小值复杂动量的累积和的曲线图,被称为虚拟平仓


5.1.2. HLM(q,r,s,u) - 虚拟平仓指标。规范
  • 文件名称Blau_HLM.mq5
  • 名称:依 William Blau 的虚拟平仓指标(q-周期复合高低动量;平滑 q-周期复合高低动量)。
  • 输入参数
    • q - HLM 计算的周期(默认 q = 2);
    • r -应用于 HLM 的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

5.2. 方向趋势指数

5.2.1. “方向趋势指数”的定义

方向趋势指数(方向趋势指数,DTI) - 是标准化 q-周期复合高低动量(标准化平滑 HLM)的一个指标。平滑 HLM 的值作为一个标度百分比给出(显示区间 [-100, 100])。

平滑 HLM 的每个值都按某平滑 HLM 的值进行标准化,取绝对值。标准化允许将 DTI 值解释为市场超买(正值)或超卖(负值)的程度。

方向趋势指数的公式

               100 * EMA(EMA(EMA( HLM(q) ,r),s),u)          100 * HLM(q,r,s,u)
DTI(q,r,s,u) = –––––––––––––––––––––––––---––––––– = ––––––––––––––--–––––––––––––––
                 EMA(EMA(EMA( |HLM(q)| ,r),s),u)     EMA(EMA(EMA( |HLM(q)| ,r),s),u)
if EMA(EMA(EMA(|HLM(q)|,r),s),u)=0, then DTI(price,q,r,s,u)=0

其中:

  • q - 上涨趋势与下降趋势动量计算中涉及到的价格图表时间周期的数量;
  • HLM(q) = HMU(q)-LMD(q) - q-周期最大值与最小值的复合;
  • |HLM(q)| - 绝对值 HLM(q);
  • HLM(q,r,s,u) - 三次平滑 HLM(q);
  • EMA (..., r) - 第一次平滑 - EMA(r),应用于
    1) HLM (q)
    2) HLM (q) 绝对值;
  • EMA (EMA(..., r),s) - 第二次平滑 - 应用于第一次平滑结果的 EMA(s);
  • EMA (EMA (EMA (..., r), s), u) - 第三次平滑 - 应用于第二次平滑结果的 EMA(s)。
5.2.2. DTI(q,r,s,u) - 方向趋势指数。规范
  • 文件名称Blau_DTI.mq5
  • 名称:依 William Blau 的方向趋势指数(标准化平滑 q-周期复合高低动量)。
  • 输入参数
    • q - HLM 计算的周期(默认 q = 2);
    • r -应用于 HLM 的第一次 EMA 的周期(默认 r = 20);
    • s - 应用于第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
    • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3)。
  • 此外
    • 于独立窗口中显示;
    • 图形绘制渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡)。
    • (可选)两级(默认为 -25 和 +25) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则在对应的 EMA 周期中,不会执行平滑;
    • 价格数组最小尺寸 = (q-1 + r + s + u-3 +1)。

 

5.3. 遍历 DTI 摆动指标

5.3.1. 遍历 DTI 摆动指标的定义:

Ergodic_DTI(q,r,s,u) = DTI(q,r,s,u)
SignalLine(q,r,s,u,ul) = EMA( Ergodic_DTI(q,r,s,u) ,ul)

其中:

  • Ergodic_DTI() - 遍历 - 方向趋势指数 DTI(q,r,s,u);
  • SignalLine() - 信号线 - 应用于遍历的 ul 周期指数移动平均线;
  • ul - EMA 信号线周期 - 根据 William Blau,ul 值必须等于 EMA 遍历最后一个有效周期 (>1)。
5.3.2. Ergodic_DTI(q,r,s,u,ul) - 遍历 DTI 摆动指标。规范
  • 文件名称Blau_Ergodic_DTI.mq5
  • 名称:依 William Blau 的遍历 DTI 摆动指标(基于方向趋势指数)。
  • 输入参数
    • 图形标绘 #0 - 遍历(方向趋势指数):
      • q - HLM 计算的周期(默认 q = 2);
      • r - 就 HLM 的第一次 EMA 的周期(默认 r = 20);
      • s - 就第一次平滑结果的第二次 EMA 的周期(默认 s = 5);
      • u - 应用于第二次平滑结果的第三次 EMA 的周期(默认 u = 3);
    • 图形结构 #1 - 信号线:
      • ul - 周期 EMA 信号线,应用于遍历(默认 ul = 3);
  • 此外
    • 于独立窗口中显示;
    • 每个图形标绘渲染风格的更改 - 颜色、粗细、线型( "Colors" 选项卡);
    • 两级(默认为 -25 和 +25) - 添加/移除某级别;更改值、级别描述,更改级别的渲染风格("Levels" 选项卡);
    • 更改单指标窗口标度的下限(默认 -100)和上限(默认 100)("Scale" 选项卡)。
  • 限制
    • q>0;
    • r>0, s>0, u>0。如果 r, s 或 u 等于 1,则不采用 EMA 平滑;
    • ul>0。如果 ul = 1,则信号信与遍历一致;
    • 价格数组最小尺寸 = (q-1 + r + s + u + ul-4 +1)。


5.4. 遍历 DTI 摆动指标的代码

Ergodic_DTI (q,r,s,u,ul) 指标:

1) 指标数组、指标缓冲区与图形标绘之间的关联:

//--- 指标缓存
   // 绘制 #0图形
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);                 // Ergodic 线
   // 绘制 #1图形
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);               // 信号线: EMA(ul),应用于Ergodic
   // 缓存,用于计算的中间过程
   SetIndexBuffer(2,HMUBuffer,INDICATOR_CALCULATIONS);          // q-周期的上升趋势动量
   SetIndexBuffer(3,LMDBuffer,INDICATOR_CALCULATIONS);          // q-周期的下降趋势动量
   SetIndexBuffer(4,HLMBuffer,INDICATOR_CALCULATIONS);          // 综合q-周期高/低动量
   SetIndexBuffer(5,EMA_HLMBuffer,INDICATOR_CALCULATIONS);      // r-周期 1st EMA
   SetIndexBuffer(6,DEMA_HLMBuffer,INDICATOR_CALCULATIONS);     // s-周期 2nd EMA
   SetIndexBuffer(7,TEMA_HLMBuffer,INDICATOR_CALCULATIONS);     // u-周期 3rd EMA
   SetIndexBuffer(8,AbsHLMBuffer,INDICATOR_CALCULATIONS);       //  综合q-周期高/低动量(绝对值)
   SetIndexBuffer(9,EMA_AbsHLMBuffer,INDICATOR_CALCULATIONS);   // r-周期1st EMA(绝对值)
   SetIndexBuffer(10,DEMA_AbsHLMBuffer,INDICATOR_CALCULATIONS); // s-周期 2nd EMA(绝对值)
   SetIndexBuffer(11,TEMA_AbsHLMBuffer,INDICATOR_CALCULATIONS); //  u-周期 3rd EMA (绝对值)

2) 计算 HLM 与 |HML| 的算法:

//--- 计算 HLM 和 |HLM|
   if(prev_calculated==0)      // 首次调用
     {
      pos=begin1;              // 
      for(i=0;i<pos;i++)       // 
        {
         HLMBuffer[i]=0.0;     // 零值
         AbsHLMBuffer[i]=0.0;  //
         HMUBuffer[i]=0.0;     //
         LMDBuffer[i]=0.0;     //
        
}
     
}
   else pos=prev_calculated-1; // 否则仅计算最近一次的值
   // 计算HLMBuffer[], AbsHLMBuffer[], HMUBuffer[], LMDBuffer[]
   for(i=pos;i<rates_total;i++)
     {
      HMUBuffer[i]=High[i]-High[i-(q-1)];    HMUBuffer[i]=(HMUBuffer[i]>0)?HMUBuffer[i]:0;
      LMDBuffer[i]=-1*(Low[i]-Low[i-(q-1)]); LMDBuffer[i]=(LMDBuffer[i]>0)?LMDBuffer[i]:0;
      HLMBuffer[i]=HMUBuffer[i]-LMDBuffer[i];
      AbsHLMBuffer[i]=MathAbs(HLMBuffer[i]);
     
}


总结

《William Blau 的 MQL5 中的指标与交易系统。第一部分:指标》,是对 MQL5 中开发指标与摆动指标的描述,详见 William Blau 下述书中内容 《动量、方向和背离》

而上述指标与摆动指标在制定交易决策过程中的使用,则会于《William Blau 的 MQL5 中的指标与交易系统。第二部分:交易系统》中讲到。

 

本文随附档案 ("Blau_Indicators_MQL5_en.zip") 的目录:

文件 说明
包含文件。位置:"terminal_data_folder\MQL5\Include"
 WilliamBlau.mqh  
指标。位置:"terminal_data_folder\MQL5\Indicators"
   基于动量的指标
Blau_Mtm.mq5  动量指标 (q-周期动量、平滑 q-周期动量)
Blau_TSI.mq5  真实强弱指数 (标准化平滑 q-周期动量)
Blau_Ergodic.mq5  遍历摆动指标 (基于真实强弱指数)
   基于随机的指标
Blau_TStoch.mq5  随机指标 (q-周期随机指标、平滑 q-周期随机指标)
Blau_TStochI.mq5  随机指数 (标准化平滑 q-周期随机指标)
Blau_TS_Stochastic.mq5  随机 TS 摆动指标 (基于随机指数)
   基于随机动量的指标
Blau_SM.mq5  随机动量 (q-周期随机动量,平滑 q-周期随机动量)
Blau_SMI.mq5  随机动量指数(平滑标准化 q-周期随机动量 RSI)
Blau_SM_Stochastic.mq5  随机 SM 摆动指标 (基于随机动量指数)
   基于市场趋势偏差的指标
Blau_MDI.mq5  平均偏差指标 (平均偏差、平滑平均偏差)
Blau_Ergodic_MDI.mq5  遍历 MDI 摆动指标 (基于平均偏差指标)
   基于平滑/异同移动平均线的指标
Blau_MACD.mq5  平滑/异同移动平均线指标 (MACD,平滑 MACD)
Blau_Ergodic_MACD.mq5  遍历 MACD 摆动指标 (基于 MACD 指标)
   基于烛形动量的指标
Blau_CMtm.mq5  烛形动量指标 (q-周期烛形动量、平滑 q-周期烛形动量)
Blau_CMI.mq5  烛形动量指数 (标准化平滑 q-周期烛形动量;按 q-周期烛形动量绝对值的标准化)
Blau_CSI.mq5  烛形指数 (标准化平滑 q-周期烛形动量;按 q-周期烛形烛形长度的标准化)
Blau_Ergodic_CMI.mq5  遍历 CMI 摆动指标 (基于烛形动量指数)
Blau_Ergodic_CSI.mq5  遍历 CSI 摆动指标 (基于烛形指数)
   基于复合动量的指标
Blau_HLM.mq5  虚拟平仓指标 (q-周期复合高低动量;平滑 q-周期复合高低动量)
Blau_DTI.mq5 方向趋势指数 (标准化平滑 q-周期复合高低动量)
Blau_Ergodic_DTI.mq5  遍历 DTI 摆动指标 (基于方向趋势指数)

本文译自 MetaQuotes Software Corp. 撰写的俄文原文
原文地址: https://www.mql5.com/ru/articles/190

附加的文件 |
分析指标统计参数 分析指标统计参数

这种技术分析广泛应用于各个指标,从而更清楚地显示基本报价,并允许交易者执行分析和预测市场价格变动。非常明显,除非我们可以解决初始报价转换以及所得结果可信度的相关问题,否则使用这些指标没什么意义,更不用说将其应用于交易系统的创建了。我们会在本文中讲述,得出这样一个结论,是经过严格推理的。

利用指数平滑法进行时间序列预测 利用指数平滑法进行时间序列预测

本文旨在让读者熟悉用于时间序列短期预测的指数平滑模型,此外还会探讨预测结果优化与评估相关的各种问题,并提供若干脚本与指标示例。当您首次接触基于指数平滑模型的预测原则时,阅读本文定会有所收益。

最新的改革 最新的改革

看一看您的交易终端。您能看到哪些价格展示方式?柱、烛形图和线条。我们追求的是时间和价格,但却只能由价格获利。那么,分析市场时,我们能否只关注价格呢?本文会针对点数图("圈圈叉叉")提出一种算法和脚本 - 已将各种各样的价格模式考虑在内,而其实际应用亦于提供的建议中列出。

基于交易模块创建多个 EA 交易 基于交易模块创建多个 EA 交易

在 MQL5 中使用面向对象方法这一做法,极大简化了多币种/多系统/多时间表 EA 交易的创建过程。不妨想象一下单个 EA 交易采用多个交易策略、使用一切可用工具以及利用所有可能的时间表进行交易的情形!此外,EA 交易还方便使用测试程序进行测试,并且对于所有策略而言,该交易包含了一个或多个资金管理工作系统。