//+------------------------------------------------------------------+
//| VCD NRP                                                          |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   5
#property indicator_minimum 0
#property indicator_maximum 24

//---- plot definitions
#property indicator_label1 "Neutral"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 DimGray
#property indicator_width1 3

#property indicator_label2 "Bull Trend"
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_color2 LimeGreen
#property indicator_width2 3

#property indicator_label3 "Bear Trend"
#property indicator_type3 DRAW_HISTOGRAM
#property indicator_color3 Red
#property indicator_width3 3

#property indicator_label4 "Bull Div"
#property indicator_type4 DRAW_HISTOGRAM
#property indicator_color4 DarkGreen
#property indicator_width4 3

#property indicator_label5 "Bear Div"
#property indicator_type5 DRAW_HISTOGRAM
#property indicator_color5 DarkRed
#property indicator_width5 3

//---- settings
extern int InpLookbackShort = 3;
extern int InpLookbackMid   = 33;
extern int InpLookbackLong  = 66;

extern int InpConsThresh = 1;

//---- buffers
double Neutral[];
double BullTrend[];
double BearTrend[];
double BullDiv[];
double BearDiv[];

//+------------------------------------------------------------------+
int init()
{
   SetIndexBuffer(0,Neutral);
   SetIndexBuffer(1,BullTrend);
   SetIndexBuffer(2,BearTrend);
   SetIndexBuffer(3,BullDiv);
   SetIndexBuffer(4,BearDiv);

   SetIndexEmptyValue(0,EMPTY_VALUE);
   SetIndexEmptyValue(1,EMPTY_VALUE);
   SetIndexEmptyValue(2,EMPTY_VALUE);
   SetIndexEmptyValue(3,EMPTY_VALUE);
   SetIndexEmptyValue(4,EMPTY_VALUE);

   IndicatorShortName("VCD NRP");

   return(0);
}

//+------------------------------------------------------------------+
//| Vote engine                                                      |
//+------------------------------------------------------------------+
int GetConsensusVotes(int shift)
{
   int votes = 0;

   double close_now  = iClose(Symbol(),0,shift);
   double close_prev = iClose(Symbol(),0,shift+1);

   if(close_now<=0 || close_prev<=0)
      return -1;

   // EMA
   double ema20 = iMA(Symbol(),0,20,0,MODE_EMA,PRICE_CLOSE,shift);
   if(close_now > ema20) votes++;

   // MACD
   double macd_main = iMACD(Symbol(),0,12,26,9,PRICE_CLOSE,MODE_MAIN,shift);
   double macd_sig  = iMACD(Symbol(),0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,shift);
   if(macd_main > macd_sig) votes++;

   // Bollinger
   double bb_mid = iBands(Symbol(),0,20,2,0,PRICE_CLOSE,MODE_MAIN,shift);
   if(close_now > bb_mid) votes++;

   // MFI
   double mfi = iMFI(Symbol(),0,14,shift);
   if(mfi > 50) votes++;

   // ADX DI
   double di_plus  = iADX(Symbol(),0,14,PRICE_CLOSE,MODE_PLUSDI,shift);
   double di_minus = iADX(Symbol(),0,14,PRICE_CLOSE,MODE_MINUSDI,shift);
   if(di_plus > di_minus) votes++;

   // OsMA
   double osma = iOsMA(Symbol(),0,12,26,9,PRICE_CLOSE,shift);
   if(osma > 0) votes++;

   // Donchian
   double high_val = iHigh(Symbol(),0,shift);
   double low_val  = iLow(Symbol(),0,shift);

   double donch_mid = (high_val+low_val)/2.0;
   if(close_now > donch_mid) votes++;

   return votes;
}

//+------------------------------------------------------------------+
int start()
{
   int counted = IndicatorCounted();
   int limit = Bars-counted;

   if(limit>500) limit=500;

   // never calculate current candle
   Neutral[0]=EMPTY_VALUE;
   BullTrend[0]=EMPTY_VALUE;
   BearTrend[0]=EMPTY_VALUE;
   BullDiv[0]=EMPTY_VALUE;
   BearDiv[0]=EMPTY_VALUE;

   for(int i=limit;i>=1;i--)
   {
      Neutral[i]=EMPTY_VALUE;
      BullTrend[i]=EMPTY_VALUE;
      BearTrend[i]=EMPTY_VALUE;
      BullDiv[i]=EMPTY_VALUE;
      BearDiv[i]=EMPTY_VALUE;

      int v_short = GetConsensusVotes(i);
      int v_mid   = GetConsensusVotes(i+InpLookbackShort);
      int v_long  = GetConsensusVotes(i+InpLookbackMid);

      if(v_short<0 || v_mid<0 || v_long<0)
         continue;

      int total = v_short + v_mid + v_long;

      if(total<0) total=0;
      if(total>21) total=21;

      if(total>=12)
         BullTrend[i]=total;
      else if(total<=9)
         BearTrend[i]=total;
      else
         Neutral[i]=total;
   }

   return(0);
}
//+------------------------------------------------------------------+