#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 LimeGreen
#property indicator_color2 DarkOrange
#property indicator_width1 2
#property indicator_width2 2
#property indicator_minimum 0
#property indicator_maximum 1

//
//
//
//
//

extern int FastEma    = 12;
extern int SlowEma    = 26;
extern int SignalEma  = 9;
extern int Price      = PRICE_CLOSE;
extern int LrPeriod   = 14;
extern int ApplyTo    = 0;

double trend[];
double hisup[];
double hisdn[];

//------------------------------------------------------------------
//
//------------------------------------------------------------------
int init()
{
   IndicatorBuffers(3);
   SetIndexBuffer(0,hisup); SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(1,hisdn); SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(2,trend);
   return(0);
}
int deinit()
{
   return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int start() 
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = MathMin(Bars-counted_bars,Bars-1);
         
         
         //
         //
         //
         //
         //
         
   for(int i=limit; i>=0; i--)
   {
      double price  = iMA(NULL,0,1,0,MODE_SMA,Price,i);
      double macd   = iEma(price,FastEma,i,0)-iEma(price,SlowEma,i,1);
      double signal = iEma(macd,SignalEma,i,2);
      switch (ApplyTo)
      {
         case 1:  double base = signal;      break;
         case 2:         base = macd-signal; break;
         default:        base = macd;
      }
      double lrva = iLinr(base,LrPeriod,i);
         trend[i] = trend[i+1];  
         if (base>lrva) trend[i] =  1;
         if (base<lrva) trend[i] = -1;
            if (trend[i]== 1) { hisup[i] = 1; hisdn[i] = EMPTY_VALUE; }
            if (trend[i]==-1) { hisdn[i] = 1; hisup[i] = EMPTY_VALUE; }
   }
   return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

double workEma[][3];
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);
}

