How to determine if price returned to a certain region of values or not on a specific timeframe

 

My code below draws a rectangle based on certain conditions. I want to add another condition for drawing the rectangle. The rectangle is drawn from the open to the high of a bullish candle with index (i+1) as shown in the code. How can I tell if :

  1. price has already reentered the region
  2. price has passed the lower value (bullish candle open) of the region

so that I don’t even draw the rectangle the first place.



int NumOfDisplayBars = 200;
string prefix="RectRegion";

bool isCandlePattern(int candleIndex, ENUM_TIMEFRAMES cPeriod)  {
   
   
   if ( (iOpen(  _Symbol, cPeriod, candleIndex) > iClose(  _Symbol, cPeriod, candleIndex)) &&
        (iOpen(  _Symbol, cPeriod, candleIndex + 1) < iClose(  _Symbol, cPeriod, candleIndex + 1)) &&
        (iOpen(  _Symbol, cPeriod, candleIndex + 2) > iClose(  _Symbol, cPeriod, candleIndex + 2))
   ){
         
         double upperWickC1 = iHigh(  _Symbol, cPeriod, candleIndex ) - iOpen( _Symbol, cPeriod, candleIndex );
         double bodyC1 = iOpen(  _Symbol, cPeriod, candleIndex ) - iClose( _Symbol, cPeriod, candleIndex );
         double lowerWickC1 = iClose(  _Symbol, cPeriod, candleIndex ) - iLow( _Symbol, cPeriod, candleIndex );
   
         double upperWickC2 = iHigh(  _Symbol, cPeriod, candleIndex + 2) - iOpen( _Symbol, cPeriod, candleIndex + 2);
         double bodyC2 = iOpen(  _Symbol, cPeriod, candleIndex + 2) - iClose( _Symbol, cPeriod, candleIndex + 2);
         double lowerWickC2 = iClose(  _Symbol, cPeriod, candleIndex + 2) - iLow( _Symbol, cPeriod, candleIndex + 2);
   
   
         if ( (iClose(  _Symbol, cPeriod, candleIndex) < iOpen(  _Symbol, cPeriod, candleIndex + 1)) && 
         (iOpen(  _Symbol, cPeriod, candleIndex + 2) > iClose(  _Symbol, cPeriod, candleIndex + 1)) &&
         (bodyC1 > upperWickC1 + lowerWickC1) && (bodyC2 > upperWickC2 + lowerWickC2)
         
         ) {
              
            return true; //all conditions satisfied for drawing rect
            
         }
         
      else
      return false;
   }
   
   
   else
      return false;
      
     
}

void showRectRegion()   {
   
    for (int i=NumOfDisplayBars;i>=1;i--)   {
         
     if (isCandlePattern(i, 0))   {
          drawRectangle(i + 2,iHigh(_Symbol,0,i + 1),iOpen(_Symbol,0,i + 1), 0, clrOrange);
     }
   }
}

bool drawRectangle(int candleInt,const double top,const double bottom, ENUM_TIMEFRAMES cDuration, color rectColor)
{ 
     bool checkBarCount = true;
     int useCurrDuration = PeriodSeconds(cDuration)/PeriodSeconds();   
         
    const datetime starts = iTime(_Symbol,_Period,candleInt);
    
    const datetime ends = starts + useCurrDuration*PeriodSeconds();
    const string name=prefix+"_"+"_"+TimeToString(starts)+TimeToString(ends);
    if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,starts ,top, ends, bottom))
    {
        return false;
    }
  
    
   ObjectSetInteger(0,name,OBJPROP_COLOR, rectColor);
    
   ObjectSetInteger(0,name,OBJPROP_STYLE, STYLE_DASHDOT);

   ObjectSetInteger(0,name,OBJPROP_WIDTH,1);

   ObjectSetInteger(0,name,OBJPROP_FILL, true);
     
    return true;
}

void OnDeinit(const int reason){ObjectsDeleteAll(0,prefix);}


void OnTick()
{
   
   showRectRegion();
}
 

The region that I want to tell if price returned to is bullish candle between two bearish candles (candle pattern has other conditions). The end game is to take a sell trade on this. After doing some extensive research I found out that I should be comparing the candles of (i - 1) to 0 to find the candle with the highest high and compare it with the highest value in the region of values to determine whether price returned. I did that (please see code below) and updated the code I provided in my original question. It doesn't work well, meaning it at times it will omit the some of the rectangles that price has returned to (which is the correct behaviour) and at times it wont. How can I fix this?


int NumOfDisplayBars = 2000;
string prefix="RectRegion";

input bool onlyFreshZones = true;

bool isCandlePattern(int candleIndex, ENUM_TIMEFRAMES cPeriod)  {
   
   
   if ( (iOpen(  _Symbol, cPeriod, candleIndex) > iClose(  _Symbol, cPeriod, candleIndex)) &&
        (iOpen(  _Symbol, cPeriod, candleIndex + 1) < iClose(  _Symbol, cPeriod, candleIndex + 1)) &&
        (iOpen(  _Symbol, cPeriod, candleIndex + 2) > iClose(  _Symbol, cPeriod, candleIndex + 2))
   ){
         
         double upperWickC1 = iHigh(  _Symbol, cPeriod, candleIndex ) - iOpen( _Symbol, cPeriod, candleIndex );
         double bodyC1 = iOpen(  _Symbol, cPeriod, candleIndex ) - iClose( _Symbol, cPeriod, candleIndex );
         double lowerWickC1 = iClose(  _Symbol, cPeriod, candleIndex ) - iLow( _Symbol, cPeriod, candleIndex );
   
         double upperWickC2 = iHigh(  _Symbol, cPeriod, candleIndex + 2) - iOpen( _Symbol, cPeriod, candleIndex + 2);
         double bodyC2 = iOpen(  _Symbol, cPeriod, candleIndex + 2) - iClose( _Symbol, cPeriod, candleIndex + 2);
         double lowerWickC2 = iClose(  _Symbol, cPeriod, candleIndex + 2) - iLow( _Symbol, cPeriod, candleIndex + 2);
   
   
         if ( (iClose(  _Symbol, cPeriod, candleIndex) < iOpen(  _Symbol, cPeriod, candleIndex + 1)) && 
         (iOpen(  _Symbol, cPeriod, candleIndex + 2) > iClose(  _Symbol, cPeriod, candleIndex + 1)) &&
         (bodyC1 > upperWickC1 + lowerWickC1) && (bodyC2 > upperWickC2 + lowerWickC2)
         /*&&
         (iOpen(  _Symbol, cPeriod, candleIndex) > iClose(  _Symbol, cPeriod, candleIndex + 1)) && 
         (iClose(  _Symbol, cPeriod, candleIndex + 2) < iOpen(  _Symbol, cPeriod, candleIndex + 1))*/
         
         ) {
              
             if (onlyFreshZones)  {
            // // finding highest high on timeframe
            double c_candle[];
            ArrayResize(c_candle,candleIndex);

            for(int i=candleIndex-1;i>0;i--)
            {
                c_candle[i]=iHigh(Symbol(),PERIOD_CURRENT,i);
               
            }
            int cC=ArrayMaximum(c_candle,0,WHOLE_ARRAY);
            
            
            if (iOpen(  _Symbol, cPeriod, candleIndex + 1) > iHigh(  _Symbol, cPeriod, cC + 1)) {
               // checking to make sure highest high hasn't passed bull candle's open 
               return true;  
            
            }
            
            
            
            else
            return false;
            }
            
            
            else
            return true;
            
            
            
         }
         
      else
      return false;
   }
   
   
   else
      return false;
      
     
}

void showRectRegion()   {
   
    for (int i=NumOfDisplayBars;i>=1;i--)   {
         
     if (isCandlePattern(i, 0))   {
          drawRectangle(i + 2,iHigh(_Symbol,0,i + 1),iOpen(_Symbol,0,i + 1), 0, clrOrange);
     }
   }
}

bool drawRectangle(int candleInt,const double top,const double bottom, ENUM_TIMEFRAMES cDuration, color rectColor)
{ 
     bool checkBarCount = true;
     int useCurrDuration = PeriodSeconds(cDuration)/PeriodSeconds();   
         
    const datetime starts = iTime(_Symbol,_Period,candleInt);
    
    const datetime ends = starts + useCurrDuration*PeriodSeconds();
    const string name=prefix+"_"+"_"+TimeToString(starts)+TimeToString(ends);
    if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,starts ,top, ends, bottom))
    {
        return false;
    }
  
    
   ObjectSetInteger(0,name,OBJPROP_COLOR, rectColor);
    
   ObjectSetInteger(0,name,OBJPROP_STYLE, STYLE_DASHDOT);

   ObjectSetInteger(0,name,OBJPROP_WIDTH,1);

   ObjectSetInteger(0,name,OBJPROP_FILL, true);
     
    return true;
}

void OnDeinit(const int reason){ObjectsDeleteAll(0,prefix);}


void OnTick()
{
   
   showRectRegion();
}
Reason: