//+——————————————————————+
//| AllClusterFilter_v1.1 600+.mq4 |
//| Copyright © 2018, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+——————————————————————+
#property copyright “Copyright © 2018, TrendLaboratory”
#property link “http://finance.groups.yahoo.com/group/TrendLaboratory”
#property link “http://newdigital-world.com/forum.php”
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 clrTomato
#property indicator_width1 2
#property indicator_color2 clrDeepSkyBlue
#property indicator_width2 2
#property indicator_color3 clrDeepSkyBlue
#property indicator_width3 2
enum ENUM_MA_MODE
{
SMA, // Simple Moving Average
EMA, // Exponential Moving Average
Wilder, // Wilder Exponential Moving Average
LWMA, // Linear Weighted Moving Average
SineWMA, // Sine Weighted Moving Average
TriMA, // Triangular Moving Average
LSMA, // Least Square Moving Average (or EPMA, Linear Regression Line)
SMMA, // Smoothed Moving Average
HMA, // Hull Moving Average by A.Hull
ZeroLagEMA, // Zero-Lag Exponential Moving Average
DEMA, // Double Exponential Moving Average by P.Mulloy
T3_basic, // T3 by T.Tillson (original version)
ITrend, // Instantaneous Trendline by J.Ehlers
Median, // Moving Median
GeoMean, // Geometric Mean
REMA, // Regularized EMA by C.Satchwell
ILRS, // Integral of Linear Regression Slope
IE_2, // Combination of LSMA and ILRS
TriMAgen, // Triangular Moving Average generalized by J.Ehlers
VWMA, // Volume Weighted Moving Average
JSmooth, // M.Jurik’s Smoothing
SMA_eq, // Simplified SMA
ALMA, // Arnaud Legoux Moving Average
TEMA, // Triple Exponential Moving Average by P.Mulloy
T3, // T3 by T.Tillson (correct version)
Laguerre, // Laguerre filter by J.Ehlers
MD, // McGinley Dynamic
BF2P, // Two-pole modified Butterworth filter by J.Ehlers
BF3P, // Three-pole modified Butterworth filter by J.Ehlers
SuperSmu, // SuperSmoother by J.Ehlers
Decycler, // Simple Decycler by J.Ehlers
eVWMA // Modified eVWMA
};
enum ENUM_PRICE
{
close, // Close
open, // Open
high, // High
low, // Low
median, // Median
typical, // Typical
weightedClose, // Weighted Close
medianBody, // Median Body (Open+Close)/2
average, // Average (High+Low+Open+Close)/4
trendBiased, // Trend Biased
haClose, // Heiken Ashi Close
haOpen, // Heiken Ashi Open
haHigh, // Heiken Ashi High
haLow, // Heiken Ashi Low
haMedian, // Heiken Ashi Median
haTypical, // Heiken Ashi Typical
haWeighted, // Heiken Ashi Weighted Close
haMedianBody, // Heiken Ashi Median Body
haAverage, // Heiken Ashi Average
haTrendBiased // Heiken Ashi Trend Biased
};
#define pi 3.14159265358979323846
//—-
input ENUM_TIMEFRAMES TimeFrame = 0; // TimeFrame
input ENUM_PRICE Price = 0; // Price
input int FirstMALength = 2; // First MA Period
input ENUM_MA_MODE FirstMAMode = 1; // First MA Method
input int SecondMALength = 2; // Second MA Period
input ENUM_MA_MODE SecondMAMode = 0; // Second MA Method
input bool ShowInColor = true; // Show In Color
input int CountBars = 0; // Number of bars counted: 0-all bars
double cluster[];
double uptrend1[];
double uptrend2[];
double iprice[];
double firstMA[];
double secondMA[];
double trend[];
int timeframe, sumlength, cBars, draw_begin, firstsize, secondsize;
string IndicatorName, TF, short_name;
//+——————————————————————+
//| |
//+——————————————————————+
int OnInit()
{
timeframe = TimeFrame;
if(timeframe <= Period()) timeframe = Period();
TF = tf(timeframe);
IndicatorDigits(_Digits);
//—-
IndicatorBuffers(7);
SetIndexBuffer(0, cluster); SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(1,uptrend1); SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(2,uptrend2); SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(3, iprice);
SetIndexBuffer(4, firstMA);
SetIndexBuffer(5,secondMA);
SetIndexBuffer(6, trend);
//—-
firstsize = averageSize(FirstMAMode );
secondsize = averageSize(SecondMAMode);
IndicatorName = WindowExpertName();
short_name = IndicatorName+”[“+TF+”](“+Price+”,”+FirstMALength+”,”+FirstMAMode+”,”+SecondMALength+”,”+SecondMAMode+”)”;
IndicatorShortName(short_name);
SetIndexLabel(0,”AllClusterFilter”);
//—-
sumlength = FirstMALength+SecondMALength;//MathMax(FirstMALength,SecondMALength);
if(CountBars == 0) cBars = timeframe/Period()*(iBars(NULL,TimeFrame) – sumlength); else cBars = CountBars*timeframe/Period();
draw_begin = Bars – cBars;
SetIndexDrawBegin(0,draw_begin);
SetIndexDrawBegin(1,draw_begin);
SetIndexDrawBegin(2,draw_begin);
//—-
ArrayResize(tmp,MathMax(firstsize,secondsize));
return(INIT_SUCCEEDED);
}
//+——————————————————————+
//| AllClusterFilter_v1.1 600+ |
//+——————————————————————+
int start()
{
int shift, limit, counted_bars = IndicatorCounted();
if(counted_bars > 0) limit = Bars – counted_bars – 1;
if(counted_bars < 0) return(0);
if(counted_bars < 1)
{
limit = MathMin(Bars – 1,(cBars + sumlength)*timeframe/Period());
for(int i=Bars-1;i>=0;i–)
{
cluster[i] = EMPTY_VALUE;
uptrend1[i] = EMPTY_VALUE;
uptrend2[i] = EMPTY_VALUE;
}
}
if(timeframe != Period())
{
limit = MathMax(limit,timeframe/Period());
for(shift = 0;shift < limit;shift++)
{
int y = iBarShift(NULL,timeframe,Time[shift]);
cluster[shift] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,FirstMALength,FirstMAMode,SecondMALength,SecondMAMode,ShowInColor,CountBars,0,y);
if(ShowInColor)
{
trend[shift] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,FirstMALength,FirstMAMode,SecondMALength,SecondMAMode,ShowInColor,CountBars,6,y);
uptrend1[shift] = EMPTY_VALUE;
if(trend[shift] > 0) uptrend1[shift] = cluster[shift];
}
}
if(ShowInColor)
{
for(shift=limit;shift>=0;shift–)
{
uptrend2[shift] = EMPTY_VALUE;
if(cluster[shift] > cluster[shift+1])
{
uptrend2[shift] = cluster[shift];
uptrend2[shift+1] = cluster[shift+1];
}
}
}
if(CountBars > 0)
{
SetIndexDrawBegin(0,Bars – cBars);
SetIndexDrawBegin(1,Bars – cBars);
SetIndexDrawBegin(2,Bars – cBars);
}
return(0);
}
for(shift=limit;shift>=0;shift–)
{
if((int)Price <= 9) iprice[shift] = getPrice((int)Price,shift);
else
if((int)Price > 9 && (int)Price <= 19) iprice[shift] = HeikenAshi(0,(int)Price-10,cBars+sumlength,shift);
firstMA[shift] = allAveragesOnArray(0,iprice,FirstMALength ,(int)FirstMAMode ,firstsize ,MathMin(Bars-1,cBars+sumlength)-FirstMALength ,shift);
secondMA[shift] = allAveragesOnArray(1,iprice,SecondMALength,(int)SecondMAMode,secondsize,MathMin(Bars-1,cBars+sumlength)-SecondMALength,shift);
clusterFilter(firstMA,secondMA,cBars,shift);
trend[shift] = trend[shift+1];
if(cluster[shift] > cluster[shift+1]) trend[shift] = 1;
if(cluster[shift] < cluster[shift+1]) trend[shift] =-1;
if(ShowInColor)
{
uptrend1[shift] = EMPTY_VALUE;
uptrend2[shift] = EMPTY_VALUE;
for(i=0;i<2;i++)
{
if(trend[shift+i] == 1)
{
if(uptrend1[shift+1+i] == EMPTY_VALUE)
{
if(uptrend1[shift+2+i] == EMPTY_VALUE)
{
uptrend1[shift+i] = cluster[shift+i];
uptrend1[shift+1+i] = cluster[shift+1+i];
uptrend2[shift+i] = EMPTY_VALUE;
}
else
{
uptrend2[shift+i] = cluster[shift+i];
uptrend2[shift+1+i] = cluster[shift+1+i];
uptrend1[shift+i] = EMPTY_VALUE;
}
}
else
{
uptrend1[shift+i] = cluster[shift+i];
uptrend2[shift+i] = EMPTY_VALUE;
}
}
}
}
}
if(CountBars > 0)
{
SetIndexDrawBegin(0,Bars – cBars);
SetIndexDrawBegin(1,Bars – cBars);
SetIndexDrawBegin(2,Bars – cBars);
}
return(0);
}
void clusterFilter(double& firstma[],double& secondma[],int cbars,int bar)
{
if(bar == cbars) cluster[bar] = firstma[bar];
else
{
if(cluster[bar+1] > cluster[bar+2])
{
if(cluster[bar+1] < firstma[bar] && cluster[bar+1] < secondma[bar])
{
cluster[bar] = fmin(firstma[bar],secondma[bar]);
return;
}
if(cluster[bar+1] < firstma[bar] && cluster[bar+1] > secondma[bar])
{
cluster[bar] = firstma[bar];
return;
}
if(cluster[bar+1] > firstma[bar] && cluster[bar+1] < secondma[bar])
{
cluster[bar] = secondma[bar];
return;
}
cluster[bar] = fmax(firstma[bar],secondma[bar]);
}
else
{
if(cluster[bar+1] > firstma[bar] && cluster[bar+1] > secondma[bar])
{
cluster[bar] = fmax(firstma[bar],secondma[bar]);
return;
}
if(cluster[bar+1] > firstma[bar] && cluster[bar+1] < secondma[bar])
{
cluster[bar] = firstma[bar];
return;
}
if(cluster[bar+1] < firstma[bar] && cluster[bar+1] > secondma[bar])
{
cluster[bar] = secondma[bar];
return;
}
cluster[bar] = fmin(firstma[bar],secondma[bar]);
}
}
}
//—————-
int averageSize(int mode)
{
int arraysize;
switch(mode)
{
case DEMA : arraysize = 2; break;
case T3_basic : arraysize = 6; break;
case JSmooth : arraysize = 5; break;
case TEMA : arraysize = 4; break;
case T3 : arraysize = 6; break;
case Laguerre : arraysize = 4; break;
default : arraysize = 0; break;
}
return(arraysize);
}
double tmp[][2][2], ma[2][4];
datetime prevtime[2];
double allAveragesOnArray(int index,double& price[],int period,int mode,int arraysize,int cbars,int bar)
{
if(period == 1) return(price[bar]);
int i;
double MA[4];
switch(mode)
{
case EMA: case Wilder: case SMMA: case ZeroLagEMA: case DEMA: case T3_basic: case ITrend: case REMA: case JSmooth: case SMA_eq: case TEMA: case T3: case Laguerre: case MD: case BF2P: case BF3P: case SuperSmu: case Decycler: case eVWMA:
if(prevtime[index] != Time[bar])
{
ma[index][3] = ma[index][2];
ma[index][2] = ma[index][1];
ma[index][1] = ma[index][0];
if(arraysize > 0) for(i=0;i<arraysize;i++) tmp[i][index][1] = tmp[i][index][0];
prevtime[index] = Time[bar];
}
if(mode == ITrend || mode == REMA || mode == SMA_eq || (mode >= BF2P && mode < eVWMA)) for(i=0;i<4;i++) MA[i] = ma[index][i];
}
switch(mode)
{
case EMA : ma[index][0] = EMAOnArray(price[bar],ma[index][1],period,cbars,bar); break;
case Wilder : ma[index][0] = WilderOnArray(price[bar],ma[index][1],period,cbars,bar); break;
case LWMA : ma[index][0] = LWMAOnArray(price,period,bar); break;
case SineWMA : ma[index][0] = SineWMAOnArray(price,period,bar); break;
case TriMA : ma[index][0] = TriMAOnArray(price,period,bar); break;
case LSMA : ma[index][0] = LSMAOnArray(price,period,bar); break;
case SMMA : ma[index][0] = SMMAOnArray(price,ma[index][1],period,cbars,bar); break;
case HMA : ma[index][0] = HMAOnArray(price,period,cbars,bar); break;
case ZeroLagEMA: ma[index][0] = ZeroLagEMAOnArray(price,ma[index][1],period,cbars,bar); break;
case DEMA : ma[index][0] = DEMAOnArray(index,0,price[bar],period,1,cbars,bar); break;
case T3_basic : ma[index][0] = T3_basicOnArray(index,0,price[bar],period,0.7,cbars,bar); break;
case ITrend : ma[index][0] = ITrendOnArray(price,MA,period,cbars,bar); break;
case Median : ma[index][0] = MedianOnArray(price,period,cbars,bar); break;
case GeoMean : ma[index][0] = GeoMeanOnArray(price,period,cbars,bar); break;
case REMA : ma[index][0] = REMAOnArray(price[bar],MA,period,0.5,cbars,bar); break;
case ILRS : ma[index][0] = ILRSOnArray(price,period,cbars,bar); break;
case IE_2 : ma[index][0] = IE2OnArray(price,period,cbars,bar); break;
case TriMAgen : ma[index][0] = TriMA_genOnArray(price,period,cbars,bar); break;
case VWMA : ma[index][0] = VWMAOnArray(price,period,bar); break;
case JSmooth : ma[index][0] = JSmoothOnArray(index,0,price[bar],period,1,cbars,bar); break;
case SMA_eq : ma[index][0] = SMA_eqOnArray(price,MA,period,cbars,bar); break;
case ALMA : ma[index][0] = ALMAOnArray(price,period,0.85,8,bar); break;
case TEMA : ma[index][0] = TEMAOnArray(index,price[bar],period,1,cbars,bar); break;
case T3 : ma[index][0] = T3OnArray(index,0,price[bar],period,0.7,cbars,bar); break;
case Laguerre : ma[index][0] = LaguerreOnArray(index,price[bar],period,4,cbars,bar); break;
case MD : ma[index][0] = McGinleyOnArray(price[bar],ma[index][1],period,cbars,bar); break;
case BF2P : ma[index][0] = BF2POnArray(price,MA,period,cbars,bar); break;
case BF3P : ma[index][0] = BF3POnArray(price,MA,period,cbars,bar); break;
case SuperSmu : ma[index][0] = SuperSmuOnArray(price,MA,period,cbars,bar); break;
case Decycler : ma[index][0] = DecyclerOnArray(price,MA,period,cbars,bar); return(price[bar] – ma[index][0]);
case eVWMA : ma[index][0] = eVWMAOnArray(price[bar],ma[index][1],period,cbars,bar); break;
default : ma[index][0] = SMAOnArray(price,period,bar); break;
}
return(ma[index][0]);
}
// MA_Method=0: SMA – Simple Moving Average
double SMAOnArray(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 EMAOnArray(double price,double prev,int per,int cbars,int bar)
{
double ema;
if(bar >= cbars) ema = price;
else
ema = prev + 2.0/(1 + per)*(price – prev);
return(ema);
}
// MA_Method=2: Wilder – Wilder Exponential Moving Average
double WilderOnArray(double price,double prev,int per,int cbars,int bar)
{
double wilder;
if(bar >= cbars) wilder = price;
else
wilder = prev + (price – prev)/per;
return(wilder);
}
// MA_Method=3: LWMA – Linear Weighted Moving Average
double LWMAOnArray(double& array[],int per,int bar)
{
double sum = 0, weight = 0;
for(int i=0;i<per;i++)
{
weight += (per – i);
sum += array[bar+i]*(per – i);
}
if(weight > 0) return(sum/weight); else return(0);
}
// MA_Method=4: SineWMA – Sine Weighted Moving Average
double SineWMAOnArray(double& array[],int per,int bar)
{
double sum = 0, 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) return(sum/weight); else return(0);
}
// MA_Method=5: TriMA – Triangular Moving Average
double TriMAOnArray(double& array[],int per,int bar)
{
int len = (int)MathCeil((per + 1)*0.5);
double sum = 0;
for(int i=0;i<len;i++) sum += SMAOnArray(array,len,bar+i);
return(sum/len);
}
// MA_Method=6: LSMA – Least Square Moving Average (or EPMA, Linear Regression Line)
double LSMAOnArray(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];
return(sum*6/(per*(per + 1)));
}
// MA_Method=7: SMMA – Smoothed Moving Average
double SMMAOnArray(double& array[],double prev,int per,int cbars,int bar)
{
double smma = 0;
if(bar == cbars) smma = SMAOnArray(array,per,bar);
else
if(bar < cbars)
{
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 HMAOnArray(double& array[],int per,int cbars,int bar)
{
double hma = 0, _tmp[];
int len = (int)MathSqrt(per);
ArrayResize(_tmp,len);
if(bar == cbars) hma = array[bar];
else
if(bar < cbars)
{
for(int i=0;i<len;i++) _tmp[i] = 2*LWMAOnArray(array,per/2,bar+i) – LWMAOnArray(array,per,bar+i);
hma = LWMAOnArray(_tmp,len,0);
}
return(hma);
}
// MA_Method=9: ZeroLagEMA – Zero-Lag Exponential Moving Average
double ZeroLagEMAOnArray(double& price[],double prev,int per,int cbars,int bar)
{
int lag = (int)0.5*(per – 1);
double zema, alpha = 2.0/(1 + per);
if(bar >= cbars) zema = price[bar];
else
zema = alpha*(2*price[bar] – price[bar+lag]) + (1 – alpha)*prev;
return(zema);
}
// MA_Method=10: DEMA – Double Exponential Moving Average by Patrick Mulloy
double DEMAOnArray(int index,int num,double price,double per,double v,int cbars,int bar)
{
double dema = 0, alpha = 2.0/(1 + per);
if(bar == cbars) {dema = price; tmp[num][index][0] = dema; tmp[num+1][index][0] = dema;}
else
if(bar < cbars)
{
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_basicOnArray(int index,int num,double price,int per,double v,int cbars,int bar)
{
double dema1, dema2, T3 = 0;
if(bar == cbars)
{
T3 = price;
for(int k=0;k<6;k++) tmp[num+k][index][0] = price;
}
else
if(bar < cbars)
{
dema1 = DEMAOnArray(index,num ,price,per,v,cbars,bar);
dema2 = DEMAOnArray(index,num+2,dema1,per,v,cbars,bar);
T3 = DEMAOnArray(index,num+4,dema2,per,v,cbars,bar);
}
return(T3);
}
// MA_Method=12: ITrend – Instantaneous Trendline by J.Ehlers
double ITrendOnArray(double& price[],double& array[],int per,int cbars,int bar)
{
double it = 0, alpha = 2.0/(per + 1);
if(bar < cbars && array[1] > 0 && array[2] > 0) it = (alpha – 0.25*alpha*alpha)*price[bar] + 0.5*alpha*alpha*price[bar+1]
-(alpha – 0.75*alpha*alpha)*price[bar+2] + 2*(1 – alpha)*array[1]
-(1 – alpha)*(1 – alpha)*array[2];
else it = (price[bar] + 2*price[bar+1] + price[bar+2])/4;
return(it);
}
// MA_Method=13: Median – Moving Median
double MedianOnArray(double& price[],int per,int cbars,int bar)
{
double median = 0, array[];
ArrayResize(array,per);
if(bar < cbars)
{
for(int i=0;i<per;i++) array[i] = price[bar+i];
ArraySort(array,WHOLE_ARRAY,0,MODE_DESCEND);
int num = (int)MathRound((per – 1)*0.5);
if(MathMod(per,2) > 0) median = array[num]; else median = 0.5*(array[num] + array[num+1]);
}
return(median);
}
// MA_Method=14: GeoMean – Geometric Mean
double GeoMeanOnArray(double& price[],int per,int cbars,int bar)
{
double gmean = 0;
if(bar < cbars)
{
gmean = MathPow(price[bar],1.0/per);
for(int i=1;i<per;i++) gmean *= MathPow(price[bar+i],1.0/per);
}
else
if(bar == cbars) gmean = SMAOnArray(price,per,bar);
return(gmean);
}
// MA_Method=15: REMA – Regularized EMA by Chris Satchwell
double REMAOnArray(double price,double& array[],int per,double lambda,int cbars,int bar)
{
double rema, alpha = 2.0/(per + 1);
if(bar < cbars && array[1] > 0 && array[2] > 0) rema = (array[1]*(1 + 2*lambda) + alpha*(price – array[1]) – lambda*array[2])/(1 + lambda);
else rema = price;
return(rema);
}
// MA_Method=16: ILRS – Integral of Linear Regression Slope
double ILRSOnArray(double& price[],int per,int cbars,int bar)
{
double slope, sum = per*(per – 1)*0.5;
double ilrs = 0, sum2 = (per – 1)*per*(2*per – 1)/6.0;
if(bar < cbars)
{
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) slope = num1/num2; else slope = 0;
ilrs = slope + SMAOnArray(price,per,bar);
}
return(ilrs);
}
// MA_Method=17: IE/2 – Combination of LSMA and ILRS
double IE2OnArray(double& price[],int per,int cbars,int bar)
{
double ie = 0;
if(bar < cbars) ie = 0.5*(ILRSOnArray(price,per,cbars,bar) + LSMAOnArray(price,per,bar));
return(ie);
}
// MA_Method=18: TriMAgen – Triangular Moving Average Generalized by J.Ehlers
double TriMA_genOnArray(double& array[],int per,int cbars,int bar)
{
int len1 = (int)MathFloor((per + 1)*0.5);
int len2 = (int)MathCeil ((per + 1)*0.5);
double sum = 0;
if(bar < cbars)
for(int i = 0;i < len2;i++) sum += SMAOnArray(array,len1,bar+i);
return(sum/len2);
}
// MA_Method=19: VWMA – Volume Weighted Moving Average
double VWMAOnArray(double& array[],int per,int bar)
{
double sum = 0, weight = 0;
for(int i=0;i<per;i++)
{
weight += (double)Volume[bar+i];
sum += array[bar+i]*Volume[bar+i];
}
if(weight > 0) return(sum/weight); else return(0);
}
// MA_Method=20: JSmooth – Smoothing by Mark Jurik
double JSmoothOnArray(int index,int num,double price,int per,double power,int cbars,int bar)
{
double beta = 0.45*(per – 1)/(0.45*(per – 1) + 2);
double alpha = MathPow(beta,power);
if(bar == cbars) {tmp[num+4][index][0] = price; tmp[num+0][index][0] = price; tmp[num+2][index][0] = price;}
else
if(bar < cbars)
{
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_eqOnArray(double& price[],double& array[],int per,int cbars,int bar)
{
double sma = 0;
if(bar == cbars) sma = SMAOnArray(price,per,bar);
else
if(bar < cbars) sma = (price[bar] – price[bar+per])/per + array[1];
return(sma);
}
// MA_Method=22: ALMA by Arnaud Legoux / Dimitris Kouzis-Loukas / Anthony Cascino
double ALMAOnArray(double& price[],int per,double offset,double sigma,int bar)
{
double m = MathFloor(offset*(per – 1)), s = per/sigma, 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) return(sum/wsum); else return(0);
}
// MA_Method=23: TEMA – Triple Exponential Moving Average by Patrick Mulloy
double TEMAOnArray(int index,double price,int per,double v,int cbars,int bar)
{
double alpha = 2.0/(per+1);
if(bar == cbars) {tmp[0][index][0] = price; tmp[1][index][0] = price; tmp[2][index][0] = price;}
else
if(bar < cbars)
{
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 T3OnArray(int index,int num,double price,int per,double v,int cbars,int bar)
{
double len = MathMax((per + 5.0)/3.0 – 1,1), dema1, dema2, T3 = 0;
if(bar == cbars )
{
T3 = price;
for(int k=0;k<6;k++) tmp[num+k][index][0] = T3;
}
else
if(bar < cbars)
{
dema1 = DEMAOnArray(index,num ,price,len,v,cbars,bar);
dema2 = DEMAOnArray(index,num+2,dema1,len,v,cbars,bar);
T3 = DEMAOnArray(index,num+4,dema2,len,v,cbars,bar);
}
return(T3);
}
// MA_Method=25: Laguerre filter by J.Ehlers
double LaguerreOnArray(int index,double price,int per,int order,int cbars,int bar)
{
double gamma = 1 – 10.0/(per + 9);
double aPrice[];
ArrayResize(aPrice,order);
for(int i=0;i<order;i++)
{
if(bar >= cbars) 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_genOnArray(aPrice,order,cbars,0);
return(laguerre);
}
// MA_Method=26: MD – McGinley Dynamic
double McGinleyOnArray(double price,double prev,int per,int cbars,int bar)
{
double md = 0;
if(bar == cbars) md = price;
else
if(bar < cbars)
if(prev != 0) md = prev + (price – prev)/(per*MathPow(price/prev,4)/2);
else md = price;
return(md);
}
// MA_Method=27: BF2P – Two-pole modified Butterworth filter
double BF2POnArray(double& price[],double& array[],int per,int cbars,int bar)
{
double a = MathExp(-1.414*pi/per);
double b = 2*a*MathCos(1.414*1.25*pi/per);
double c2 = b;
double c3 = -a*a;
double c1 = 1 – c2 – c3, bf2p;
if(bar < cbars && array[1] > 0 && array[2] > 0) {bf2p = c1*(price[bar] + 2*price[bar+1] + price[bar+2])/4 + c2*array[1] + c3*array[2];
if(bar == cbars-1) Print(“bar=”,bar,” cbars=”,cbars,” bf2p=”,bf2p,” array[1]=”,array[1],” array[2]=”,array[2]);
}
else bf2p = (price[bar] + 2*price[bar+1] + price[bar+2])/4;
return(bf2p);
}
// MA_Method=28: BF3P – Three-pole modified Butterworth filter
double BF3POnArray(double& price[],double& array[],int per,int cbars,int bar)
{
double a = MathExp(-pi/per);
double b = 2*a*MathCos(1.738*pi/per);
double c = a*a;
double d2 = b + c;
double d3 = -(c + b*c);
double d4 = c*c;
double d1 = 1 – d2 – d3 – d4, bf3p;
if(bar < cbars && array[1] > 0 && array[2] > 0 && array[3] > 0) bf3p = d1*(price[bar] + 3*price[bar+1] + 3*price[bar+2] + price[bar+3])/8 + d2*array[1] + d3*array[2] + d4*array[3];
else bf3p = (price[bar] + 3*price[bar+1] + 3*price[bar+2] + price[bar+3])/8;
return(bf3p);
}
// MA_Method=29: SuperSmu – SuperSmoother filter
double SuperSmuOnArray(double& price[],double& array[],int per,int cbars,int bar)
{
double a = MathExp(-1.414*pi/per);
double b = 2*a*MathCos(1.414*pi/per);
double c2 = b;
double c3 = -a*a;
double c1 = 1 – c2 – c3, supsm;
if(bar < cbars && array[1] > 0 && array[2] > 0) supsm = c1*(price[bar] + price[bar+1])/2 + c2*array[1] + c3*array[2]; else supsm = (price[bar] + price[bar+1])/2;
return(supsm);
}
// MA_Method=30: Decycler – Simple Decycler by J.Ehlers
double DecyclerOnArray(double& price[],double& hp[],int per,int cbars,int bar)
{
double alpha1 = (MathCos(1.414*pi/per) + MathSin(1.414*pi/per) – 1)/MathCos(1.414*pi/per);
if(bar > cbars – 4) return(0);
hp[0] = (1 – alpha1/2)*(1 – alpha1/2)*(price[bar] – 2*price[bar+1] + price[bar+2]) + 2*(1 – alpha1)*hp[1] – (1 – alpha1)*(1 – alpha1)*hp[2];
return(hp[0]);
}
// MA_Method=31: eVWMA – Elastic Volume Weighted Moving Average by C.Fries
double eVWMAOnArray(double price,double prev,int per,int cbars,int bar)
{
double evwma;
if(bar < cbars && prev > 0)
{
double max = 0;
for(int i=0;i<per;i++) max = MathMax(max,Volume[bar+i]);
double diff = 3*max – Volume[bar];
if(diff < 0) evwma = prev;
else
evwma = (diff*prev + Volume[bar]*price)/(3*max);
}
else evwma = price;
return(evwma);
}
double getPrice(int price,int bar)
{
double close = Close[bar];
double open = Open [bar];
double high = High [bar];
double low = Low [bar];
switch(price)
{
case 0: return(close); break;
case 1: return(open ); break;
case 2: return(high ); break;
case 3: return(low ); break;
case 4: return((high + low)/2); break;
case 5: return((high + low + close)/3); break;
case 6: return((high + low + 2*close)/4); break;
case 7: return((close + open)/2); break;
case 8: return((high + low + close + open)/4); break;
case 9: if(close > open) return((high + close)/2); else return((low + close)/2); break;
default: return(close); break;
}
}
// HeikenAshi Price
double haClose[1][2], haOpen[1][2], haHigh[1][2], haLow[1][2];
datetime prevhatime[1];
double HeikenAshi(int index,int price,int cbars,int bar)
{
if(prevhatime[index] != Time[bar])
{
haClose[index][1] = haClose[index][0];
haOpen [index][1] = haOpen [index][0];
haHigh [index][1] = haHigh [index][0];
haLow [index][1] = haLow [index][0];
prevhatime[index] = Time[bar];
}
if(bar == cbars – 1)
{
haClose[index][0] = Close[bar];
haOpen [index][0] = Open [bar];
haHigh [index][0] = High [bar];
haLow [index][0] = Low [bar];
}
else
{
haClose[index][0] = (Open[bar] + High[bar] + Low[bar] + Close[bar])/4;
haOpen [index][0] = (haOpen[index][1] + haClose[index][1])/2;
haHigh [index][0] = MathMax(High[bar],MathMax(haOpen[index][0],haClose[index][0]));
haLow [index][0] = MathMin(Low [bar],MathMin(haOpen[index][0],haClose[index][0]));
}
switch(price)
{
case 0: return(haClose[index][0]); break;
case 1: return(haOpen [index][0]); break;
case 2: return(haHigh [index][0]); break;
case 3: return(haLow [index][0]); break;
case 4: return((haHigh [index][0] + haLow [index][0])/2); break;
case 5: return((haHigh[index][0] + haLow[index][0] + haClose[index][0])/3); break;
case 6: return((haHigh[index][0] + haLow[index][0] + 2*haClose[index][0])/4); break;
case 7: return((haClose[index][0] + haOpen[index][0])/2); break;
case 8: return((haHigh[index][0] + haLow[index][0] + haClose[index][0] + haOpen[index][0])/4); break;
case 9: if(haClose[index][0] > haOpen[index][0]) return((haHigh[index][0] + haClose[index][0])/2); else return((haLow[index][0] + haClose[index][0])/2); break;
default: return(haClose[index][0]); break;
}
}
string tf(int itimeframe)
{
string result = “”;
switch(itimeframe)
{
case PERIOD_M1: result = “M1” ;
case PERIOD_M5: result = “M5” ;
case PERIOD_M15: result = “M15”;
case PERIOD_M30: result = “M30”;
case PERIOD_H1: result = “H1” ;
case PERIOD_H4: result = “H4” ;
case PERIOD_D1: result = “D1” ;
case PERIOD_W1: result = “W1” ;
case PERIOD_MN1: result = “MN1”;
default: result = “N/A”;
}
if(result == “N/A”)
{
if(itimeframe < PERIOD_H1 ) result = “M” + itimeframe;
if(itimeframe >= PERIOD_H1 ) result = “H” + itimeframe/PERIOD_H1;
if(itimeframe >= PERIOD_D1 ) result = “D” + itimeframe/PERIOD_D1;
if(itimeframe >= PERIOD_W1 ) result = “W” + itimeframe/PERIOD_W1;
if(itimeframe >= PERIOD_MN1) result = “MN” + itimeframe/PERIOD_MN1;
}
return(result);
}