Price Data Components
Miscellaneous
0
Views
0
Downloads
0
Favorites
HPMA102_v1
//+--------------------------------------------------------------------------+
//| HPMA.mq4 |
//| Hodrick-Prescott filter MA |
//| based on HP filter implementation by gwpr (http://codebase.mql4.com/5169)|
//+--------------------------------------------------------------------------+
#define IND "HPMA"
#define VER "1_02"
#property copyright "ryaz"
#property link "outta@here"
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 Gray
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_color4 Olive
#property indicator_color5 Indigo
#property indicator_color6 Indigo
#property indicator_color7 SeaGreen
#property indicator_color8 SeaGreen
//Input parameters
extern int nobs=150; //Number of bars to process for filter evaluation
extern double lambda=1600; //Higher lambda leads to the smoother data
extern int timeframe=0;//The applied timeframe, 0=the same as chart
extern int price=PRICE_CLOSE;//The applied price
extern int delay=0; //Shows the result of delaying (or advancing if negative) the HP filter
extern int trend=10; //how many consecutive filter bars to check to determine trend
extern int future=8; //How many bars in the future to display for the HP filter
extern int bands= 0; //how many bars to include in bands calculation
extern double band1 =2; //deviations for first band
extern double band2 =2; //deviations for second Band
extern int type1=-1; //Type for the first band -1=Filter Band or else Price Band 0=applied price 1=mean 2=exterme High/Low 3=inside High/Low 4=median 5=typical 6=weighted
extern int type2=0; //Type for second band as above
extern bool repaint =FALSE; //To repaint last bar, FALSE for faster execution
extern bool points =FALSE; //Plot up/downtrend as points instead of line
extern bool alerts =FALSE; //Enable visual alert
extern string audio="alert.wav"; //Enable audioalert
extern int history=500; //history bars to display on initialisation, 0 means all history
//Indicator buffers
double hp0[],hpu0[],hpd0[],hpf0[],fhi0[],flo0[],phi0[],plo0[];
//Global vars
double hp[],hpu[],hpd[],hpf[],fhi[],flo[],phi[],plo[];
double dat[],a[],b[],c[];
datetime time;
string tframe;
bool alerting;
bool showf;
//+----------------------------------------------------------------------------------------+
int init()
{
if(timeframe==0) timeframe=Period();
SetIndexBuffer(0,hp0);
SetIndexStyle(0,DRAW_LINE);
SetIndexLabel(0,"hpma");
SetIndexBuffer(1,hpu0);
SetIndexLabel(1,"up");
SetIndexBuffer(2,hpd0);
SetIndexLabel(2,"down");
if(points)
{
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,4);
SetIndexStyle(2,DRAW_ARROW);
SetIndexArrow(2,4);
} else {
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_LINE);
}
SetIndexBuffer(3,hpf0);
if(trend>0)
{
SetIndexStyle(3,DRAW_LINE);
SetIndexLabel(3,"filter");
SetIndexShift(3,future);
}
else
SetIndexStyle(3,DRAW_LINE);
SetIndexBuffer(4,fhi0);
SetIndexBuffer(5,flo0);
SetIndexBuffer(6,phi0);
SetIndexBuffer(7,plo0);
if(history==0) history=iBarShift(NULL,0,iTime(NULL,timeframe,iBars(NULL,timeframe)-nobs));
SetIndexDrawBegin(0,Bars-history);
SetIndexDrawBegin(1,Bars-history);
SetIndexDrawBegin(2,Bars-history);
SetIndexDrawBegin(3,Bars-history+future);
if(bands>0 && band1!=0)
{
SetIndexLabel(4,"Fhi");
SetIndexLabel(5,"Flo");
SetIndexStyle(4,DRAW_LINE);
SetIndexStyle(5,DRAW_LINE);
if(band1>0)
{
SetIndexDrawBegin(4,Bars-history);
SetIndexDrawBegin(5,Bars-history);
}
} else {
SetIndexStyle(4,DRAW_NONE);
SetIndexStyle(5,DRAW_NONE);
}
if(bands>0 && band2!=0)
{
SetIndexLabel(6,"Phi");
SetIndexLabel(7,"Plo");
SetIndexStyle(6,DRAW_LINE);
SetIndexStyle(7,DRAW_LINE);
if(band2>0)
{
SetIndexDrawBegin(6,Bars-history);
SetIndexDrawBegin(7,Bars-history);
}
} else {
SetIndexStyle(6,DRAW_NONE);
SetIndexStyle(7,DRAW_NONE);
}
ArrayResize(hpf,nobs);
ArrayResize(dat,nobs);
ArrayResize(a,nobs);
ArrayResize(b,nobs);
ArrayResize(c,nobs);
time=Time[history-1];
if(lambda<1) lambda=MathExp(-lambda);
switch(timeframe)
{
case 60:{tframe="H1";break;}
case 240:{tframe="H4";break;}
case 1440:{tframe="D1";break;}
case 10080:{tframe="W1";break;}
case 43200:{tframe="MN1";break;}
default:tframe="M"+Period();
}
IndicatorShortName(IND+"("+tframe+")");
tframe=Symbol()+" "+tframe+": ";
history=MathMax(iBarShift(NULL,timeframe,time),bands);
ArrayResize(hp,history);
ArrayResize(hpu,history);
ArrayResize(hpd,history);
ArrayResize(fhi,history);
ArrayResize(flo,history);
ArrayResize(phi,history);
ArrayResize(plo,history);
alerting=alerts || audio!="";
showf=trend>0;
if(trend<0) trend=-trend;
return(0);
}
//+----------------------------------------------------------------------------------------+
int start()
{
double H1,H2,H3,H4,H5,HH1,HH2,HH3,HH4,HH5,HB,HC,Z,V;
int i,disp,bar,limit;
if(iBars(NULL,timeframe)<nobs) return(0);
limit=iBarShift(NULL,timeframe,time);
time=Time[0];
if(limit>=history) limit=history-2;
if(limit<history-1)
for(bar=history-limit-1; bar>=0; bar--)
{
hp[bar+limit] =hp[bar];
hpu[bar+limit]=hpu[bar];
hpd[bar+limit]=hpd[bar];
fhi[bar+limit]=fhi[bar];
flo[bar+limit]=flo[bar];
phi[bar+limit]=phi[bar];
plo[bar+limit]=plo[bar];
}
for(bar=history-limit-1; bar>=0; bar--)
{
hpu[bar]=EMPTY_VALUE;
hpd[bar]=EMPTY_VALUE;
fhi[bar]=EMPTY_VALUE;
flo[bar]=EMPTY_VALUE;
phi[bar]=EMPTY_VALUE;
plo[bar]=EMPTY_VALUE;
H1=0;H2=0;H3=0;H4=0;H5=0;HH1=0;HH2=0;HH3=0;HH4=0;HH5=0;
switch(price)
{
case PRICE_CLOSE:
{
for(i=0;i<nobs;i++) dat[i]=iClose(NULL,timeframe,bar+i);break;
}
case PRICE_OPEN:
{
for(i=0;i<nobs;i++)dat[i]=iOpen(NULL,timeframe,bar+i);break;
}
case PRICE_HIGH:
{
for(i=0;i<nobs;i++)dat[i]=iHigh(NULL,timeframe,bar+i);break;
}
case PRICE_LOW:
{
for(i=0;i<nobs;i++)dat[i]=iLow(NULL,timeframe,bar+i);break;
}
case PRICE_MEDIAN:
{
for(i=0;i<nobs;i++)dat[i]=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i))/2;break;
}
case PRICE_TYPICAL:
{
for(i=0;i<nobs;i++)dat[i]=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i)+iClose(NULL,timeframe,bar+i))/3;break;
}
case PRICE_WEIGHTED:
{
for(i=0;i<nobs;i++)dat[i]=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i)+2*iClose(NULL,timeframe,bar+i))/4;break;
}
default:
for(i=0;i<nobs;i++) dat[i]=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i)+iOpen(NULL,timeframe,bar+i)+iClose(NULL,timeframe,bar+i))/4;
}
V=dat[0];
a[0]=1.0+lambda;
b[0]=-2.0*lambda;
c[0]=lambda;
for(i=1;i<nobs-2;i++)
{
a[i]=6.0*lambda+1.0;
b[i]=-4.0*lambda;
c[i]=lambda;
}
a[1]=5.0*lambda+1;
a[nobs-1]=1.0+lambda;
a[nobs-2]=5.0*lambda+1.0;
b[nobs-2]=-2.0*lambda;
b[nobs-1]=0.0;
c[nobs-2]=0.0;
c[nobs-1]=0.0;
//Forward
for(i=0;i<nobs;i++)
{
Z=a[i]-H4*H1-HH5*HH2;
HB=b[i];
HH1=H1;
H1=(HB-H4*H2)/Z;
b[i]=H1;
HC=c[i];
HH2=H2;
H2=HC/Z;
c[i]=H2;
a[i]=(dat[i]-HH3*HH5-H3*H4)/Z;
HH3=H3;
H3=a[i];
H4=HB-H5*HH1;
HH5=H5;
H5=HC;
}
//Backward
H2=0;
H1=a[nobs-1];
hpf[nobs-1]=H1;
for(i=nobs-2;i>=0;i--)
{
hpf[i]=a[i]-b[i]*H1-c[i]*H2;
H2=H1;
H1=hpf[i];
}
hp[bar]=hpf[0];
if((bar+1<ArraySize(hpu)-1) && hpu[bar+1]==EMPTY_VALUE && (hp[bar]<hp[bar+1] || V<hp[bar]))
hpu[bar]=EMPTY_VALUE;
else if(trend>0)
{
for(i=0; i<trend; i++)
if(hpf[i]<hpf[i+1]) break;
if(i<trend)
hpu[bar]=EMPTY_VALUE;
else
hpu[bar]=hpf[0];
} else {
if(hp[bar]<hp[bar+1])
hpu[bar]=EMPTY_VALUE;
else
hpu[bar]=hpf[0];
}
if((bar+1<ArraySize(hpu)-1) && hpd[bar+1]==EMPTY_VALUE && (hp[bar]>hp[bar+1] || V>hp[bar]))
hpd[bar]=EMPTY_VALUE;
else if(trend>0)
{
for(i=0; i<trend; i++)
if(hpf[i]>hpf[i+1]) break;
if(i<trend)
hpd[bar]=EMPTY_VALUE;
else
hpd[bar]=hpf[0];
} else {
if(hp[bar]>hp[bar+1])
hpd[bar]=EMPTY_VALUE;
else
hpd[bar]=hpf[0];
}
if(bands>0 && (band1>0 || (band1<0 && bar==0)))
{
Z=0;
for(i=0; i<bands; i++)
{
V=hpf[i];
switch(type1)
{
case -1: {V-=hp[bar+i];break;}
case 0: {V-=dat[i];break;}
case 1: {V-=(2*(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i))+iOpen(NULL,timeframe,bar+i)+iClose(NULL,timeframe,bar+i))/6;break;}
case 2: {V=MathMax(MathAbs(iHigh(NULL,timeframe,bar+i)-V),MathAbs(iLow(NULL,timeframe,bar+i)-V));break;}
case 3: {V=MathMin(MathAbs(iHigh(NULL,timeframe,bar+i)-V),MathAbs(iLow(NULL,timeframe,bar+i)-V));break;}
case 4: {V-=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i))/2;break;}
case 5: {V-=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i)+iClose(NULL,timeframe,bar+i))/3;break;}
case 6: {V-=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i)+2*iClose(NULL,timeframe,bar+i))/4;break;}
default: V-=iClose(NULL,timeframe,bar+i);
}
Z+=V*V;
}
Z=band1*MathSqrt(Z/bands);
if(band1>0)
{
fhi[bar]=hp[bar]+Z;
flo[bar]=hp[bar]-Z;
} else {
limit=iBarShift(NULL,0,iTime(NULL,timeframe,nobs-1));
SetIndexDrawBegin(6,limit);
SetIndexDrawBegin(7,limit);
for(i=0; i<nobs; i++)
{
fhi[i]=hpf[i]-Z;
flo[i]=hpf[i]+Z;
}
}
}
if(bands>0 && (band2>0 || (band2<0 && bar==0)))
{
Z=0;
for(i=0; i<bands; i++)
{
V=hpf[i];
switch(type2)
{
case -1: {V-=hp[bar+i];break;}
case 0: {V-=dat[i];break;}
case 1: {V-=(2*(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i))+iOpen(NULL,timeframe,bar+i)+iClose(NULL,timeframe,bar+i))/6;break;}
case 2: {V=MathMax(MathAbs(iHigh(NULL,timeframe,bar+i)-V),MathAbs(iLow(NULL,timeframe,bar+i)-V));break;}
case 3: {V=MathMin(MathAbs(iHigh(NULL,timeframe,bar+i)-V),MathAbs(iLow(NULL,timeframe,bar+i)-V));break;}
case 4: {V-=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i))/2;break;}
case 5: {V-=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i)+iClose(NULL,timeframe,bar+i))/3;break;}
case 6: {V-=(iHigh(NULL,timeframe,bar+i)+iLow(NULL,timeframe,bar+i)+2*iClose(NULL,timeframe,bar+i))/4;break;}
default: V-=iClose(NULL,timeframe,bar+i);
}
Z+=V*V;
}
Z=band2*MathSqrt(Z/bands);
if(band2>0)
{
phi[bar]=hp[bar]+Z;
plo[bar]=hp[bar]-Z;
} else {
limit=iBarShift(NULL,0,iTime(NULL,timeframe,nobs-1));
SetIndexDrawBegin(4,limit);
SetIndexDrawBegin(5,limit);
for(i=0; i<nobs; i++)
{
phi[i]=hpf[i]-Z;
plo[i]=hpf[i]+Z;
}
}
}
if(bar<history-1)
{
if(bar==0)
disp=0;
else if(timeframe<=Period())
disp=iBarShift(NULL,0,iTime(NULL,timeframe,bar));
else
disp=iBarShift(NULL,0,iTime(NULL,timeframe,bar-1))+1;
if(delay>=0)
hp0[disp]=hpf[delay];
else
hp0[disp]=newt(hpf,0,-delay);
if(hpu[bar]!=EMPTY_VALUE)
hpu0[disp]=hp0[disp];
else
hpu0[disp]=EMPTY_VALUE;
if(hpd[bar]!=EMPTY_VALUE)
hpd0[disp]=hp0[disp];
else
hpd0[disp]=EMPTY_VALUE;
fhi0[disp]=fhi[bar];
flo0[disp]=flo[bar];
phi0[disp]=phi[bar];
plo0[disp]=plo[bar];
if(timeframe<=Period())
limit=iBarShift(NULL,0,iTime(NULL,timeframe,bar+1));
else
limit=iBarShift(NULL,0,iTime(NULL,timeframe,bar))+1;
i=limit-disp;
if(i<2) continue;
H1=hp[bar+1];
HH1=(hp[bar]-H1)/i;
if(bands>0 && band1>0)
{
H2=fhi[bar+1];
HH2=(fhi[bar]-H2)/i;
H3=flo[bar+1];
HH3=(flo[bar]-H3)/i;
}
if(bands>0 && band2>0)
{
H4=phi[bar+1];
HH4=(phi[bar]-H4)/i;
H5=plo[bar+1];
HH5=(plo[bar]-H5)/i;
}
for(i=limit-1; i>disp; i--)
{
H1+=HH1;
hp0[i]=H1;
if(hpu[bar+1]!=EMPTY_VALUE) hpu0[i]=H1; else hpu0[i]=EMPTY_VALUE;
if(hpd[bar+1]!=EMPTY_VALUE) hpd0[i]=H1; else hpd0[i]=EMPTY_VALUE;
if(bands>0 && band1>0)
{
H2+=HH2;
H3+=HH3;
fhi0[i]=H2;
flo0[i]=H3;
}
if(bands>0 && band2>0)
{
H4+=HH4;
H5+=HH5;
phi0[i]=H4;
plo0[i]=H5;
}
}
}
}
if(showf>0)
{
limit=iBarShift(NULL,0,iTime(NULL,timeframe,nobs-1));
SetIndexDrawBegin(3,limit);
if(future>0)
{
V=Period();
V/=timeframe;
for(bar=0; bar<future; bar++)
hpf0[bar]=newt(hpf,0,(future-bar)*V);
}
for(bar=nobs-1; bar>=0; bar--)
{
if(bar==0)
disp=future;
else if(timeframe<=Period())
disp=iBarShift(NULL,0,iTime(NULL,timeframe,bar))+future;
else
disp=iBarShift(NULL,0,iTime(NULL,timeframe,bar-1))+future+1;
hpf0[disp]=hpf[bar];
if(bar<nobs-1)
{
limit=iBarShift(NULL,0,iTime(NULL,timeframe,bar+1))+future;
i=limit-disp;
if(i<2) continue;
H1=hpf[bar];
HH1=(H1-hpf[bar+1])/i;
for(i=limit-1; i>disp; i--)
{
H1+=HH1;
hpf0[i]=H1;
}
}
}
}
if(bands>0 && band1<0)
{
limit=iBarShift(NULL,0,iTime(NULL,timeframe,nobs-1));
for(bar=nobs-1; bar>=0; bar--)
{
if(bar==0)
disp=0;
else if(timeframe<=Period())
disp=iBarShift(NULL,0,iTime(NULL,timeframe,bar));
else
disp=iBarShift(NULL,0,iTime(NULL,timeframe,bar-1))+1;
fhi0[disp]=fhi[bar];
flo0[disp]=flo[bar];
if(bar<nobs-1)
{
if(timeframe<=Period())
limit=iBarShift(NULL,0,iTime(NULL,timeframe,bar+1));
else
limit=iBarShift(NULL,0,iTime(NULL,timeframe,bar))+1;
i=limit-disp;
if(i<2) continue;
H2=fhi[bar+1];
HH2=(fhi[bar]-H2)/i;
H3=flo[bar+1];
HH3=(flo[bar]-H3)/i;
for(i=limit-1; i>disp; i--)
{
H2+=HH2;
H3+=HH3;
fhi0[i]=H2;
flo0[i]=H3;
}
}
}
}
if(bands>0 && band2<0)
{
limit=iBarShift(NULL,0,iTime(NULL,timeframe,nobs-1));
for(bar=nobs-1; bar>=0; bar--)
{
if(bar==0)
disp=0;
else if(timeframe<=Period())
disp=iBarShift(NULL,0,iTime(NULL,timeframe,bar));
else
disp=iBarShift(NULL,0,iTime(NULL,timeframe,bar-1))+1;
phi0[disp]=phi[bar];
plo0[disp]=plo[bar];
if(bar<nobs-1)
{
if(timeframe<=Period())
limit=iBarShift(NULL,0,iTime(NULL,timeframe,bar+1));
else
limit=iBarShift(NULL,0,iTime(NULL,timeframe,bar))+1;
i=limit-disp;
if(i<2) continue;
H4=phi[bar+1];
HH4=(phi[bar]-H4)/i;
H5=plo[bar+1];
HH5=(plo[bar]-H5)/i;
for(i=limit-1; i>disp; i--)
{
H4+=HH4;
H5+=HH5;
phi0[i]=H4;
plo0[i]=H5;
}
}
}
}
if(alerting)
{
if(hpu[0]!=EMPTY_VALUE && hpu[1]==EMPTY_VALUE)
{
MyAlert("Up Trend");
}
else
if(hpu[0]==EMPTY_VALUE && hpu[1]!=EMPTY_VALUE && hpd[0]==EMPTY_VALUE)
{
MyAlert("No Trend");
}
else
if(hpd[0]!=EMPTY_VALUE && hpd[1]==EMPTY_VALUE)
{
MyAlert("Down Trend");
}
else
if(hpd[0]==EMPTY_VALUE && hpd[1]!=EMPTY_VALUE && hpu[0]==EMPTY_VALUE)
{
MyAlert("No Trend");
}
}
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void MyAlert(string alert)
{
static string last;
if(alert==last) return;
last=alert;
if(alerts) Alert(IND+tframe+alert);
if(audio!="") PlaySound(audio);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double newt(double x[],int pos,double n)
{
double r=x[pos],k=1;
int l=MathCeil(n),i;
if(pos+l>=ArraySize(x)) l=ArraySize(x)-pos-1;
if(n==0) return(r);
if(n<0) return(EMPTY_VALUE);
for(i=1; i<=l; i++)
{
k*=n/i;
r+=k*dlt(x,pos,i);
}
return(r);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double dlt(double x[],int pos,int d)
{
double r=0;
int i, k=1, pod=pos+d, l=d>>1;
if(pos>=ArraySize(x)) return(EMPTY_VALUE);
if(pos+d>=ArraySize(x)) return(0);
if(d%2>0)
for(i=0; i<=l; i++,pos++,pod--)
{
r+=k*(x[pos]-x[pod]);
k*=i-d;
k/=i+1;
}
else
{
for(i=0; i<l; i++,pos++,pod--)
{
r+=k*(x[pos]+x[pod]);
k*=i-d;
k/=i+1;
}
r+=k*x[pos];
}
return(r);
}
//+------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---