找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
首页论坛EAHub 外汇论坛
查看: 13|回复: 0

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

[复制链接]

4万

主题

54

回帖

4万

积分

管理员

积分
45954
发表于 2026-8-23 04:26:00 | 显示全部楼层 |阅读模式
均线也叫移动平均线,一般有以下四种:

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中的核心算法代码:


//--- first calculation or number of bars was changed
   if(prev_calculated==0)
     {
      start=InpMAPeriod+begin;
      //--- set empty value for first start bars
      for(i=0; i<start-1; i++)
         ExtLineBuffer=0.0;
      //--- calculate first visible value
      double first_value=0;
      for(i=begin; i<start; i++)
         first_value+=price;
      first_value/=InpMAPeriod;
      ExtLineBuffer[start-1]=first_value;
     }
   else
      start=prev_calculated-1;
//--- main loop
   for(i=start; i<rates_total && !IsStopped(); i++)
      ExtLineBuffer=(ExtLineBuffer[i-1]*(InpMAPeriod-1)+price)/InpMAPeriod;
复制代码

4.线性加权移动平均Linear Weighted Moving Average (LWMA)

LWMA = SUM (CLOSE (i) * i, N) / SUM (i, N)  ,其中SUM (i, N)在确定N后,是个定数,即1+2+...+N的和


MT5中的核心算法代码:   double sum=0.0,lsum=0.0;
//--- first calculation or number of bars was changed
   if(prev_calculated<=InpMAPeriod+begin+2)
     {
      start=InpMAPeriod+begin;
      //--- set empty value for first start bars
      for(i=0; i<start; i++)
         ExtLineBuffer=0.0;
     }
   else
      start=prev_calculated-1;

   for(i=start-InpMAPeriod,l=1; i<start; i++,l++)
     {
      sum   +=price*l;   // 带权数的价格求和
      lsum  +=price;     //  简单的价格求和
      weight+=l;
     }
   ExtLineBuffer[start-1]=sum/weight;
//--- main loop
   for(i=start; i<rates_total && !IsStopped(); i++)
     {
      sum             =sum-lsum+price*InpMAPeriod;
      lsum            =lsum-price[i-InpMAPeriod]+price;
      ExtLineBuffer=sum/weight;
     }复制代码

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中的核心算法代码://--- detect position
   int pos=prev_calculated-1;
//--- first calculations
   if(pos<ExtPeriodAMA+begin)
     {
      pos=ExtPeriodAMA+begin;
      for(i=0; i<pos-1; i++)
         ExtAMABuffer=0.0;
      ExtAMABuffer[pos-1]=price[pos-1];
     }
//--- main cycle
   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      //--- calculate SSC
      double currentSSC=(CalculateER(i,price)*(ExtFastSC-ExtSlowSC))+ExtSlowSC;
      //--- calculate AMA
      double prevAMA=ExtAMABuffer[i-1];
      ExtAMABuffer=MathPow(currentSSC,2)*(price-prevAMA)+prevAMA;
     }
//+------------------------------------------------------------------+
//| Calculate ER value                                               |
//+------------------------------------------------------------------+
double CalculateER(const int pos,const double& price[])
  {
   double signal=MathAbs(price[pos]-price[pos-ExtPeriodAMA]);
   double noise=0.0;
   for(int delta=0; delta<ExtPeriodAMA; delta++)
      noise+=MathAbs(price[pos-delta]-price[pos-delta-1]);
   if(noise!=0.0)
      return(signal/noise);
   return(0.0);
  }
复制代码

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中的核心算法代码://--- calculate EMA
   ExponentialMAOnBuffer(rates_total,prev_calculated,0,InpPeriodEMA,price,Ema);
//--- calculate EMA on EMA array
   ExponentialMAOnBuffer(rates_total,prev_calculated,InpPeriodEMA-1,InpPeriodEMA,Ema,EmaOfEma);
//--- calculate DEMA
   for(int i=start; i<rates_total && !IsStopped(); i++)
      DemaBuffer=2.0*Ema-EmaOfEma;复制代码

ExponentialMAOnBuffer()函数的核心代码://--- calculate start position
   int    start_position;
   double smooth_factor=2.0/(1.0+period);

   if(prev_calculated==0)  // first calculation or number of bars was changed
     {
      //--- set empty value for first bars
      for(int i=0; i<begin; i++)
         buffer=0.0;
      //--- calculate first visible value
      start_position=period+begin;
      buffer[begin] =price[begin];

      for(int i=begin+1; i<start_position; i++)
         buffer=price*smooth_factor+buffer[i-1]*(1.0-smooth_factor);
     }
   else
      start_position=prev_calculated-1;
//--- main loop
   for(int i=start_position; i<rates_total; i++)
      buffer=price*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中的核心算法代码://--- start calculations
   if(prev_calculated==0)
     {
      start=2*InpPeriodFrAMA-1;
      for(int i=0; i<=start; i++)
         FrAmaBuffer=price;
     }
   else
      start=prev_calculated-1;
//--- main cycle
   double math_log_2=MathLog(2.0);
   for(int i=start; i<rates_total && !IsStopped(); i++)
     {
      double hi1=iHigh(_Symbol,_Period,iHighest(_Symbol,_Period,MODE_HIGH,InpPeriodFrAMA,rates_total-i-1));
      double lo1=iLow(_Symbol,_Period,iLowest(_Symbol,_Period,MODE_LOW,InpPeriodFrAMA,rates_total-i-1));
      double hi2=iHigh(_Symbol,_Period,iHighest(_Symbol,_Period,MODE_HIGH,InpPeriodFrAMA,rates_total-i+InpPeriodFrAMA-1));
      double lo2=iLow(_Symbol,_Period,iLowest(_Symbol,_Period,MODE_LOW,InpPeriodFrAMA,rates_total-i+InpPeriodFrAMA-1));
      double hi3=iHigh(_Symbol,_Period,iHighest(_Symbol,_Period,MODE_HIGH,2*InpPeriodFrAMA,rates_total-i-1));
      double lo3=iLow(_Symbol,_Period,iLowest(_Symbol,_Period,MODE_LOW,2*InpPeriodFrAMA,rates_total-i-1));
      double n1=(hi1-lo1)/InpPeriodFrAMA;
      double n2=(hi2-lo2)/InpPeriodFrAMA;
      double n3=(hi3-lo3)/(2*InpPeriodFrAMA);
      double d=(MathLog(n1+n2)-MathLog(n3))/math_log_2;
      double alfa=MathExp(-4.6*(d-1.0));
      //---
      FrAmaBuffer=alfa*price+(1-alfa)*FrAmaBuffer[i-1];
     }复制代码

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



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|EAHub外汇论坛

GMT+8, 2026-10-12 12:35 , Processed in 0.105358 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表