#property indicator_separate_window
#property indicator_buffers   7
#property indicator_color1  clrDimGray
#property indicator_color2  clrDimGray
#property indicator_color3  clrGreen
#property indicator_color4  clrGreen
#property indicator_color5  clrRed
#property indicator_color6  clrRed
#property indicator_color7  clrDimGray
#property indicator_style1  STYLE_DOT
#property indicator_style2  STYLE_DOT
#property indicator_width3  2
#property indicator_width5  2
#property indicator_width7  2
#property strict

//
//
//
//
//

extern int                CalcPeriod   = 50;          // Calculation period
extern ENUM_APPLIED_PRICE CalcPrice    = PRICE_CLOSE; // Price
extern ENUM_MA_METHOD     CalcMaMethod = MODE_SMA;    // MaMethod for price smoothing
extern int                CalcMaPeriod = 1;           // period for price smoothing
extern bool               ShowHisto    = true;        // Display histogram?
extern double             DslSignal    = 9;           // Signal period

//
//
//
//
//

double   buffer1[];
double   buffer2[];
double   buffer3[];
double   buffer4[];
double   buffer5[],prices[],levelu[],leveld[];


//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int init()
{
   IndicatorBuffers(8);
   SetIndexBuffer(0,levelu);
   SetIndexBuffer(1,leveld);
   SetIndexBuffer(2,buffer1); SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer(3,buffer2); SetIndexStyle(3,DRAW_HISTOGRAM);
   SetIndexBuffer(4,buffer3); SetIndexStyle(4,DRAW_HISTOGRAM);
   SetIndexBuffer(5,buffer4); SetIndexStyle(5,DRAW_HISTOGRAM);
   SetIndexBuffer(6,buffer5);
   SetIndexBuffer(7,prices);
      IndicatorShortName("Weighted bulls/bears ("+(string)CalcPeriod+","+(string)CalcMaPeriod+","+(string)DslSignal+")");
   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);

   //
   //
   //
   //
   //

   double alpha = 2.0/(1.0+DslSignal);
      for(int i=limit; i>=0; i--)
      {
         prices[i] = iMA(NULL,0,CalcMaPeriod,0,CalcMaMethod,CalcPrice,i);
         int    hbar = ArrayMaximum(prices,CalcPeriod,i); double hval=prices[hbar];
         int    lbar = ArrayMinimum(prices,CalcPeriod,i); double lval=prices[lbar];
         double bear = -weight(hval-prices[i],hbar-i+1);
         double bull = +weight(prices[i]-lval,lbar-i+1);
         
         buffer5[i] = bull*2+bear*2;
         levelu[i] = (i<Bars-1) ? (buffer5[i]>0) ? levelu[i+1]+alpha*(buffer5[i]-levelu[i+1]) : levelu[i+1] : 50;
         leveld[i] = (i<Bars-1) ? (buffer5[i]<0) ? leveld[i+1]+alpha*(buffer5[i]-leveld[i+1]) : leveld[i+1] : 50;
         
               if (i<(Bars-1) && ShowHisto)
               {
                  buffer1[i]=EMPTY_VALUE;
                  buffer2[i]=EMPTY_VALUE;
                  buffer3[i]=EMPTY_VALUE;
                  buffer4[i]=EMPTY_VALUE;
                  
                  if(buffer5[i]<leveld[i])
                  {
                     if (buffer5[i]<buffer5[i+1]) buffer3[i]=buffer5[i];
                     if (buffer5[i]>buffer5[i+1]) buffer4[i]=buffer5[i];
                  }
                  if(buffer5[i]>levelu[i])
                  {
                     if (buffer5[i]<buffer5[i+1]) buffer2[i]=buffer5[i];
                     if (buffer5[i]>buffer5[i+1]) buffer1[i]=buffer5[i];
                  }
               }                  
      }
   return(0);
}


double weight(double range, double dist) { return(range+range/dist); }