Author: ryaz
Price Data Components
Series array that contains close prices for each barSeries array that contains open prices of each barSeries array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt plays sound alerts
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 supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---