//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "2022 IonOne"
#property link      "www.forex-station.com"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1  Yellow
#property indicator_color2  DeepSkyBlue
#property indicator_color3  PaleVioletRed
#property indicator_style1  STYLE_DOT
#property strict

//
//
//
//
//
extern int LengthStdError = 21;//StdError Len (min 3)
extern int                Length          = 1;           // Linear regression calculation period
extern int                SmoothingLength = 3;            // Smoothing length
extern ENUM_APPLIED_PRICE Price           = PRICE_CLOSE;  // Price to use

extern int bars = 10000;

double mid[];
double up[];
double dn[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   SetIndexBuffer(0,mid); 
   SetIndexBuffer(1,up); 
   SetIndexBuffer(2,dn); 
   
   if (LengthStdError < 3) LengthStdError = 3;
   return(0);
}

//+------------------------------------------------------------------
//|                                                                  
//+------------------------------------------------------------------
//
//
//
//
//

double work[][2];

int start()
{
   int k,counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
           limit = MathMin(limit, bars);
           if (ArrayRange(work,0)!=Bars) ArrayResize(work,Bars);

   //
   //
   //
   //
   //

   for(int i=limit, r=Bars-i-1; i>=0; i--, r++)
   {
      work[r][0] = 3.0*iMA(NULL,0,Length,0,MODE_LWMA,Price,i)-2.0*iMA(NULL,0,Length,0,MODE_SMA,Price,i);
      work[r][1] = iStdError(iMA(NULL,0,1,0,MODE_SMA,Price,i),LengthStdError,i);
      double avglr  = work[r][0]; for (k=1; k<SmoothingLength && (r-k)>=0; k++) avglr += work[r-k][0]; avglr /= k;
      double avger  = work[r][1]; for (k=1; k<SmoothingLength && (r-k)>=0; k++) avger += work[r-k][1]; avger /= k;

      //
      //
      //
      //
      //
      
      mid[i] = avglr;
      up[i]  = avglr+avger;
      dn[i]  = avglr-avger;
   }   
   return(0);           
}


//+------------------------------------------------------------------
//|                                                                  
//+------------------------------------------------------------------
//
//
//
//
//

double workErr[][1];

double iStdError(double price, int length,int i, int forInstance = 0)
{
   if (ArrayRange(workErr,0)!=Bars) ArrayResize(workErr,Bars);
      int r = Bars-i-1; workErr[r][forInstance] = price;
                        
      //
      //
      //
      //
      //
                              
      double avgY     = workErr[r][forInstance]; int j; for (j=1; j<length && (r-j)>=0; j++) avgY += workErr[r-j][forInstance]; avgY /= j;
      double avgX     = length * (length-1) * 0.5 / length;
      double sumDxSqr = 0.00;
      double sumDySqr = 0.00;
      double sumDxDy  = 0.00;
   
      for (int k=0; k<length && (r-k)>=0; k++)
      {
         double dx = k-avgX;
         double dy = workErr[r-k][forInstance]-avgY;
            sumDxSqr += (dx*dx);
            sumDySqr += (dy*dy);
            sumDxDy  += (dx*dy);
      }
      double err2;
      if (fabs(sumDxSqr) > 0 && length-2 > 0)
         err2 = (sumDySqr-(sumDxDy*sumDxDy)/sumDxSqr)/(length-2); 
      
   //
   //
   //
   //
   //
         
   if (err2 > 0)
         return(MathSqrt(err2));
   else  return(0.00);       
}