//+--------------------------------------------------------------------------+ //| 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)=history) limit=history-1; if (limit=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=limit; 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=0;i--) { hpf[i]=a[i]-b[i]*H1-c[i]*H2; H2=H1; H1=hpf[i]; } hp[bar]=hpf[0]; if (hpu[bar+1]==EMPTY_VALUE && (hp[bar]0) { for (i=0; ihp[bar+1] || V>hp[bar])) hpd[bar]=EMPTY_VALUE; else if (trend>0) { for (i=0; ihpf[i+1]) break; if (ihp[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; i0) { 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; i0 && (band2>0 || (band2<0 && bar==0))) { Z=0; for (i=0; i0) { 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=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=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 (bardisp; 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 (bardisp; 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 (bardisp; 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