//+------------------------------------------------------------------+
//|                                                       WRB_HG.mq4 |
//|                                                  Copyright © 201 |
//+------------------------------------------------------------------+
#property copyright "Free to Use"

#property indicator_chart_window
#property indicator_buffers 1

#property indicator_color1 Aqua      // WRB symbol
#property indicator_width1 1

extern int WRB_LookBackBarCount = 3;
extern int WRB_WingDingsSymbol = 115;
extern color HGcolor1 = DodgerBlue;
extern color HGcolor2 = Blue;
extern int StartCalculationFromBar=800;
//---- buffers
double WRB[];

int totalBarCount = -1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   //---- indicators
   IndicatorBuffers(1);
   
   SetIndexStyle(0,DRAW_ARROW); 
   SetIndexArrow(0,WRB_WingDingsSymbol); 
   SetIndexBuffer(0,WRB); 
   
   return(0);
  }
  

//+------------------------------------------------------------------+
//| Delete all objects with given prefix                             |
//+------------------------------------------------------------------+
void ObDeleteObjectsByPrefix(string Prefix)
{
   int L = StringLen(Prefix);
   int i = 0; 
   while(i < ObjectsTotal())
   {
       string ObjName = ObjectName(i);
       if(StringSubstr(ObjName, 0, L) != Prefix) 
       { 
           i++; 
           continue;
       }
       ObjectDelete(ObjName);
   }
}


//+------------------------------------------------------------------+
//|  intersect: Check two bars intersect or not                      |
//+------------------------------------------------------------------+
int intersect(double H1, double L1, double H2, double L2)
{
   if ( (L1>H2) || (H1<L2) ) return (0);
   if ( (H1>=H2) && (L1>=L2) ) return (1);
   if ( (H1<=H2) && (L1<=L2) ) return (2);
   if ( (H1>=H2) && (L1<=L2) ) return (3);
   if ( (H1<=H2) && (L1>=L2) ) return (4);
}  
  
//+------------------------------------------------------------------+
//|  checkHGFilled: Check if the hidden gap is filled or not         |
//+------------------------------------------------------------------+
void checkHGFilled(int barNumber)
{
   int j,i;
   string ObjectText;
   string Prefix="HG_UNFILLED_";
   double box_H, box_L;
   double HGFillPA_H, HGFillPA_L;
   datetime startTime;
   color objectColor;


   int L = StringLen(Prefix);
   i = 0; 
   while(i < ObjectsTotal()) // loop over all unfilled boxes
   {
       string ObjName = ObjectName(i);
       if(StringSubstr(ObjName, 0, L) != Prefix) 
       { 
           i++; 
           continue;
       }
       box_H=ObjectGet(ObjName, OBJPROP_PRICE1); // get HG high and low values
       box_L=ObjectGet(ObjName, OBJPROP_PRICE2);
       objectColor=ObjectGet(ObjName, OBJPROP_COLOR);
       startTime=ObjectGet(ObjName, OBJPROP_TIME1);
              
       HGFillPA_H = High[barNumber];
       HGFillPA_L = Low[barNumber];
       j=0;
       
       
       while ( intersect(High[barNumber+j], Low[barNumber+j], box_H, box_L)!=0 && (barNumber+j<Bars) && (startTime<Time[barNumber+j]))
       {
         if (High[barNumber+j] > HGFillPA_H)  HGFillPA_H = High[barNumber+j];
         if (Low[barNumber+j]  < HGFillPA_L)  HGFillPA_L = Low[barNumber+j];
         if ( (HGFillPA_H>box_H) && (HGFillPA_L<box_L) )
         {
            ObjectDelete(ObjName);
                        
            ObjectText = "HG_FILLED_" + TimeToStr(startTime,TIME_DATE|TIME_MINUTES);            
            ObjectCreate(ObjectText, OBJ_RECTANGLE, 0, startTime, box_H, Time[barNumber], box_L);
            ObjectSet(ObjectText, OBJPROP_STYLE, DRAW_HISTOGRAM);
            ObjectSet(ObjectText, OBJPROP_COLOR, objectColor);
            ObjectSet(ObjectText, OBJPROP_BACK, true);                                 
            break;
         }
         j++;
       }
       
       i++;
   }

}


//+------------------------------------------------------------------+
//| checkWRB: Check if the given bar is a WRB or not                 |
//| The lookback period can be changed by user input                 |
//+------------------------------------------------------------------+
bool checkWRB(int i)
{
      int j;
      bool WRB_test;
      double body,bodyPrior;
      
      WRB_test=true;
      body  = MathAbs(Open[i]-Close[i]);
      for (j=1;j<=WRB_LookBackBarCount;j++)
      {
        bodyPrior=MathAbs(Open[i+j]-Close[i+j]);
        if (bodyPrior>body)
        {
           WRB_test = false;
           break;
        }            
      }
         
      if (WRB_test) WRB[i] = (Open[i] + Close[i])/2;

      return(WRB_test);
}

//+------------------------------------------------------------------+
//| checkHG: Checks HG status of the previous bar.                   |
//+------------------------------------------------------------------+
void checkHG(int i)
{
   string ObjectText;
   double H,L,H2,L2,H1,L1,A,B;
   int result;
   int j;
   color HGcolor=HGcolor1;

   // HG-TEST ( test the previous bar i+1)
   if (WRB[i+1]!=EMPTY_VALUE) // First rule to become a HG is to become a WRB
   {
      H2 = High[i+2];
      L2 = Low[i+2];
      H1 = High[i];
      L1 = Low[i];
            
      if (Open[i+1]>Close[i+1])
      {
         H = Open[i+1];
         L = Close[i+1];
      }
      else
      {
         H = Close[i+1];
         L = Open[i+1];
      }
      
      A = H;
      B = L;

      
      result = intersect(H2,L2,A,B);
      if (result==1) A = L2;
      else if (result==2) B = H2;
      else if (result==3) return(NULL);

      result = intersect(H1,L1,A,B);
      if (result==1) A = L1;
      else if (result==2) B = H1;
      else if (result==3) return(NULL);
           
      if (A > B)
      {
         int Length = StringLen("HG_UNFILLED_");
         j = 0; 
         while(j < ObjectsTotal()) // loop over all unfilled boxes
         {
             ObjectText = ObjectName(j);
             if(StringSubstr(ObjectText, 0, Length) != "HG_UNFILLED_") 
             { 
                 j++; 
                 continue;
             }
             if (intersect(ObjectGet(ObjectText, OBJPROP_PRICE1),ObjectGet(ObjectText, OBJPROP_PRICE2),A,B)!=0)
             {
               HGcolor = ObjectGet(ObjectText, OBJPROP_COLOR);
               if (HGcolor==HGcolor1) HGcolor=HGcolor2;
               else HGcolor=HGcolor1;               
               break;
             }
             j++;
         }
      
         ObjectText = "HG_UNFILLED_" + TimeToStr(Time[i+1],TIME_DATE|TIME_MINUTES);
         ObjectCreate(ObjectText, OBJ_RECTANGLE, 0, Time[i+1], A, D'01.01.2035', B);
         ObjectSet(ObjectText, OBJPROP_STYLE, DRAW_HISTOGRAM);
         ObjectSet(ObjectText, OBJPROP_COLOR, HGcolor);
         ObjectSet(ObjectText, OBJPROP_BACK, true);               
      }
   } //End of HG-Test
}
  

    
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   ObDeleteObjectsByPrefix("HG_");

   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {

   int i,counted_bars=IndicatorCounted();


   // Initialization (RUNS ONLY ONCE)
   if (totalBarCount == -1)
   {   
      i=Bars - WRB_LookBackBarCount;
      if (i>StartCalculationFromBar) i=StartCalculationFromBar;
      while(i>0)
      {
      
         checkWRB(i);
         checkHG(i);
         checkHGFilled(i);
                         
         i--;
     }
     totalBarCount = Bars;
   }

   // A new bar started.
   if (totalBarCount != Bars)
   {
      i=1;

      checkWRB(i);
      checkHG(i);
      checkHGFilled(i);
 
      totalBarCount = Bars;
   }


  }
//+------------------------------------------------------------------+

