//+------------------------------------------------------------------+
//| AllStochastics_v4.1 600+.mq4 |
//| Copyright � 2007-14, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
// List of MAs:
// MA_Method= 0: SMA - Simple Moving Average
// MA_Method= 1: EMA - Exponential Moving Average
// MA_Method= 2: Wilder - Wilder Exponential Moving Average
// MA_Method= 3: LWMA - Linear Weighted Moving Average
// MA_Method= 4: SineWMA - Sine Weighted Moving Average
// MA_Method= 5: TriMA - Triangular Moving Average
// MA_Method= 6: LSMA - Least Square Moving Average (or EPMA, Linear Regression Line)
// MA_Method= 7: SMMA - Smoothed Moving Average
// MA_Method= 8: HMA - Hull Moving Average by Alan Hull
// MA_Method= 9: ZeroLagEMA - Zero-Lag Exponential Moving Average
// MA_Method=10: DEMA - Double Exponential Moving Average by Patrick Mulloy
// MA_Method=11: T3_basic - T3 by T.Tillson (original version)
// MA_Method=12: ITrend - Instantaneous Trendline by J.Ehlers
// MA_Method=13: Median - Moving Median
// MA_Method=14: GeoMean - Geometric Mean
// MA_Method=15: REMA - Regularized EMA by Chris Satchwell
// MA_Method=16: ILRS - Integral of Linear Regression Slope
// MA_Method=17: IE/2 - Combination of LSMA and ILRS
// MA_Method=18: TriMAgen - Triangular Moving Average generalized by J.Ehlers
// MA_Method=19: VWMA - Volume Weighted Moving Average
// MA_Method=20: JSmooth - Smoothing by Mark Jurik
// MA_Method=21: SMA_eq - Simplified SMA
// MA_Method=22: ALMA - Arnaud Legoux Moving Average
// MA_Method=23: TEMA - Triple Exponential Moving Average by Patrick Mulloy
// MA_Method=24: T3 - T3 by T.Tillson (correct version)
// MA_Method=25: Laguerre - Laguerre filter by J.Ehlers
// List of Prices:
// Price = 0 - Close
// Price = 1 - Open
// Price = 2 - High
// Price = 3 - Low
// Price = 4 - Median Price = (High+Low)/2
// Price = 5 - Typical Price = (High+Low+Close)/3
// Price = 6 - Weighted Close = (High+Low+Close*2)/4
#property copyright "Copyright � 2007-14, TrendLaboratory"
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 YellowGreen
#property indicator_width1 1
#property indicator_color2 Coral
#property indicator_width2 1
#property indicator_style2 2
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 30
#property indicator_level2 70
//---- indicator parameters
extern int TimeFrame = 0; // Numeric value of the TimeFrame
extern int Price = 0; // Apply to Price(0-Close;1-Open;2-High;3-Low;4-Median price;5-Typical price;6-Weighted Close)
extern int Price_field = 0; // 0-High/Low,1-Close/Close
extern int Sto_Period = 20; // Period of Stochastic(or Raw %K period)
extern int Smooth = 5; // Period of Smoothing MA (or Fast %D period)
extern int SmoothMode = 0; // Method of Smoothing MA
extern int Signal = 5; // Period of Signal MA (Slow %D Period)
extern int SignalMode = 0; // Method of Signal MA
extern int DoubleMode = 1; // Double Stochastic Mode: 0-off,1-on
//---- indicator buffers
double Sto[];
double Sig[];
double Sto1[];
double K1[];
double K2[];
//----
double tmp[][3][2], ma[3][3];
int draw_begin, smoothsize, signalsize;
datetime prevtime[4];
string IndicatorName, TF, fast_name, slow_name;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
if(TimeFrame <= Period()) TimeFrame = Period();
IndicatorDigits(Digits);
//---- indicator buffers mapping
IndicatorBuffers(5);
SetIndexBuffer(0, Sto); SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(1, Sig); SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(2,Sto1);
SetIndexBuffer(3, K1);
SetIndexBuffer(4, K2);
//---- indicator name
fast_name = averageName(SmoothMode,smoothsize);
slow_name = averageName(SignalMode,signalsize);
switch(TimeFrame)
{
case 1 : TF = "M1" ; break;
case 5 : TF = "M5" ; break;
case 15 : TF = "M15"; break;
case 30 : TF = "M30"; break;
case 60 : TF = "H1" ; break;
case 240 : TF = "H4" ; break;
case 1440 : TF = "D1" ; break;
case 10080 : TF = "W1" ; break;
case 43200 : TF = "MN1"; break;
default : TF = "Current";
}
IndicatorName = WindowExpertName();
IndicatorShortName(IndicatorName+"["+TF+"]("+Price+","+Sto_Period+","+fast_name+"("+Smooth+"),"+slow_name+"("+Signal+")"+","+DoubleMode+")");
SetIndexLabel(0,"Stochastic");
SetIndexLabel(1,"Signal");
draw_begin = Sto_Period + Smooth + Signal;
SetIndexDrawBegin(0,draw_begin);
SetIndexDrawBegin(1,draw_begin);
ArrayResize(tmp,MathMax(smoothsize,signalsize));
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| AllStochastics_v4.1 600+ |
//+------------------------------------------------------------------+
int start()
{
int i, shift, limit, counted_bars=IndicatorCounted();
double up, dn;
if(counted_bars > 0) limit = Bars - counted_bars - 1;
if(counted_bars < 0) return(0);
if(counted_bars < 1)
{
limit = Bars-1;
for(i=limit;i>=0;i--)
{
Sto[i] = EMPTY_VALUE;
Sig[i] = EMPTY_VALUE;
}
}
if(TimeFrame != Period())
{
limit = MathMax(limit,TimeFrame/Period());
for(shift = 0;shift < limit;shift++)
{
int y = iBarShift(NULL,TimeFrame,Time[shift]);
Sto[shift] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,Price_field,Sto_Period,Smooth,SmoothMode,Signal,SignalMode,DoubleMode,0,y);
Sig[shift] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,Price_field,Sto_Period,Smooth,SmoothMode,Signal,SignalMode,DoubleMode,1,y);
}
return(0);
}
else
{
for(shift=limit;shift>=0;shift--)
{
double aPrice = iMA(NULL,0,1,0,0,Price,shift);
up = 0;
dn = 1000000;
for(i=0;i<Sto_Period;i++)
{
if(Price_field == 0)
{
up = MathMax(up,High[shift+i]);
dn = MathMin(dn,Low [shift+i]);
}
else
{
up = MathMax(up,Close[shift+i]);
dn = MathMin(dn,Close[shift+i]);
}
}
if(up - dn > 0) K1[shift] = 100*(aPrice - dn)/(up - dn); else K1[shift] = 0;
if(DoubleMode == 0) Sto[shift] = allAverages(0,K1,Smooth,SmoothMode,smoothsize,shift);
else
{
Sto1[shift] = allAverages(0,K1,Smooth,SmoothMode,smoothsize,shift);
up = 0;
dn = 1000000;
for(i=0;i<Sto_Period;i++)
{
up = MathMax(up,Sto1[shift+i]);
dn = MathMin(dn,Sto1[shift+i]);
}
if(up - dn > 0) K2[shift] = 100*(Sto1[shift] - dn)/(up - dn); else K2[shift] = 0;
Sto[shift] = allAverages(1,K2,Smooth,SmoothMode,smoothsize,shift);
}
if(Signal > 0)
{
if(Signal > 1) Sig[shift] = allAverages(2,Sto,Signal,SignalMode,signalsize,shift);
if(Signal == 1) Sig[shift] = Sto[shift+1];
}
}
}
//---- done
return(0);
}
string averageName(int mode,int& arraysize)
{
string ma_name = "";
switch(mode)
{
case 1 : ma_name="EMA" ; break;
case 2 : ma_name="Wilder" ; break;
case 3 : ma_name="LWMA" ; break;
case 4 : ma_name="SineWMA" ; break;
case 5 : ma_name="TriMA" ; break;
case 6 : ma_name="LSMA" ; break;
case 7 : ma_name="SMMA" ; break;
case 8 : ma_name="HMA" ; break;
case 9 : ma_name="ZeroLagEMA"; break;
case 10: ma_name="DEMA" ; arraysize = 2; break;
case 11: ma_name="T3 basic" ; arraysize = 6; break;
case 12: ma_name="InstTrend" ; break;
case 13: ma_name="Median" ; break;
case 14: ma_name="GeoMean" ; break;
case 15: ma_name="REMA" ; break;
case 16: ma_name="ILRS" ; break;
case 17: ma_name="IE/2" ; break;
case 18: ma_name="TriMA_gen" ; break;
case 19: ma_name="VWMA" ; break;
case 20: ma_name="JSmooth" ; arraysize = 5; break;
case 21: ma_name="SMA_eq" ; break;
case 22: ma_name="ALMA" ; break;
case 23: ma_name="TEMA" ; arraysize = 4; break;
case 24: ma_name="T3" ; arraysize = 6; break;
case 25: ma_name="Laguerre" ; arraysize = 4; break;
default: ma_name="SMA";
}
return(ma_name);
}
double allAverages(int index,double& price[],int period,int mode,int arraysize,int bar)
{
double MA[3];
if(prevtime[index] != Time[bar])
{
ma[index][2] = ma[index][1];
ma[index][1] = ma[index][0];
for(int i=0;i<arraysize;i++) tmp[i][index][1] = tmp[i][index][0];
prevtime[index] = Time[bar];
}
for(i=0;i<3;i++) MA[i] = ma[index][i];
switch(mode)
{
case 1 : ma[index][0] = EMA(price[bar],ma[index][1],period,bar); break;
case 2 : ma[index][0] = Wilder(price[bar],ma[index][1],period,bar); break;
case 3 : ma[index][0] = LWMA(price,period,bar); break;
case 4 : ma[index][0] = SineWMA(price,period,bar); break;
case 5 : ma[index][0] = TriMA(price,period,bar); break;
case 6 : ma[index][0] = LSMA(price,period,bar); break;
case 7 : ma[index][0] = SMMA(price,ma[index][1],period,bar); break;
case 8 : ma[index][0] = HMA(price,period,bar); break;
case 9 : ma[index][0] = ZeroLagEMA(price,ma[index][1],period,bar); break;
case 10: ma[index][0] = DEMA(index,0,price[bar],period,1,bar); break;
case 11: ma[index][0] = T3_basic(index,0,price[bar],period,0.7,bar); break;
case 12: ma[index][0] = ITrend(price,MA,period,bar); break;
case 13: ma[index][0] = Median(price,period,bar); break;
case 14: ma[index][0] = GeoMean(price,period,bar); break;
case 15: ma[index][0] = REMA(price[bar],MA,period,0.5,bar); break;
case 16: ma[index][0] = ILRS(price,period,bar); break;
case 17: ma[index][0] = IE2(price,period,bar); break;
case 18: ma[index][0] = TriMA_gen(price,period,bar); break;
case 19: ma[index][0] = VWMA(price,period,bar); break;
case 20: ma[index][0] = JSmooth(index,0,price[bar],period,1,bar); break;
case 21: ma[index][0] = SMA_eq(price,MA,period,bar); break;
case 22: ma[index][0] = ALMA(price,period,0.85,8,bar); break;
case 23: ma[index][0] = TEMA(index,price[bar],period,1,bar); break;
case 24: ma[index][0] = T3(index,0,price[bar],period,0.7,bar); break;
case 25: ma[index][0] = Laguerre(index,price[bar],period,4,bar); break;
default: ma[index][0] = SMA(price,period,bar); break;
}
return(ma[index][0]);
}
// MA_Method=0: SMA - Simple Moving Average
double SMA(double& array[],int per,int bar)
{
double Sum = 0;
for(int i = 0;i < per;i++) Sum += array[bar+i];
return(Sum/per);
}
// MA_Method=1: EMA - Exponential Moving Average
double EMA(double price,double prev,int per,int bar)
{
if(bar >= Bars - 2) double ema = price;
else
ema = prev + 2.0/(1+per)*(price - prev);
return(ema);
}
// MA_Method=2: Wilder - Wilder Exponential Moving Average
double Wilder(double price,double prev,int per,int bar)
{
if(bar >= Bars - 2) double wilder = price; //SMA(array1,per,bar);
else
wilder = prev + (price - prev)/per;
return(wilder);
}
// MA_Method=3: LWMA - Linear Weighted Moving Average
double LWMA(double& array[],int per,int bar)
{
double Sum = 0;
double Weight = 0;
for(int i = 0;i < per;i++)
{
Weight+= (per - i);
Sum += array[bar+i]*(per - i);
}
if(Weight>0) double lwma = Sum/Weight;
else lwma = 0;
return(lwma);
}
// MA_Method=4: SineWMA - Sine Weighted Moving Average
double SineWMA(double& array[],int per,int bar)
{
double pi = 3.1415926535;
double Sum = 0;
double Weight = 0;
for(int i = 0;i < per;i++)
{
Weight+= MathSin(pi*(i+1)/(per+1));
Sum += array[bar+i]*MathSin(pi*(i+1)/(per+1));
}
if(Weight>0) double swma = Sum/Weight;
else swma = 0;
return(swma);
}
// MA_Method=5: TriMA - Triangular Moving Average
double TriMA(double& array[],int per,int bar)
{
double sma;
int len = MathCeil((per+1)*0.5);
double sum=0;
for(int i = 0;i < len;i++)
{
sma = SMA(array,len,bar+i);
sum += sma;
}
double trima = sum/len;
return(trima);
}
// MA_Method=6: LSMA - Least Square Moving Average (or EPMA, Linear Regression Line)
double LSMA(double& array[],int per,int bar)
{
double Sum=0;
for(int i=per; i>=1; i--) Sum += (i-(per+1)/3.0)*array[bar+per-i];
double lsma = Sum*6/(per*(per+1));
return(lsma);
}
// MA_Method=7: SMMA - Smoothed Moving Average
double SMMA(double& array[],double prev,int per,int bar)
{
if(bar == Bars - per) double smma = SMA(array,per,bar);
else
if(bar < Bars - per)
{
double Sum = 0;
for(int i = 0;i < per;i++) Sum += array[bar+i+1];
smma = (Sum - prev + array[bar])/per;
}
return(smma);
}
// MA_Method=8: HMA - Hull Moving Average by Alan Hull
double HMA(double& array[],int per,int bar)
{
double temp[];
int len = MathSqrt(per);
ArrayResize(temp,len);
if(bar == Bars - per) double hma = array[bar];
else
if(bar < Bars - per)
{
for(int i=0;i<len;i++) temp[i] = 2*LWMA(array,per/2,bar+i) - LWMA(array,per,bar+i);
hma = LWMA(temp,len,0);
}
return(hma);
}
// MA_Method=9: ZeroLagEMA - Zero-Lag Exponential Moving Average
double ZeroLagEMA(double& price[],double prev,int per,int bar)
{
double alfa = 2.0/(1+per);
int lag = 0.5*(per - 1);
if(bar >= Bars - lag) double zema = price[bar];
else
zema = alfa*(2*price[bar] - price[bar+lag]) + (1-alfa)*prev;
return(zema);
}
// MA_Method=10: DEMA - Double Exponential Moving Average by Patrick Mulloy
double DEMA(int index,int num,double price,double per,double v,int bar)
{
double alpha = 2.0/(1+per);
if(bar == Bars - 2) {double dema = price; tmp[num][index][0] = dema; tmp[num+1][index][0] = dema;}
else
if(bar < Bars - 2)
{
tmp[num ][index][0] = tmp[num ][index][1] + alpha*(price - tmp[num ][index][1]);
tmp[num+1][index][0] = tmp[num+1][index][1] + alpha*(tmp[num][index][0] - tmp[num+1][index][1]);
dema = tmp[num ][index][0]*(1+v) - tmp[num+1][index][0]*v;
}
return(dema);
}
// MA_Method=11: T3 by T.Tillson
double T3_basic(int index,int num,double price,int per,double v,int bar)
{
double dema1, dema2;
if(bar == Bars - 2)
{
double T3 = price;
for(int k=0;k<6;k++) tmp[num+k][index][0] = T3;
}
else
if(bar < Bars - 2)
{
dema1 = DEMA(index,num ,price,per,v,bar);
dema2 = DEMA(index,num+2,dema1,per,v,bar);
T3 = DEMA(index,num+4,dema2,per,v,bar);
}
return(T3);
}
// MA_Method=12: ITrend - Instantaneous Trendline by J.Ehlers
double ITrend(double& price[],double& array[],int per,int bar)
{
double alfa = 2.0/(per+1);
if(bar < Bars - 7)
double it = (alfa - 0.25*alfa*alfa)*price[bar] + 0.5*alfa*alfa*price[bar+1] - (alfa - 0.75*alfa*alfa)*price[bar+2] +
2*(1-alfa)*array[1] - (1-alfa)*(1-alfa)*array[2];
else
it = (price[bar] + 2*price[bar+1] + price[bar+2])/4;
return(it);
}
// MA_Method=13: Median - Moving Median
double Median(double& price[],int per,int bar)
{
double _array[];
ArrayResize(_array,per);
for(int i = 0; i < per;i++) _array[i] = price[bar+i];
ArraySort(_array);
int num = MathRound((per-1)/2);
if(MathMod(per,2) > 0) double median = _array[num]; else median = 0.5*(_array[num] + _array[num+1]);
return(median);
}
// MA_Method=14: GeoMean - Geometric Mean
double GeoMean(double& price[],int per,int bar)
{
if(bar < Bars - per)
{
double gmean = MathPow(price[bar],1.0/per);
for(int i = 1; i < per;i++) gmean *= MathPow(price[bar+i],1.0/per);
}
return(gmean);
}
// MA_Method=15: REMA - Regularized EMA by Chris Satchwell
double REMA(double price,double& array[],int per,double lambda,int bar)
{
double alpha = 2.0/(per + 1);
if(bar >= Bars - 3) double rema = price;
else
rema = (array[1]*(1+2*lambda) + alpha*(price - array[1]) - lambda*array[2])/(1+lambda);
return(rema);
}
// MA_Method=16: ILRS - Integral of Linear Regression Slope
double ILRS(double& price[],int per,int bar)
{
double sum = per*(per-1)*0.5;
double sum2 = (per-1)*per*(2*per-1)/6.0;
double sum1 = 0;
double sumy = 0;
for(int i=0;i<per;i++)
{
sum1 += i*price[bar+i];
sumy += price[bar+i];
}
double num1 = per*sum1 - sum*sumy;
double num2 = sum*sum - per*sum2;
if(num2 != 0) double slope = num1/num2; else slope = 0;
double ilrs = slope + SMA(price,per,bar);
return(ilrs);
}
// MA_Method=17: IE/2 - Combination of LSMA and ILRS
double IE2(double& price[],int per,int bar)
{
double ie = 0.5*(ILRS(price,per,bar) + LSMA(price,per,bar));
return(ie);
}
// MA_Method=18: TriMAgen - Triangular Moving Average Generalized by J.Ehlers
double TriMA_gen(double& array[],int per,int bar)
{
int len1 = MathFloor((per+1)*0.5);
int len2 = MathCeil((per+1)*0.5);
double sum=0;
for(int i = 0;i < len2;i++) sum += SMA(array,len1,bar+i);
double trimagen = sum/len2;
return(trimagen);
}
// MA_Method=19: VWMA - Volume Weighted Moving Average
double VWMA(double& array[],int per,int bar)
{
double Sum = 0;
double Weight = 0;
for(int i = 0;i < per;i++)
{
Weight+= Volume[bar+i];
Sum += array[bar+i]*Volume[bar+i];
}
if(Weight>0) double vwma = Sum/Weight;
else vwma = 0;
return(vwma);
}
// MA_Method=20: JSmooth - Smoothing by Mark Jurik
double JSmooth(int index,int num,double price,int per,double pow,int bar)
{
double beta = 0.45*(per-1)/(0.45*(per-1)+2);
double alpha = MathPow(beta,pow);
if(bar == Bars - 2) {tmp[num+4][index][0] = price; tmp[num+0][index][0] = price; tmp[num+2][index][0] = price;}
else
if(bar < Bars - 2)
{
tmp[num+0][index][0] = (1-alpha)*price + alpha*tmp[num+0][index][1];
tmp[num+1][index][0] = (price - tmp[num+0][index][0])*(1-beta) + beta*tmp[num+1][index][1];
tmp[num+2][index][0] = tmp[num+0][index][0] + tmp[num+1][index][0];
tmp[num+3][index][0] = (tmp[num+2][index][0] - tmp[num+4][index][1])*MathPow((1-alpha),2) + MathPow(alpha,2)*tmp[num+3][index][1];
tmp[num+4][index][0] = tmp[num+4][index][1] + tmp[num+3][index][0];
}
return(tmp[num+4][index][0]);
}
// MA_Method=21: SMA_eq - Simplified SMA
double SMA_eq(double& price[],double& array[],int per,int bar)
{
if(bar == Bars - per) double sma = SMA(price,per,bar);
else
if(bar < Bars - per) sma = (price[bar] - price[bar+per])/per + array[1];
return(sma);
}
// MA_Method=22: ALMA by Arnaud Legoux / Dimitris Kouzis-Loukas / Anthony Cascino
double ALMA(double& price[],int per,double offset,double sigma,int bar)
{
double m = MathFloor(offset * (per - 1));
double s = per/sigma;
double w, sum =0, wsum = 0;
for (int i=0;i < per;i++)
{
w = MathExp(-((i - m)*(i - m))/(2*s*s));
wsum += w;
sum += price[bar+(per-1-i)] * w;
}
if(wsum != 0) double alma = sum/wsum;
return(alma);
}
// MA_Method=23: TEMA - Triple Exponential Moving Average by Patrick Mulloy
double TEMA(int index,double price,int per,double v,int bar)
{
double alpha = 2.0/(per+1);
if(bar == Bars - 2) {tmp[0][index][0] = price; tmp[1][index][0] = price; tmp[2][index][0] = price;}
else
if(bar < Bars - 2)
{
tmp[0][index][0] = tmp[0][index][1] + alpha *(price - tmp[0][index][1]);
tmp[1][index][0] = tmp[1][index][1] + alpha *(tmp[0][index][0] - tmp[1][index][1]);
tmp[2][index][0] = tmp[2][index][1] + alpha *(tmp[1][index][0] - tmp[2][index][1]);
tmp[3][index][0] = tmp[0][index][0] + v*(tmp[0][index][0] + v*(tmp[0][index][0]-tmp[1][index][0]) - tmp[1][index][0] - v*(tmp[1][index][0] - tmp[2][index][0]));
}
return(tmp[3][index][0]);
}
// MA_Method=24: T3 by T.Tillson (correct version)
double T3(int index,int num,double price,int per,double v,int bar)
{
double len = MathMax((per + 5.0)/3.0-1,1), dema1, dema2;
if(bar == Bars - 2)
{
double T3 = price;
for(int k=0;k<6;k++) tmp[num+k][index][0] = T3;
}
else
if(bar < Bars - 2)
{
dema1 = DEMA(index,num ,price,len,v,bar);
dema2 = DEMA(index,num+2,dema1,len,v,bar);
T3 = DEMA(index,num+4,dema2,len,v,bar);
}
return(T3);
}
// MA_Method=25: Laguerre filter by J.Ehlers
double Laguerre(int index,double price,int per,int order,int bar)
{
double gamma = 1-10.0/(per+9);
double aPrice[];
ArrayResize(aPrice,order);
for(int i=0;i<order;i++)
{
if(bar >= Bars - order) tmp[i][index][0] = price;
else
{
if(i == 0) tmp[i][index][0] = (1 - gamma)*price + gamma*tmp[i][index][1];
else
tmp[i][index][0] = -gamma * tmp[i-1][index][0] + tmp[i-1][index][1] + gamma * tmp[i][index][1];
aPrice[i] = tmp[i][index][0];
}
}
double laguerre = TriMA_gen(aPrice,order,0);
return(laguerre);
}