© 本贴为 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中的核心算法代码:
//--- 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[i]=0.0;
//--- calculate first visible value
double first_value=0;
for(i=begin; i<start; i++)
first_value+=price[i];
first_value/=InpMAPeriod;
ExtLineBuffer[start-1]=first_value;
}
else
start=prev_calculated-1;
//--- main loop
for(i=start; i<rates_total && !IsStopped(); i++)
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中的核心算法代码: 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[i]=0.0;
}
else
start=prev_calculated-1;
for(i=start-InpMAPeriod,l=1; i<start; i++,l++)
{
sum +=price[i]*l; // 带权数的价格求和
lsum +=price[i]; // 简单的价格求和
weight+=l;
}
ExtLineBuffer[start-1]=sum/weight;
//--- main loop
for(i=start; i<rates_total && !IsStopped(); i++)
{
sum =sum-lsum+price[i]*InpMAPeriod;
lsum =lsum-price[i-InpMAPeriod]+price[i];
ExtLineBuffer[i]=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[i]=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[i]=MathPow(currentSSC,2)*(price[i]-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[i]=2.0*Ema[i]-EmaOfEma[i];
复制代码
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[i]=0.0;
//--- calculate first visible value
start_position=period+begin;
buffer[begin] =price[begin];
for(int i=begin+1; i<start_position; i++)
buffer[i]=price[i]*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[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中的核心算法代码://--- start calculations
if(prev_calculated==0)
{
start=2*InpPeriodFrAMA-1;
for(int i=0; i<=start; i++)
FrAmaBuffer[i]=price[i];
}
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[i]=alfa*price[i]+(1-alfa)*FrAmaBuffer[i-1];
}
复制代码
在以上的7个种类的均线中,对趋势的敏感强度依次为DEMA>FRAMA> AMA>LWMA>EMA>SMA>SSMA,如下图依次为紫色>蓝色>白色>青色>黄色>兰色>红色。