PolyFitBands

 
Sorry, this is a temporary entry that will be deleted just to format the below as code on the web in order to make use of the Google Chrome "Highlight all on dblclick" extension. If you know a better place/way to do so please share.

-2
down vote
accept
//+------------------------------------------------------------------+
//|                                              PolyFitBands_v1.mq4 |
//|                     Source: https://www.mql5.com/en/forum/178009 |
//|                                Copyright © 2007, TrendLaboratory |
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|                                   E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, TrendLaboratory"
#property link      "http://finance.groups.yahoo.com/group/TrendLaboratory"

#property indicator_chart_window
#property indicator_buffers   14
//Nummerierlogik: SetIndexBuffer + 1
#property indicator_color1    clrBlack
#property indicator_width1    1
#property indicator_style1    STYLE_DOT //Line style. Used only if the line width is equal to 0 or 1
#property indicator_color2    Black
#property indicator_width2    1
#property indicator_style2    2       
#property indicator_color3    clrGold //UpBand1
#property indicator_width3    1
#property indicator_color4    clrGold //DnProject1
#property indicator_width4    1
#property indicator_style4    2 
#property indicator_color5    clrGold //DnBand1
#property indicator_width5    1
#property indicator_color6    clrGold //UpProject1
#property indicator_width6    1
#property indicator_style6    2  
#property indicator_color7    clrDarkOrange //UpBand2
#property indicator_width7    2
#property indicator_color8    clrDarkOrange //DnBand2
#property indicator_width8    2
#property indicator_color9    clrRed //UpBand3
#property indicator_width9    3
#property indicator_color10   clrRed //DnBand3
#property indicator_width10   3

#property indicator_color11   clrDarkOrange //UpProject2
#property indicator_width11   1
#property indicator_style11   2 //dotted
#property indicator_color12   clrDarkOrange //DnProject2
#property indicator_width12   1
#property indicator_style12   2 //dotted

#property indicator_color13   clrRed //UpProject3
#property indicator_width13   1
#property indicator_style13   2 //dotted
#property indicator_color14   clrRed //DnProject3
#property indicator_width14   1
#property indicator_style14   2 //dotted

//---- external variables
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     Length      =  30;   //Number of bars for an evaluation
extern int     Degree      =   3;   //Degree of a Polynomial(no more 12)
extern int     MA_Length   =   1;   //Period of Preliminary Smoothing
extern int     MA_Mode     =   0;   //Mode of MA:0-SMA,1-EMA,2-Wilders(SMMA),3-LWMA
extern int     ProjLength  =   5;   //Length of Projection 
extern double  K_Sigma     =   1;   //Multiplier of Sigma(Standard Deviation)
extern int     FitMode     =   0;   //Fitting Mode: 0-Fitting,1-Moving
extern int     CenterMode  =   1;   //Center Line Plot: 0-without,1-with 
extern int     CountBars   = 500;   //Maximum Number of Bars(0-all Bars) 
//---- indicator buffers
double PolyFitMA[];
double Projection[];
double UpBand1[];
double UpProject1[];
double DnBand1[];
double DnProject1[];
double Polynom[];
double Project[];
//---- global variables
double PriceArray[];
int cBars;

double UpBand2[];
double DnBand2[];
double UpBand3[];
double DnBand3[];
double UpProject2[];
double DnProject2[];
double UpProject3[];
double DnProject3[];
//+---------------------------------------------------------------------------+
//| Custom indicator initialization function                                  |
//+---------------------------------------------------------------------------+
int init()
{
   IndicatorDigits(MarketInfo(Symbol(), MODE_DIGITS )+2);
   IndicatorBuffers(16);
   SetIndexStyle(0, DRAW_LINE);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexStyle(2, DRAW_LINE);
   SetIndexStyle(3, DRAW_LINE);
   SetIndexStyle(4, DRAW_LINE);
   SetIndexStyle(5, DRAW_LINE);

   SetIndexBuffer(0, PolyFitMA);
   SetIndexBuffer(1, Projection);
   SetIndexBuffer(2, UpBand1);
   SetIndexBuffer(3, UpProject1);
   SetIndexBuffer(4, DnBand1);
   SetIndexBuffer(5, DnProject1);

   SetIndexBuffer(6, UpBand2);  
   SetIndexBuffer(7, DnBand2);
   SetIndexBuffer(8, UpBand3);  
   SetIndexBuffer(9, DnBand3);

   SetIndexBuffer(10, UpProject2);  
   SetIndexBuffer(11, DnProject2);   
   SetIndexBuffer(12, UpProject3);  
   SetIndexBuffer(13, DnProject3); 

   //diese beiden werden nicht gezeichnet:
   SetIndexBuffer(14, Polynom);
   SetIndexBuffer(15, Project);

   if(CountBars == 0) cBars = Bars;
   else cBars = CountBars;

   SetIndexDrawBegin( 0,Bars-cBars+(Length+MA_Length));
   SetIndexDrawBegin( 2,Bars-cBars+2*(Length+MA_Length));
   SetIndexDrawBegin( 4,Bars-cBars+2*(Length+MA_Length));

   SetIndexDrawBegin( 6,Bars-cBars+2*(Length+MA_Length));
   SetIndexDrawBegin( 7,Bars-cBars+2*(Length+MA_Length));
   SetIndexDrawBegin( 8,Bars-cBars+2*(Length+MA_Length));
   SetIndexDrawBegin( 9,Bars-cBars+2*(Length+MA_Length));

   SetIndexShift(1,ProjLength);
   SetIndexShift(3,ProjLength);
   SetIndexShift(5,ProjLength);
   SetIndexShift(10,ProjLength);
   SetIndexShift(11,ProjLength);
   SetIndexShift(12,ProjLength);
   SetIndexShift(13,ProjLength);

   string short_name="PolyFitBands("+Price+","+Length+","+Degree+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,"PolyFitCenter");
   SetIndexLabel(1,"CenterProject");
   SetIndexLabel(2,"UpPolyBand");
   SetIndexLabel(3,"UpProject1");
   SetIndexLabel(4,"DnPolyBand");
   SetIndexLabel(5,"DnProject1");
   SetIndexLabel(6,"UpPolyBand2");
   SetIndexLabel(7,"DnPolyBand2");
   SetIndexLabel(8,"UpPolyBand3");
   SetIndexLabel(9,"DnPolyBand3");
   SetIndexLabel(10,"UpProject2");
   SetIndexLabel(11,"DnProject2");
   SetIndexLabel(12,"UpProject3");
   SetIndexLabel(13,"DnProject3");

   ArrayResize(PriceArray, Length);

   return(0);
}

double PolyFit(double price[],int deg,int len,int bar)
{
double   result=0,Sum=0;
double   AX[12,12],BX[12],CX[12],ZX[12],Pow[24];
int      Row[12];

// FILL MATRIX FIRST
   if (len<=1)  Sum=price[0];
   else
   {    

   for (int j=1;j<=deg+1;j++) BX[j]=0;

        for (int k=1;k<=len;k++) 
       {
       double YK=price[len-k];
       double XK=k;
       double Prod=1;
          for (j=1;j<=deg+1;j++)
           {
           BX[j]+= YK*Prod;
           Prod*=XK;
           }
      }

   for (j=1;j<=2*deg;j++) Pow[j]=0;

    Pow[0]=len;

      for (k=1;k<=len;k++)
       {
       XK=k;
       Prod=k;
          for (j=1;j<=2*deg;j++)
          {
           Pow[j]+=Prod;
           Prod*=XK;
           }
      } 

       for (j=1;j<=deg+1;j++)
       {    
         for (int l=1;l<=deg+1;l++) 
          AX[j,l]=Pow[j+l-2];
      } 
//NOW SOLVE FOR COEFFICIENTS

    for (j=1;j<=deg+1;j++) Row[j]=j;

      for (int i=1;i<=deg;i++)
       {
          for (k=i+1;k<=deg+1;k++)
         {
            if(MathAbs(AX[Row[k],i]) > MathAbs(AX[Row[i],i]))
           {    
           int Temp=Row[i];
           Row[i]=Row[k];
           Row[k]=Temp;
            }
         }

         for (k=i+1;k<=deg+1;k++)
           {
           if(AX[Row[i],i]!=0) AX[Row[k],i]=AX[Row[k],i]/AX[Row[i],i];
               for (l=i+1;l<=deg+1;l++)
           AX[Row[k],l]=AX[Row[k],l]-AX[Row[k],i]*AX[Row[i],l];
            }
        }

   ZX[1]=BX[Row[1]];

      for (k=2;k<=deg+1;k++)
       {
       Sum=0;
      for (l=1;l<=k-1;l++) Sum+=AX[Row[k],l]*ZX[l];

       ZX[k]=BX[Row[k]]-Sum;
       }

    CX[deg+1]=ZX[deg+1]/AX[Row[deg+1],deg+1];

      for (k=deg;k>=1;k--)
       {
       Sum=0;
       l=k+1;       
       for (l=k+1;l<=deg+1;l++) Sum += AX[Row[k],l]*CX[l];
       CX[k]=(ZX[k]-Sum)/AX[Row[k],k];
       }

//NOW COMPUTE NEXT POINT IN SERIES AND RETURN}

    Sum=CX[deg+1];
    for (k=deg;k>=1;k--) Sum=CX[k]+Sum*(len+bar);

   }
   return (Sum);
}   
//+------------------------------------------------------------------+
//| PolyFitBands_v1                                                     |
//+------------------------------------------------------------------+
int start()
{
   int i, j, k, m, shift, counted_bars=IndicatorCounted(), limit;


   if ( counted_bars < 0 )  return(0);
   if ( counted_bars ==0 )  limit=cBars-1; 

   if (FitMode==1 && counted_bars > 0) {limit = Bars - counted_bars; int len = Length+MA_Length;}
   else
   if (FitMode==0) {limit = Length; len = cBars - Length+1;} 

   if ( counted_bars < 1 || FitMode==0)
   { 
      for(i=1;i<len;i++)
      { 
      Polynom[cBars-i]=0; 
      PolyFitMA[cBars-i]=EMPTY_VALUE;    
      UpBand1[cBars-i]=EMPTY_VALUE;
      DnBand1[cBars-i]=EMPTY_VALUE;
      UpBand2[cBars-i]=EMPTY_VALUE;
      DnBand2[cBars-i]=EMPTY_VALUE;
      UpBand3[cBars-i]=EMPTY_VALUE;
      DnBand3[cBars-i]=EMPTY_VALUE;
      }
   }   

   if ( ProjLength > 0 )
   {  
      for(i=1;i<Length;i++)
      {
      Projection[i]=EMPTY_VALUE;  
      UpProject1[i]=EMPTY_VALUE;
      DnProject1[i]=EMPTY_VALUE;

      UpProject2[i]=EMPTY_VALUE;
      DnProject2[i]=EMPTY_VALUE;
      UpProject3[i]=EMPTY_VALUE;
      DnProject3[i]=EMPTY_VALUE;
      }
   } 

   for(shift=0;shift<limit;shift++ )
   {
      if((shift==0 && FitMode==0) || (FitMode==1))
      {   
         for(j=0;j<Length;j++) 
         PriceArray[j] = iMA(NULL,0,MA_Length,0,MA_Mode,Price,shift*FitMode + j);

         double Sum=0;
         for(j=Length-1;j>=0;j--)
         {
         double poly = PolyFit(PriceArray,Degree,Length,-j); 
         double del = PriceArray[j] - poly; 
         Sum += del*del;
         if (FitMode==0) Polynom[j] = poly;  
         }

      if(FitMode==1) Polynom[shift] = poly; 

         if (Length-1 > 0 && Sum > 0)
         {
            if(Length < 32) double StdDev = MathSqrt(Sum/(Length-1));   
            else
            StdDev = MathSqrt(Sum/Length);       
         }
      }

   UpBand1[shift] = Polynom[shift] + K_Sigma * StdDev;    
   DnBand1[shift] = Polynom[shift] - K_Sigma * StdDev;

   UpBand2[shift] = Polynom[shift] + K_Sigma * 2*StdDev;
   DnBand2[shift] = Polynom[shift] - K_Sigma * 2*StdDev;
   UpBand3[shift] = Polynom[shift] + K_Sigma * 3*StdDev;
   DnBand3[shift] = Polynom[shift] - K_Sigma * 3*StdDev;

      if(ProjLength > 0 && shift == 0)
      {
         for (j=0;j<=ProjLength;j++)
         Project[j] = PolyFit(PriceArray,Degree,Length,ProjLength - j);
      }  
   }

   for(shift=0;shift<limit;shift++ )
   {
   if (CenterMode == 1) PolyFitMA[shift] = Polynom[shift]; 

      if(ProjLength > 0 && shift == 0)
      {
         for (j=0;j<=ProjLength;j++)
         { 
         if (CenterMode == 1) Projection[j] = Project[j];
         UpProject1[j] = Project[j] + K_Sigma * StdDev;   
         DnProject1[j] = Project[j] - K_Sigma * StdDev;

         UpProject2[j] = Project[j] + K_Sigma * 2*StdDev;   
         DnProject2[j] = Project[j] - K_Sigma * 2*StdDev;
         UpProject3[j] = Project[j] + K_Sigma * 3*StdDev;   
         DnProject3[j] = Project[j] - K_Sigma * 3*StdDev;
         }
      }
   }     
   return(0);