MQL指标:MACD

来源:互联网 发布:安卓版数据恢复软件 编辑:程序博客网 时间:2024/05/16 12:30

MACD 简介

MACD,Moving Average Convergence / Divergence,中文译名“指数平滑异同平均线”。

Moving Average 很好理解,一个区间内的价格平均数,由于区间随时间平移,因此有了一个形象的名字“Moving Average”(移动平均线)。

关于算均值的方法有若干个。

  • Simple Moving Average(简单移动平均):即算术平均数
  • Exponential Moving Average (指数平均数)
    指数平均数公式 Avgt=αPricet+(1α)Avgt1
    α 是“平滑指数”,一般取2N+1
    本质上是一种加权平均,最新的价格的权值为2N+1

其他的平均线就暂且不提

这个名字不是很好理解,Convergence是聚合度,Divergence是散度。

用”/”这个符号可以解释成“或”

Convergence or Divergence。

聚合或离散,比起“异同”这样一个状态词,Convergence与Divergence更应该是表示变化的过程。

MACD 算法

MACD要依次计算五个时间序列:
+ 短周期指数均线 FMA (快线,一般周期取12)
+ 长周期指数均线 SMA (慢线,一般周期取26)
+ 快慢均线之差DIFF(DIFF = FMA - SMA)
+ DIFF的指数平均线DMA(一般周期取9)
+ DIF与DEA之差MACD

网上有所谓“双线MACD”的说法,其实就是将DIFF、DEMA画成线,MACD画成柱的做法。

MT5中自带一个“(单线)MACD”的指标,其做法与大众做法不一致,它将DIFF画成柱状图,DIFF使用简单算术平均处理成DMA。尽管走了非主流的路线,但思想是没有问题的:首先,DIFF是柱状图还是连线图并没有本质区别;其次,指数平均线与算术平均线没有绝对的正误之分,都是移动平均线;最后,将MACD显式计算为两者之差 与描述DIF与DMA的金叉死叉是类似的事情。主要还是看习惯

浅析 MACD

快慢均线之差 DIFF 是为了代替快慢均线的金叉死叉分析。

因为两线的金叉死叉有时候是不符合直觉的,不是那么自然。

通常有一种方法:计算两线之差DIFF,将FMA、SMA金叉死叉转化为DIFF是正是负的问题。

快均线FMA对价格的变化比SMA更敏感。

当价格上行时,FMA的上升幅度大于SMA,当FMA自下而上击穿SMA(金叉)时,表示上升趋势的开始,此时,DIFF=FMA-SMA为正。

反之,当价格下行时,FMA的下降幅度大于SMA,当FMA自上而下击穿SMA(死叉)时,表示下降趋势的开始,此时,DIFF=FMA-SMA为负。

所以,DIFF是可以描述金叉死叉的,本质上是价格的变化率。

有趣的是,数学中微分(Differential)与差(DIFF)同源,意思是一样的。微分一开始还是描述一些物理概念的,如速度、加速度等。 MA作为价格的均值,其量纲与价格相同;则DIFF则一定程度上描述了价格的变化率。因此,总体呈上行态时,DIFF为正;总体呈下形态时,DIFF为负。理论上来说,SMA、FMA的周期越小,DIFF越接近“瞬时速度”,对于价格变动越是敏感,可以达到无限接近、无限敏感。然而现实是,因为相对论因果律的作用,均线总是滞后于价格,所以无论怎么接近真实价格的变动速度,也不可能超越价格变动。

DMA是DIFF的均线,本质上是价格变化率的均值,结合其固定的周期,代表的意义是“实际变化的价格”,即在周期区间内,价格变化的量。当价格在周期内总体上升时,DMA为正;反之为负。

从量纲上看 DMA与DIFF是一致的,性质是一致的,DMA的值域一定是DIFF值域的子集。DMA与DIFF共同扮演“速度”这一概念。

DIFF与DMA的差MACD是价格变化率的变化率,代表的意义是“驱动价格变化的因素”,是一种“势”。

继续沿用动力学的概念,MACD即是“加速度”,其值可直接与“力”正比。MACD在图上的图例是,力在时间上的积累为动量,即MACD岛的面积,动量与速度可正比,因此通过MACD岛的面积可以推出DIFF的变化情况,进而预测价格的走势。

MACD岛的面积越大,其对DIFF的影响越大。
MACD岛为正,则DIFF、DMA上升。
MACD岛为负,则DIFF、DMA下降。

附:双线MACD代码

//+------------------------------------------------------------------+//|                                                         MACD.mq5 |//|                                       Copyright 2016, Izumo Riki |//|                                             https://www.mql5.com |//+------------------------------------------------------------------+#property copyright "Copyright 2016, Izumo Riki"#property link      "https://www.mql5.com"#property version   "1.00"#include <MovingAverages.mqh>#property indicator_separate_window#property indicator_buffers 3#property indicator_plots   3//--- plot DIFF#property indicator_label1  "DIFF"#property indicator_type1   DRAW_LINE#property indicator_color1  clrRed#property indicator_style1  STYLE_SOLID#property indicator_width1  1//--- plot DMA#property indicator_label2  "DMA"#property indicator_type2   DRAW_LINE#property indicator_color2  clrYellow#property indicator_style2  STYLE_SOLID#property indicator_width2  1//--- plot MACD#property indicator_label3  "MACD"#property indicator_type3   DRAW_HISTOGRAM#property indicator_color3  clrChartreuse#property indicator_style3  STYLE_SOLID#property indicator_width3  1//--- input parametersinput int                InpFastEMA = 12;               // Fast EMA periodinput int                InpSlowEMA = 26;               // Slow EMA periodinput int                InpDiffEMA = 9;                // DIFF EMA periodinput ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE; // Applied price//--- indicator buffersdouble         DIFFBuffer[];double         DMABuffer[];double         MACDBuffer[];double         ExtFastMaBuffer[];double         ExtSlowMaBuffer[];//--- MA handlesint            ExtFastMaHandle;int            ExtSlowMaHandle;//+------------------------------------------------------------------+//| Custom indicator initialization function                         |//+------------------------------------------------------------------+int OnInit()  {//--- indicator buffers mapping   SetIndexBuffer(0, DIFFBuffer, INDICATOR_DATA);   SetIndexBuffer(1, DMABuffer, INDICATOR_DATA);   SetIndexBuffer(2, MACDBuffer, INDICATOR_DATA);   SetIndexBuffer(3, ExtFastMaBuffer, INDICATOR_CALCULATIONS);   SetIndexBuffer(4, ExtSlowMaBuffer, INDICATOR_CALCULATIONS);//--- sets first bar from what index will be drawn   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, InpDiffEMA-1);//--- name for Dindicator subwindow label   IndicatorSetString(INDICATOR_SHORTNAME, "MACD(" + string(InpFastEMA) + "," + string(InpSlowEMA) + "," + string(InpDiffEMA) + ")");//--- get MA handles   ExtFastMaHandle=iMA(NULL, 0, InpFastEMA, 0, MODE_EMA, InpAppliedPrice);   ExtSlowMaHandle=iMA(NULL, 0, InpSlowEMA, 0, MODE_EMA, InpAppliedPrice);//---   return(INIT_SUCCEEDED);  }//+------------------------------------------------------------------+//| Custom indicator iteration function                              |//+------------------------------------------------------------------+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 &tick_volume[],                const long &volume[],                const int &spread[]) {//--- we can copy not all data   int to_copy;   if(prev_calculated > rates_total || prev_calculated < 0) to_copy = rates_total;   else {      to_copy = rates_total - prev_calculated;      if(prev_calculated > 0) to_copy++;   }//--- get Fast EMA buffer   CopyBuffer(ExtFastMaHandle, 0, 0, to_copy, ExtFastMaBuffer);//--- get SlowEMA buffer   CopyBuffer(ExtSlowMaHandle, 0, 0, to_copy, ExtSlowMaBuffer);//--- calculate domain   int from, to;   if(prev_calculated == 0) from = 0;   else from = prev_calculated - 1;   to = rates_total;//--- calculate DIFF   for(int i = from; i < to; i++){      DIFFBuffer[i] = ExtFastMaBuffer[i - from] - ExtSlowMaBuffer[i - from];   }//--- calculate DMA      ExponentialMAOnBuffer(rates_total, prev_calculated, 0, InpDiffEMA, DIFFBuffer, DMABuffer);//--- calculate MACD   for(int i = from; i < to; i++)      MACDBuffer[i] = (DIFFBuffer[i] - DMABuffer[i]);//--- OnCalculate done. Return new prev_calculated.   return to;  }//+------------------------------------------------------------------+
0 0