//------------------------------------------------------------------
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  LimeGreen
#property indicator_color2  Gold
#property indicator_width1  2
#property indicator_style2  STYLE_DOT
#property indicator_level1  0
#property indicator_level2  20
#property indicator_level3  80

//
//
//
//
//

extern int    StoPeriod   = 21;
extern int    StoSlowing  = 10;
extern int    StoPrice    =  0;
extern int    WprPeriod   = 21;
extern int    MomPeriod   = 21;
extern int    MomPrice    = PRICE_CLOSE;
extern double MomModifier =  0;
extern int    RsiPeriod   = 21;
extern int    RsiPrice    = PRICE_CLOSE;
extern int    CciPeriod   = 21;
extern int    CciPrice    = PRICE_TYPICAL;
extern int    UltFast     =  7;
extern int    UltMiddle   = 14;
extern int    UltSlow     = 28;
extern int    UltFastK    =  4;
extern int    UltMiddleK  =  2;
extern int    UltSlowK    =  1;
extern int    MfiPeriod   = 14;
extern int    LrPeriod    = 21;
extern int    EmaPeriod   =  4;

double lrvalue[];
double emavalue[];
double value[];
double temp[];

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

int init()
{
   IndicatorBuffers(4);
   SetIndexBuffer(0,lrvalue);
   SetIndexBuffer(1,emavalue);
   SetIndexBuffer(2,value);
   SetIndexBuffer(3,temp);
   return(0);
}
int deinit() { return(0); }

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

int start()
{
   int i,counted_bars=IndicatorCounted();
   double divider = UltFastK+UltMiddleK+UltSlowK;
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = MathMin(Bars-counted_bars,Bars-1);

   //
   //
   //
   //
   //
   
   for(i=limit; i>=0; i--) temp[i] = Close[i]-MathMin(Low[i],Close[i+1]);
   for(i=limit; i>=0; i--)
   {
      double atrf = iATR(NULL,0,UltFast  ,i);
      double atrm = iATR(NULL,0,UltMiddle,i);
      double atrs = iATR(NULL,0,UltSlow  ,i);
      double ult  = 0;
      if (atrf!=0 && atrm !=0 && atrs !=0)
             ult = (UltFastK  *iMAOnArray(temp,0,UltFast  ,0,MODE_SMA,i)/atrf +
                    UltMiddleK*iMAOnArray(temp,0,UltMiddle,0,MODE_SMA,i)/atrm +
                    UltSlowK  *iMAOnArray(temp,0,UltSlow  ,0,MODE_SMA,i)/atrs)/divider*100;
                    
            //
            //
            //
            //
            //
                                
                                
            value[i] = (iStochastic(NULL,0,StoPeriod,1,StoSlowing,MODE_SMA,StoPrice,MODE_MAIN,i)+
                        iWPR(NULL,0,WprPeriod,i)+
                        iMomentum(NULL,0,MomPeriod,MomPrice,i)+MomModifier+
                        iRSI(NULL,0,RsiPeriod,RsiPrice,i)+
                        iCCI(NULL,0,CciPeriod,CciPrice,i)+
                        iMFI(NULL,0,MfiPeriod,i)+ult)/7.0;
            lrvalue[i]  = iLinr(value[i],LrPeriod,i,0);                        
            emavalue[i] = iEma(lrvalue[i],EmaPeriod,i,0);                        
   }
   return(0);
}

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

double workEma[][1];
double iEma(double price, double period, int r, int instanceNo=0)
{
   if (ArrayRange(workEma,0)!= Bars) ArrayResize(workEma,Bars); r=Bars-r-1;

   //
   //
   //
   //
   //
      
   double alpha = 2.0 / (1.0+period);
          workEma[r][instanceNo] = workEma[r-1][instanceNo]+alpha*(price-workEma[r-1][instanceNo]);
   return(workEma[r][instanceNo]);
}

//
//
//
//
//

double workLinr[][1];
double iLinr(double price, double period, int r, int instanceNo=0)
{
   if (ArrayRange(workLinr,0)!= Bars) ArrayResize(workLinr,Bars); r = Bars-r-1;

   //
   //
   //
   //
   //
   
      period = MathMax(period,1);
      workLinr[r][instanceNo] = price;
         double lwmw = period; double lwma = lwmw*price;
         double sma  = price;
         for(int k=1; k<period && (r-k)>=0; k++)
         {
            double weight = period-k;
                   lwmw  += weight;
                   lwma  += weight*workLinr[r-k][instanceNo];  
                   sma   +=        workLinr[r-k][instanceNo];
         }             
   
   return(3.0*lwma/lwmw-2.0*sma/period);
}