//+------------------------------------------------------------------+
//|                                                     OB ident.mq4 |
//+------------------------------------------------------------------+

#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 clrAqua
#property indicator_color2 clrAqua
#property indicator_color3 clrYellow
#property indicator_color4 clrYellow
#property indicator_color5 clrLime
#property indicator_color6 clrLime
#property indicator_color7 clrYellow
#property indicator_color8 clrYellow
#property indicator_width1 4
#property indicator_width2 4
#property indicator_width3 4
#property indicator_width4 4
#property indicator_width5 4
#property indicator_width6 4
#property indicator_width7 4
#property indicator_width8 4


extern double   MinBarHeight       = 10;
extern double   MaxBarHeight       = 35;
extern double   CloseWithinXpct    = 25;
extern double   MinBodyPct         = 25;
extern bool     MustFollowOppColor = false;
extern int      EngulfMarginPct    = 100;
extern int      EngulfTolerance    = 20;
extern int      StartHour          = 0;
extern int      EndHour            = 23;
extern bool   UseSound         = True;         // not working properly, keeps going off
extern string NameFileSound    = "meep.wav"; //  not working properly, keeps going off

string   ccy;
int      dig, spr, tf;
double   pnt;
datetime prev_time;

double ExtUpperBuffer1[];
double ExtUpperBuffer2[];
double ExtUpperBuffer3[];
double ExtUpperBuffer4[];
double ExtLowerBuffer1[];
double ExtLowerBuffer2[];
double ExtLowerBuffer3[];
double ExtLowerBuffer4[];


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()  {
   IndicatorBuffers(2);
   IndicatorDigits(Digits);
//--- middle line
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,242);
   SetIndexBuffer(0,ExtUpperBuffer1);
   SetIndexShift(0,0);
   SetIndexLabel(0,"UpArr");
//--- upper band
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,242);
   SetIndexBuffer(1,ExtUpperBuffer2);
   SetIndexShift(1,0);
   SetIndexLabel(1,"UpArr");
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,242);
   SetIndexBuffer(2,ExtUpperBuffer3);
   SetIndexShift(2,0);
   SetIndexLabel(2,"UpArr");
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexArrow(3,242);
   SetIndexBuffer(3,ExtUpperBuffer4);
   SetIndexShift(3,0);
   SetIndexLabel(3,"UpArr");

   SetIndexStyle(4,DRAW_ARROW);
   SetIndexArrow(4,241);
   SetIndexBuffer(4,ExtLowerBuffer1);
   SetIndexShift(4,0);
   SetIndexLabel(4,"DnArr");
   SetIndexStyle(5,DRAW_ARROW);
   SetIndexArrow(5,241);
   SetIndexBuffer(5,ExtLowerBuffer2);
   SetIndexShift(5,0);
   SetIndexLabel(5,"DnArr");
   SetIndexStyle(6,DRAW_ARROW);
   SetIndexArrow(6,241);
   SetIndexBuffer(6,ExtLowerBuffer3);
   SetIndexShift(6,0);
   SetIndexLabel(6,"DnArr");
   SetIndexStyle(7,DRAW_ARROW);
   SetIndexArrow(7,241);
   SetIndexBuffer(7,ExtLowerBuffer4);
   SetIndexShift(7,0);
   SetIndexLabel(7,"DnArr");


  ccy = Symbol();
  tf  = Period();
  pnt = MarketInfo(ccy,MODE_POINT);
  dig = MarketInfo(ccy,MODE_DIGITS);
  spr = MarketInfo(ccy,MODE_SPREAD);

//  Comment("pnt=" + pnt + "    dig=" + dig + "    spr=" + spr);

  del_obj();
  plot_obj();    
  prev_time = -9999;
  return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()  {
  del_obj();
  return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {
  if(prev_time != Time[0])  {
    del_obj();
    plot_obj();    
  }  
  prev_time = Time[0];
  return(0);
}

//+------------------------------------------------------------------+
void del_obj()   {
int i;
   for(i=ArraySize(ExtUpperBuffer1)-1;i>=0;i--)ExtUpperBuffer1[i]=EMPTY_VALUE;
   for(i=ArraySize(ExtUpperBuffer2)-1;i>=0;i--)ExtUpperBuffer2[i]=EMPTY_VALUE;
   for(i=ArraySize(ExtUpperBuffer3)-1;i>=0;i--)ExtUpperBuffer3[i]=EMPTY_VALUE;
   for(i=ArraySize(ExtUpperBuffer4)-1;i>=0;i--)ExtUpperBuffer4[i]=EMPTY_VALUE;
   for(i=ArraySize(ExtLowerBuffer1)-1;i>=0;i--)ExtLowerBuffer1[i]=EMPTY_VALUE;
   for(i=ArraySize(ExtLowerBuffer2)-1;i>=0;i--)ExtLowerBuffer2[i]=EMPTY_VALUE;
   for(i=ArraySize(ExtLowerBuffer3)-1;i>=0;i--)ExtLowerBuffer3[i]=EMPTY_VALUE;
   for(i=ArraySize(ExtLowerBuffer4)-1;i>=0;i--)ExtLowerBuffer4[i]=EMPTY_VALUE;
   
   
/*
  for(i=ObjectsTotal()-1; i>=0; i--)  {
    string objname = ObjectName(i);
    if (ObjectType(objname) == OBJ_ARROW && StringSubstr(objname,0,4) == "obid")   ObjectDelete(objname);
  }  */
  return(0);
} 

//+------------------------------------------------------------------+
void plot_obj()   {

  int valid;
  for (int i=1; i<=Bars-1; i++)  {
    int hr = TimeHour(Time[i]);
    if (hr < StartHour || hr > EndHour)  continue;
    bool OutsideBar = true;
    if (High[i] < High[i+1] || Low[i] > Low[i+1])   OutsideBar = false;                  // not an OB

    bool EngulfBody = true;
    if (EngulfTolerance < 0)   
      EngulfBody = false;
    else  {
      double HiOCcurr = MathMax(Open[i], Close[i]);
      double LoOCcurr = MathMin(Open[i], Close[i]);
      double HiOCprev = MathMax(Open[i+1], Close[i+1]);
      double LoOCprev = MathMin(Open[i+1], Close[i+1]);
      if ((HiOCcurr - LoOCcurr) < (HiOCprev - LoOCprev) * EngulfMarginPct /100 )   EngulfBody = false;                                                // not an engulfing body
      if (HiOCcurr < HiOCprev - EngulfTolerance*pnt || LoOCcurr > LoOCprev + EngulfTolerance*pnt)  EngulfBody = false;    // not an engulfing body
      if (Close[i] > Open[i] && High[i] < High[i+1])   EngulfBody = false;                                                // green bar whose high lower than prev high
      if (Close[i] < Open[i] && Low[i]  > Low[i+1])    EngulfBody = false;                                                // red bar whose low higher than prev low
    }  

    if (!OutsideBar && !EngulfBody)   continue;
    if (High[i] - Low[i] < MinBarHeight*pnt || High[i] - Low[i] > MaxBarHeight*pnt)  continue;         // bar length outside max or min
    if (MathAbs(Close[i] - Open[i]) / (High[i] - Low[i]) < MinBodyPct / 100)  continue;                // body not at least X% of candle height
    
    if (Close[i] > Open[i])  {                                                                         // green bar 
      if (!MustFollowOppColor || Close[i+1] < Open[i+1])  {                                            // must be preceded by red bar
        if ((High[i] - Close[i]) / (High[i] - Low[i]) <= CloseWithinXpct / 100)  {                     // close within X% of top of candle
          //ObjectCreate("obidl"+i,OBJ_ARROW,0,iTime(ccy,tf,i),iLow(ccy,tf,i)-50*pnt);
          //ObjectSet("obidl"+i,OBJPROP_ARROWCODE,241);
          //ObjectSet("obidl"+i,OBJPROP_COLOR,Lime);
          //ObjectSet("obidl"+i,OBJPROP_WIDTH,1);
          
          
          valid = 0;
          if (High[i+2]  >  High[i+1])  valid += 2;
          if (High[i+3]  >  High[i+2])  valid += 1;
          if (High[i+4]  >= High[i+3])  valid += 1;
          if (High[i+5]  >= High[i+4])  valid += 1;
          if (High[i+10] >  High[i+1])  valid += 1;
        
          if (valid >= 5)  
               {
               //ObjectSet("obidl"+i,OBJPROP_WIDTH,4);
               if (!OutsideBar) 
                  {//UpBigYellow
                  //ObjectSet("obidl"+i,OBJPROP_COLOR,Yellow);
                   ExtLowerBuffer3[i]=iLow(ccy,tf,i)-2*pnt;
                   if (UseSound) PlaySound(NameFileSound);
                    
                  }
               else
                  {//UpBigGreen
                   ExtLowerBuffer1[i]=iLow(ccy,tf,i)-2*pnt;
                   //if (UseSound) PlaySound(NameFileSound);
                    
                  }
               }
          else
               {
               if (!OutsideBar) 
                  {//UpLittleYellow
                  //ObjectSet("obidl"+i,OBJPROP_COLOR,Yellow);
                   ExtLowerBuffer4[i]=iLow(ccy,tf,i)-2*pnt;
                  //  if (UseSound) PlaySound(NameFileSound);
                    
                  }
               else
                  {//UpLittleGreen
                   ExtLowerBuffer2[i]=iLow(ccy,tf,i)-2*pnt;
                  //  if (UseSound) PlaySound(NameFileSound);
                  }
               }
    } } }    
    
    if (Close[i] < Open[i])  {                                                                          // red bar
      if (!MustFollowOppColor || Close[i+1] > Open[i+1])  {                                             // must be preceded by green bar
        if ((Close[i] - Low[i]) / (High[i] - Low[i]) <= CloseWithinXpct / 100)  {                       // close within X% of bottom of candle
          //ExtUpperBuffer1[i]=iHigh(ccy,tf,i)+50*pnt;
          //ObjectCreate("obidh"+i,OBJ_ARROW,0,iTime(ccy,tf,i),iHigh(ccy,tf,i)+200*pnt);
          //ObjectSet("obidh"+i,OBJPROP_ARROWCODE,242);
          //ObjectSet("obidh"+i,OBJPROP_COLOR,Aqua);
          //ObjectSet("obidh"+i,OBJPROP_WIDTH,1);
          valid = 0;
          if (Low[i+2]  <  Low[i+1])  valid += 2;
          if (Low[i+3]  <  Low[i+2])  valid += 1;
          if (Low[i+4]  <= Low[i+3])  valid += 1;
          if (Low[i+5]  <= Low[i+4])  valid += 1;
          if (Low[i+10] <  Low[i+1])  valid += 1;
          if (valid >= 5)
               {
                 //ObjectSet("obidh"+i,OBJPROP_WIDTH,4);
               if (!OutsideBar)
                  {//dOWN BIG YELLOW   
                   //ObjectSet("obidh"+i,OBJPROP_COLOR,Yellow);
                   ExtUpperBuffer3[i]=iHigh(ccy,tf,i)+200*pnt;
                  // if (UseSound) PlaySound(NameFileSound);
                  }
               else
                  {//Down big Aquia
                   ExtUpperBuffer1[i]=iHigh(ccy,tf,i)+200*pnt;
                   //if (UseSound) PlaySound(NameFileSound);
                  }
               }
          else
               {
               if (!OutsideBar)
                  {//Down little yellow
                   //ObjectSet("obidh"+i,OBJPROP_COLOR,Yellow);
                   ExtUpperBuffer4[i]=iHigh(ccy,tf,i)+200*pnt;
                  // if (UseSound) PlaySound(NameFileSound);
                  }
               else
                  {//Down little Aquia
                   ExtUpperBuffer2[i]=iHigh(ccy,tf,i)+200*pnt;
                 //  if (UseSound) PlaySound(NameFileSound);
                  }
               }
          
          
          
          
    } } }    
  }
  return(0);
} 

