设为首页 收藏本站 切换语言

移动平均线的各种平均方法的比较

| 发表于 2023-1-3 21:13:16 | 显示全部楼层 |复制链接
© 本贴为 xxtz 原创/首发,严禁抄袭!
均线也叫移动平均线,一般有以下四种:
1. 最简单的简单移动平均线 Simple Moving Average (SMA)
SMA= SUM (CLOSE (i), N) / N     :其中N:计算期间数InpMAPeriod;CLOSE(i):第i根K线的收盘价。SUM:求和


2.指数移动平均Exponential Moving Average (EMA)
EMA = (CLOSE (i) * P) + (EMA (i - 1) * (1 - P))   其中:P价格使用的权数SmoothFactor,在MQL中一般使用2.0/(1.0+InpMAPeriod),可见计算的期数越长,当前价格影响越低。

3.平滑移动平均Smoothed Moving Average (SMMA)
第1个值计算公式:
SMMA1 = SUM (CLOSE (i), N)/ N
第2个值计算公式:
SMMA (i) = (SMMA1*(N-1) + CLOSE (i)) / N
第3项及以后的计算迭代计算公式:
SMMA (i) = (SMMA (i - 1) * (N-1)+ CLOSE (i)) / N

MT5中的核心算法代码:
  1. //--- first calculation or number of bars was changed
  2.    if(prev_calculated==0)
  3.      {
  4.       start=InpMAPeriod+begin;
  5.       //--- set empty value for first start bars
  6.       for(i=0; i<start-1; i++)
  7.          ExtLineBuffer[i]=0.0;
  8.       //--- calculate first visible value
  9.       double first_value=0;
  10.       for(i=begin; i<start; i++)
  11.          first_value+=price[i];
  12.       first_value/=InpMAPeriod;
  13.       ExtLineBuffer[start-1]=first_value;
  14.      }
  15.    else
  16.       start=prev_calculated-1;
  17. //--- main loop
  18.    for(i=start; i<rates_total && !IsStopped(); i++)
  19.       ExtLineBuffer[i]=(ExtLineBuffer[i-1]*(InpMAPeriod-1)+price[i])/InpMAPeriod;
复制代码


4.线性加权移动平均Linear Weighted Moving Average (LWMA)
LWMA = SUM (CLOSE (i) * i, N) / SUM (i, N)  ,其中SUM (i, N)在确定N后,是个定数,即1+2+...+N的和

MT5中的核心算法代码:
  1.    double sum=0.0,lsum=0.0;
  2. //--- first calculation or number of bars was changed
  3.    if(prev_calculated<=InpMAPeriod+begin+2)
  4.      {
  5.       start=InpMAPeriod+begin;
  6.       //--- set empty value for first start bars
  7.       for(i=0; i<start; i++)
  8.          ExtLineBuffer[i]=0.0;
  9.      }
  10.    else
  11.       start=prev_calculated-1;
  12.    for(i=start-InpMAPeriod,l=1; i<start; i++,l++)
  13.      {
  14.       sum   +=price[i]*l;   // 带权数的价格求和
  15.       lsum  +=price[i];     //  简单的价格求和
  16.       weight+=l;
  17.      }
  18.    ExtLineBuffer[start-1]=sum/weight;
  19. //--- main loop
  20.    for(i=start; i<rates_total && !IsStopped(); i++)
  21.      {
  22.       sum             =sum-lsum+price[i]*InpMAPeriod;
  23.       lsum            =lsum-price[i-InpMAPeriod]+price[i];
  24.       ExtLineBuffer[i]=sum/weight;
  25.      }
复制代码


5. 自适应移动平均Adaptive Moving Average (AMA)

为了降低价格变动的噪音(如价格突变)和对趋势的最小延迟,派瑞考夫曼在他的Smarter Trading书中提出了AMA。
为了描述当前市场的状态,考夫曼引入了ER“当前市场效率”这个概念:ER(i) = Signal(i)/Noise(i);
Signal(i) = ABS(Price(i) - Price(i - N));          第i期信号值=第i期价格与第i期的N期前的价格差的绝对值;

Noise(i) = Sum(ABS(Price(i) - Price(i-1)),N);第i期噪音值= N个期间的信号值求和;
强趋势,ER值=1;无趋势ER=0;

EMA(i) = Price(i) * SC + EMA(i-1) * (1 - SC)       ,其中:SC = 2/(n+1) — EMA 平滑常数  n —平均期数;
SSC(i) = (ER(i) * ( fast SC - slow SC) + slow SC  , 其中:fast SC = 2/(2+1) = 0.6667;slow SC = 2/(30+1) = 0.06452;
所以, SSC(i) = ER(i) * 0.60215 + 0.06425  ;
为了获得更好的平滑参数,考夫曼建议将ssc(i)取平方:
AMA(i) = Price(i) * (SSC(i)^2) + AMA(i-1)*(1-SSC(i)^2)= AMA(i-1) + (SSC(i)^2) * (Price(i) - AMA(i-1));
MT5中的核心算法代码:
  1. //--- detect position
  2.    int pos=prev_calculated-1;
  3. //--- first calculations
  4.    if(pos<ExtPeriodAMA+begin)
  5.      {
  6.       pos=ExtPeriodAMA+begin;
  7.       for(i=0; i<pos-1; i++)
  8.          ExtAMABuffer[i]=0.0;
  9.       ExtAMABuffer[pos-1]=price[pos-1];
  10.      }
  11. //--- main cycle
  12.    for(i=pos; i<rates_total && !IsStopped(); i++)
  13.      {
  14.       //--- calculate SSC
  15.       double currentSSC=(CalculateER(i,price)*(ExtFastSC-ExtSlowSC))+ExtSlowSC;
  16.       //--- calculate AMA
  17.       double prevAMA=ExtAMABuffer[i-1];
  18.       ExtAMABuffer[i]=MathPow(currentSSC,2)*(price[i]-prevAMA)+prevAMA;
  19.      }
  20. //+------------------------------------------------------------------+
  21. //| Calculate ER value                                               |
  22. //+------------------------------------------------------------------+
  23. double CalculateER(const int pos,const double& price[])
  24.   {
  25.    double signal=MathAbs(price[pos]-price[pos-ExtPeriodAMA]);
  26.    double noise=0.0;
  27.    for(int delta=0; delta<ExtPeriodAMA; delta++)
  28.       noise+=MathAbs(price[pos-delta]-price[pos-delta-1]);
  29.    if(noise!=0.0)
  30.       return(signal/noise);
  31.    return(0.0);
  32.   }
复制代码

6.双倍指数移动平均Double Exponential Moving Average Technical Indicator (DEMA)
Patrick Mulloy于1994年2月份在“股票与商品技术分析”杂志发表了该指标,它可以用来平滑价格序列,这个指标公式也可用于对其他指标的平滑。


首先计算当前EMA的error: err(i) = Price(i) - EMA(Price, N, i)   

DEMA(i) = EMA(Price, N, i) + EMA(err, N, i) = EMA(Price, N, i) + EMA(Price - EMA(Price, N, i), N, i)
= 2 * EMA(Price, N, i) - EMA(Price - EMA(Price, N, i), N, i) = 2 * EMA(Price, N, i) - EMA2(Price, N, i)
其中:EMA2(Price, N, i) — 2次连续价格平滑.


MT5中的核心算法代码:
  1. //--- calculate EMA
  2.    ExponentialMAOnBuffer(rates_total,prev_calculated,0,InpPeriodEMA,price,Ema);
  3. //--- calculate EMA on EMA array
  4.    ExponentialMAOnBuffer(rates_total,prev_calculated,InpPeriodEMA-1,InpPeriodEMA,Ema,EmaOfEma);
  5. //--- calculate DEMA
  6.    for(int i=start; i<rates_total && !IsStopped(); i++)
  7.       DemaBuffer[i]=2.0*Ema[i]-EmaOfEma[i];
复制代码

ExponentialMAOnBuffer()函数的核心代码:
  1. //--- calculate start position
  2.    int    start_position;
  3.    double smooth_factor=2.0/(1.0+period);
  4.    if(prev_calculated==0)  // first calculation or number of bars was changed
  5.      {
  6.       //--- set empty value for first bars
  7.       for(int i=0; i<begin; i++)
  8.          buffer[i]=0.0;
  9.       //--- calculate first visible value
  10.       start_position=period+begin;
  11.       buffer[begin] =price[begin];
  12.       for(int i=begin+1; i<start_position; i++)
  13.          buffer[i]=price[i]*smooth_factor+buffer[i-1]*(1.0-smooth_factor);
  14.      }
  15.    else
  16.       start_position=prev_calculated-1;
  17. //--- main loop
  18.    for(int i=start_position; i<rates_total; i++)
  19.       buffer[i]=price[i]*smooth_factor+buffer[i-1]*(1.0-smooth_factor);
复制代码


7.分形自适应移动平均Fractal Adaptive Moving Average Technical Indicator (FRAMA)
该指标由John Ehlers开发,受到EMA启发,该指标的平滑因子是价格序列的分形维数,指标优势是很好的跟随趋势,但对强趋势的回调却反应迟滞。
FRAMA(i) = A(i) * Price(i) + (1 - A(i)) * FRAMA(i-1)   ;其中A(i) = EXP(-4.6 * (D(i) - 1));D(i)是当前分形维数。
直线的分形维数是1,D(1)=1时,A(i)=1。所以价格按照线性变化,EMA就不起作用了,FRAMA(i) = 1 * Price(i) + (1-1) * FRAMA(i-1) = Price(i)。
平面的分形维数=2,D(2)=EXP(-4.6 * (2 - 1))=EXP(-4.6) = 0.01, 如此小的EMA平滑因子,一般很强的锯齿状的价格运动,如此的强趋势的缓和过程大约相当200期的SMA。


分形维数的公式:D = (LOG(N1 + N2) - LOG(N3))/LOG(2);
其中:N1(i) = N(Length,i);N2(i) = N(Length,i + Length);N3(i) = N(2 * Length,i);
N(Length,i) = (HighestPrice(i) - LowestPrice(i))/Length   ; HighestPrice(i)是Length期间内的最高价。


MT5中的核心算法代码:
  1. //--- start calculations
  2.    if(prev_calculated==0)
  3.      {
  4.       start=2*InpPeriodFrAMA-1;
  5.       for(int i=0; i<=start; i++)
  6.          FrAmaBuffer[i]=price[i];
  7.      }
  8.    else
  9.       start=prev_calculated-1;
  10. //--- main cycle
  11.    double math_log_2=MathLog(2.0);
  12.    for(int i=start; i<rates_total && !IsStopped(); i++)
  13.      {
  14.       double hi1=iHigh(_Symbol,_Period,iHighest(_Symbol,_Period,MODE_HIGH,InpPeriodFrAMA,rates_total-i-1));
  15.       double lo1=iLow(_Symbol,_Period,iLowest(_Symbol,_Period,MODE_LOW,InpPeriodFrAMA,rates_total-i-1));
  16.       double hi2=iHigh(_Symbol,_Period,iHighest(_Symbol,_Period,MODE_HIGH,InpPeriodFrAMA,rates_total-i+InpPeriodFrAMA-1));
  17.       double lo2=iLow(_Symbol,_Period,iLowest(_Symbol,_Period,MODE_LOW,InpPeriodFrAMA,rates_total-i+InpPeriodFrAMA-1));
  18.       double hi3=iHigh(_Symbol,_Period,iHighest(_Symbol,_Period,MODE_HIGH,2*InpPeriodFrAMA,rates_total-i-1));
  19.       double lo3=iLow(_Symbol,_Period,iLowest(_Symbol,_Period,MODE_LOW,2*InpPeriodFrAMA,rates_total-i-1));
  20.       double n1=(hi1-lo1)/InpPeriodFrAMA;
  21.       double n2=(hi2-lo2)/InpPeriodFrAMA;
  22.       double n3=(hi3-lo3)/(2*InpPeriodFrAMA);
  23.       double d=(MathLog(n1+n2)-MathLog(n3))/math_log_2;
  24.       double alfa=MathExp(-4.6*(d-1.0));
  25.       //---
  26.       FrAmaBuffer[i]=alfa*price[i]+(1-alfa)*FrAmaBuffer[i-1];
  27.      }
复制代码


在以上的7个种类的均线中,对趋势的敏感强度依次为DEMA>FRAMA> AMA>LWMA>EMA>SMA>SSMA,如下图依次为紫色>蓝色>白色>青色>黄色>兰色>红色。
image.png

image.png
如果有帮助,就支持一下我呗
举报

评论 使用道具

精彩评论3

xinhua123
DDD
| 发表于 2023-1-4 02:20:26 | 显示全部楼层
移动平均线
举报

点赞 评论 使用道具

zhanghailong
DD
| 发表于 2023-1-4 11:43:09 | 显示全部楼层
楼主辛苦了
举报

点赞 评论 使用道具

yalihenda
DD
| 发表于 2023-2-3 11:48:01 | 显示全部楼层
谢谢分享辛苦了!
举报

点赞 评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册

天眼云VPS
简体中文
繁體中文
English(英语)
日本語(日语)
Deutsch(德语)
Русский язык(俄语)
بالعربية(阿拉伯语)
Türkçe(土耳其语)
Português(葡萄牙语)
ภาษาไทย(泰国语)
한어(朝鲜语/韩语)
Français(法语)