函数iOsMA()有问题,其根源在于MACD指标的参数设置有问题。

 

MACD指标中,核心部分如下:

//---- macd counted in the 1-st buffer
   for(int i=0; i<limit; i++)
      MacdBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)-iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
   for(i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i);

其中iMAOnArray()函数用的是 “MODE_SMA”,而标准的MACD指标用的是 “MODE_EMA”。

这一点差别在平时体现不出差别。但是,在EURUSD日线2009.06.30. -- 07.02.三天中,Diff的值 > Dea的值。而标准的MACD指标,在这三天中,Diff始终是小于Dea的值。

因为OsMA指标是基于MACD指标的,所以mt4的OsMA指标也与标准的OsMA指标不一样。在那三天中,mt4的OsMA指标,是正值。而标准的OsMA指标,是负值。

同样,mt4的iMACD()和iOsMA()也与标准的不同。

现在的问题是,如何才能得到标准的iOsMA()函数?

 
MACD在应用上,首先计算出快速移动平均线(即EMA1)和慢速移动平均线(即EMA2),以此两个数值,来作为测量两者(快慢速线)间的离差值(DIF)的依据,然后再求DIF的N周期的平滑移动平均线DEA(也叫MACD、DEM)线。
以EMA1的参数为12日,EMA2的参数为26日,DIF的参数为9日为例来看看MACD的计算过程

1、计算移动平均值(EMA)

12日EMA的算式为
EMA(12)=前一日EMA(12)×11/13+今日收盘价×2/13
26日EMA的算式为
EMA(26)=前一日EMA(26)×25/27+今日收盘价×2/27

2、计算离差值(DIF)

DIF=今日EMA(12)-今日EMA(26)

3、计算DIF的9日EMA

根据离差值计算其9日的EMA,即离差平均值,是所求的MACD值。为了不与指标原名相混淆,此值又名DEA或DEM。

今日DEA(MACD)=前一日DEA×8/10+今日DIF×2/10

计算出的DIF和DEA的数值均为正值或负值。

理论上,在持续的涨势中,12日EMA线在26日 EMA线之上,其间的正离差值(+DIF)会越来越大;反之,在跌势中离差值可能变为负数(—DIF),也会越来越大,而在行情开始好转时,正负离差值将 会缩小。指标MACD正是利用正负的离差值(±DIF)与离差值的N日平均线(N日EMA)的交叉信号作为买卖信号的依据,即再度以快慢速移动线的交叉原 理来分析买卖信号。另外,MACD指标在股市软件上还有个辅助指标——BAR柱状线,其公式为:BAR=2×(DIF-DEA),我们还是可以利用BAR 柱状线的收缩来决定买卖时机。

离差值DIF和离差平均值DEA是研判MACD的主要工具。其计算方法比较烦琐,由于目前这些计算值都会在股市分析软件上由计算机自动完成,因此,投资者 只要了解其运算过程即可,而更重要的是掌握它的研判功能。另外,和其他指标的计算一样,由于选用的计算周期的不同,MACD指标也包括日MACD指标、周 MACD指标、月MACD指标年MACD指标以及分钟MACD指标等各种类型。经常被用于股市研判的是日MACD指标和周MACD指标。虽然它们的计算时 的取值有所不同,但基本的计算方法一样。

在实践中,将各点的 DIF和DEA(MACD)连接起来就会形成在零轴上下移动的两条快速(短期)和慢速(长期)线,此即为MACD图。
 

已经解决!


#define DEBUG   1
#define MAXLEN  30

double iOsMA_my(int timeframe, int shift) {
        int i;
        double Bar;
        double Diff[MAXLEN], Dea[MAXLEN];
        ArraySetAsSeries(Diff, true);

        for (i=0; i<MAXLEN; i++)
                Diff[i] = iMA(NULL, timeframe, FastEMA, 0, MODE_EMA, PRICE_CLOSE, i) - iMA(NULL, timeframe, SlowEMA, 0, MODE_EMA, PRICE_CLOSE, i);
        for (i=0; i<MAXLEN; i++)
                Dea[i] = iMAOnArray(Diff, MAXLEN, SignalSMA, 0, MODE_EMA, i);
        Bar = Diff[shift] - Dea[shift];

        if (DEBUG != 0) {
                Print("iOsMA_my(", timeframe, "): Diff[", shift, "]=", Diff[shift], " Dea[", shift, "]=", Dea[shift], " Bar=", Bar);
        }

        return(Bar);
}

void alarm() {
        ... ...
        OsMA_small = iOsMA_my(PERIOD_M15, 1);
        ... ...
}
 
学习