multi-timeframe rectangle regions for bullish and bearish patterns not showing on chart

 

I have written code to draw rectangles for two timeframes based on bullish and bearish patterns. But the rectangles don't show on the chart. Not sure what's causing it. I would really appreciate some help.


int numBars = 1;
string prefix="HG";

extern ENUM_TIMEFRAMES higherRegionPeriod = PERIOD_D1;
extern ENUM_TIMEFRAMES lowerRegionPeriod = PERIOD_H4;

extern color higherRegionColorSupply = clrRed;
extern color lowerRegionColorSupply = clrChocolate;

extern color higherRegionColorDemand = clrBlue;
extern color lowerRegionColorDemand = clrAqua;
 
 
bool isBullishEngulfing(int current, ENUM_TIMEFRAMES cDuration)  {
 
 

   if((iClose(_Symbol,cDuration,current) > iOpen(_Symbol,cDuration,current)) && 
      (iClose(_Symbol,cDuration,current + 1) < iOpen(_Symbol,cDuration,current + 1))  && 
      (iOpen(_Symbol,cDuration,current) < iClose(_Symbol,cDuration,current + 1)) && 
      (iClose(_Symbol,cDuration,current) > iOpen(_Symbol,cDuration,current + 1)))
         return true;
      return false;         
  
}


bool isBearishEngulfing(int current, ENUM_TIMEFRAMES cDuration)   {


   if((iClose(_Symbol,cDuration,current) < iOpen(_Symbol,cDuration,current)) && 
      (iClose(_Symbol,cDuration,current + 1) > iOpen(_Symbol,cDuration,current + 1))  && 
      (iOpen(_Symbol,cDuration,current) > iClose(_Symbol,cDuration,current + 1)) && 
      (iClose(_Symbol,cDuration,current) < iOpen(_Symbol,cDuration,current + 1)))
         return true;
      return false;  
    }


void showRectangles() {

   for (int i=300;i>=1;i--)   {

if(isBullishEngulfing(i, lowerRegionPeriod)) {
       
        drawBullRectangle(i + 1,iHigh(_Symbol,lowerRegionPeriod,i + 1),iOpen(_Symbol,lowerRegionPeriod,i + 1), lowerRegionPeriod, lowerRegionColorDemand);
    }
    
    if(isBullishEngulfing(i, higherRegionPeriod)) {
       
        drawBullRectangle(i + 1,iHigh(_Symbol,higherRegionPeriod,i + 1),iOpen(_Symbol,higherRegionPeriod,i + 1), higherRegionPeriod, higherRegionColorDemand);
    }
    


if(isBearishEngulfing(i, lowerRegionPeriod)) {

        drawBearRectangle(i + 1,iHigh(_Symbol,lowerRegionPeriod,i + 1),iOpen(_Symbol,lowerRegionPeriod,i + 1), lowerRegionPeriod, lowerRegionColorSupply);
    }

    if(isBearishEngulfing(i, higherRegionPeriod)) {

        drawBearRectangle(i + 1,iHigh(_Symbol,higherRegionPeriod,i + 1),iOpen(_Symbol,higherRegionPeriod,i + 1), higherRegionPeriod, higherRegionColorSupply);
    }
   }
}


bool drawBullRectangle(int candleInt,const double top,const double bottom, ENUM_TIMEFRAMES cDuration, color rectColor)
{

     
     bool checkBarCount = true;
    
    const datetime starts=iTime(_Symbol,cDuration,candleInt); 
    const datetime ends=starts+PeriodSeconds()*numBars;
    const string name=prefix+"_"+(candleInt>0?"DEMAND":"SUPPLY")+"_"+TimeToString(starts)+TimeToString(ends);
    if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,0,0,0,0))
    {
        printf("%i %s: failed to create %s. error=%d",__LINE__,__FILE__,name,_LastError);
        return false;
    }
    ObjectSetInteger(0,name,OBJPROP_TIME1,starts);
    ObjectSetInteger(0,name,OBJPROP_TIME2,ends);
    ObjectSetDouble(0,name,OBJPROP_PRICE1,top);
    ObjectSetDouble(0,name,OBJPROP_PRICE2,bottom);
    
    ObjectSetInteger(0,name,OBJPROP_COLOR, rectColor);
    

   ObjectSetInteger(0,name,OBJPROP_STYLE, STYLE_DASHDOT);

   ObjectSetInteger(0,name,OBJPROP_WIDTH,1);

   ObjectSetInteger(0,name,OBJPROP_FILL, false);

    
    return true;
}

bool drawBearRectangle(int candleInt,const double top,const double bottom, ENUM_TIMEFRAMES cDuration, color rectColor)
{


    const datetime starts=iTime(_Symbol,cDuration,candleInt); 
    const datetime ends=starts+PeriodSeconds()*numBars;
    
    const string name=prefix+"_"+(candleInt>0?"DEMAND":"SUPPLY")+"_"+TimeToString(starts)+TimeToString(ends);
    
    
    if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,0,0,0,0))
    {
        printf("%i %s: failed to create %s. error=%d",__LINE__,__FILE__,name,_LastError);
        return false;
    }
    ObjectSetInteger(0,name,OBJPROP_TIME1,starts);
    ObjectSetInteger(0,name,OBJPROP_TIME2,ends);

    ObjectSetDouble(0,name,OBJPROP_PRICE1,bottom);
    ObjectSetDouble(0,name,OBJPROP_PRICE2,top);

    ObjectSetInteger(0,name,OBJPROP_COLOR, rectColor);


   ObjectSetInteger(0,name,OBJPROP_STYLE, STYLE_DASHDOT);
   ObjectSetInteger(0,name,OBJPROP_WIDTH,1);

   ObjectSetInteger(0,name,OBJPROP_FILL, false);

    return true;
}

void OnDeinit(const int reason){ObjectsDeleteAll(0,prefix);}
void OnTick()
{
    if(!isNewBar(higherRegionPeriod))
        return;     //not necessary but waste of time to check every second

   if(!isNewBar(lowerRegionPeriod))
        return;     //not necessary but waste of time to check every second

showRectangles();
}


bool isNewBar(ENUM_TIMEFRAMES cDuration)
{
   static datetime lastbar;
   datetime curbar = (datetime)SeriesInfoInteger(_Symbol,cDuration,SERIES_LASTBAR_DATE);
   if(lastbar != curbar)
   {
      lastbar = curbar;
      return true;
   }
   return false;
}
 

there may be many bugs

------------------

but one i found is that

bool isNewBar(ENUM_TIMEFRAMES cDuration)
{
   static datetime lastbar;
...
}

your are using the same static variable for both   hgherRegionPeriod and lowerRegionPeriod

----------------------------

the second :  chart with chartID=0 in which you try to draw hgherRegionPeriod and lowerRegionPeriod rectangles 

What Is the  timeframe where you sketch rectangles ?

if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,0,0,0,0))

-------------------

you must  check if it works  for only one timeframe 

 

Here's another big problem - you cannot use the same bar index 'i' to access data from different timeframes (hint: use iBarShift()) :

void showRectangles() {

   for (int i=300;i>=1;i--)   {

if(isBullishEngulfing(i, lowerRegionPeriod)) {
       
        drawBullRectangle(i + 1,iHigh(_Symbol,lowerRegionPeriod,i + 1),iOpen(_Symbol,lowerRegionPeriod,i + 1), lowerRegionPeriod, lowerRegionColorDemand);
    }
    
    if(isBullishEngulfing(i, higherRegionPeriod)) {
       
        drawBullRectangle(i + 1,iHigh(_Symbol,higherRegionPeriod,i + 1),iOpen(_Symbol,higherRegionPeriod,i + 1), higherRegionPeriod, higherRegionColorDemand);
    }
    


if(isBearishEngulfing(i, lowerRegionPeriod)) {

        drawBearRectangle(i + 1,iHigh(_Symbol,lowerRegionPeriod,i + 1),iOpen(_Symbol,lowerRegionPeriod,i + 1), lowerRegionPeriod, lowerRegionColorSupply);
    }

    if(isBearishEngulfing(i, higherRegionPeriod)) {

        drawBearRectangle(i + 1,iHigh(_Symbol,higherRegionPeriod,i + 1),iOpen(_Symbol,higherRegionPeriod,i + 1), higherRegionPeriod, higherRegionColorSupply);
    }
   }
}

 
    if(!isNewBar(higherRegionPeriod)) 

   if(!isNewBar(lowerRegionPeriod))
For a new bar test, Bars is unreliable (a refresh/reconnect can change number of bars on chart,) volume is unreliable (miss ticks,) Price is unreliable (duplicate prices and The == operand. - MQL4 programming forum.) Always use time.
I disagree with making a new bar function, because it can only be called once per tick. A variable can be tested multiple times.
          New candle - MQL4 programming forum
 
Seng Joo Thio:

Here's another big problem - you cannot use the same bar index 'i' to access data from different timeframes (hint: use iBarShift()) :



I read the docs on iBarShift() but it isn't clear to me how I could achieve this with iBarShift(). I would appreciate some more detail on this.
 
HappyMeMe:

I read the docs on iBarShift() but it isn't clear to me how I could achieve this with iBarShift(). I would appreciate some more detail on this.

Here's what you should do for lowerRegionPeriod. You can do the same for higherRegionPeriod, then run and see the outcome (you should be able to see bigger rectangles now).

But if your _Period is not M1, your rectangles will not be of the right size... and you'll next have to figure out how to modify the 4th parameter of your calls to drawBuffRectangle() and drawBearRectangle()... (hint: how many _Period equals lowerRegionPeriod?)

void showRectangles() {

   for (int i=300;i>=1;i--)   {
    
    int iLRPBar = iBarShift(_Symbol,lowerRegionPeriod,iTime(_Symbol,_Period,i))+1;

    if(isBullishEngulfing(i, lowerRegionPeriod)) {
       
        drawBullRectangle(i + 1,iHigh(_Symbol,lowerRegionPeriod,iLRPBar),iOpen(_Symbol,lowerRegionPeriod,iLRPBar), lowerRegionPeriod, lowerRegionColorDemand);
    }
    
    if(isBullishEngulfing(i, higherRegionPeriod)) {
       
        drawBullRectangle(i + 1,iHigh(_Symbol,higherRegionPeriod,i + 1),iOpen(_Symbol,higherRegionPeriod,i + 1), higherRegionPeriod, higherRegionColorDemand);
    }
    


if(isBearishEngulfing(i, lowerRegionPeriod)) {

        drawBearRectangle(i + 1,iHigh(_Symbol,lowerRegionPeriod,i + 1),iOpen(_Symbol,lowerRegionPeriod,i + 1), lowerRegionPeriod, lowerRegionColorSupply);
    }

    if(isBearishEngulfing(i, higherRegionPeriod)) {

        drawBearRectangle(i + 1,iHigh(_Symbol,higherRegionPeriod,i + 1),iOpen(_Symbol,higherRegionPeriod,i + 1), higherRegionPeriod, higherRegionColorSupply);
    }
   }
}
 
HappyMeMe: I read the docs on iBarShift() but it isn't clear to me how I could achieve this with iBarShift(). I would appreciate some more detail on this.
Don't mix apples and oranges.
 
William Roeder:
Don't mix apples and oranges.
How am I mixing apples and oranges?
 

After implementing the recommendations in the comments above, I've still not been able to get the rectangles to draw. Maybe, I didn't do something right. not too sure though. Here is my updated code below:


int numBars = 1;
string prefix="HG";

extern ENUM_TIMEFRAMES higherRegionPeriod = PERIOD_D1;
extern ENUM_TIMEFRAMES lowerRegionPeriod = PERIOD_H4;

extern color higherRegionColorSupply = clrRed;
extern color lowerRegionColorSupply = clrChocolate;

extern color higherRegionColorDemand = clrBlue;
extern color lowerRegionColorDemand = clrAqua;
 
 
bool isBullishEngulfing(int current, ENUM_TIMEFRAMES cDuration)  {
 
   if((iClose(_Symbol,cDuration,current) > iOpen(_Symbol,cDuration,current)) && 
      (iClose(_Symbol,cDuration,current + 1) < iOpen(_Symbol,cDuration,current + 1))  && 
      (iOpen(_Symbol,cDuration,current) < iClose(_Symbol,cDuration,current + 1)) && 
      (iClose(_Symbol,cDuration,current) > iOpen(_Symbol,cDuration,current + 1)))
         return true;
      return false;         
  
}


bool isBearishEngulfing(int current, ENUM_TIMEFRAMES cDuration)   {

   if((iClose(_Symbol,cDuration,current) < iOpen(_Symbol,cDuration,current)) && 
      (iClose(_Symbol,cDuration,current + 1) > iOpen(_Symbol,cDuration,current + 1))  && 
      (iOpen(_Symbol,cDuration,current) > iClose(_Symbol,cDuration,current + 1)) && 
      (iClose(_Symbol,cDuration,current) < iOpen(_Symbol,cDuration,current + 1)))
         return true;
      return false;  
 
}

void showLRRectangles() {

   for (int i=300;i>=1;i--)   {
   
   
   int iLRPBar = iBarShift(_Symbol,lowerRegionPeriod,iTime(_Symbol,_Period,i))+1;

    if(isBullishEngulfing(i, lowerRegionPeriod)) {
       
        drawBullRectangle(i + 1,iHigh(_Symbol,lowerRegionPeriod,iLRPBar),iOpen(_Symbol,lowerRegionPeriod,iLRPBar), lowerRegionPeriod/_Period, lowerRegionColorDemand);
    }
    

if(isBearishEngulfing(i, lowerRegionPeriod)) {

        drawBearRectangle(i + 1,iHigh(_Symbol,lowerRegionPeriod,iLRPBar),iOpen(_Symbol,lowerRegionPeriod,iLRPBar), lowerRegionPeriod/_Period, lowerRegionColorSupply);
    }
   }
}

void showHRRectangles() {

   for (int i=300;i>=1;i--)   {

   int iHRPBar = iBarShift(_Symbol,higherRegionPeriod,iTime(_Symbol,_Period,i))+1;
       
    if(isBullishEngulfing(i, higherRegionPeriod)) {
       
        drawBullRectangle(i + 1,iHigh(_Symbol,higherRegionPeriod,iHRPBar),iOpen(_Symbol,higherRegionPeriod,iHRPBar), higherRegionPeriod/_Period, higherRegionColorDemand);
    }
    
    if(isBearishEngulfing(i, higherRegionPeriod)) {

        drawBearRectangle(i + 1,iHigh(_Symbol,higherRegionPeriod,iHRPBar),iOpen(_Symbol,higherRegionPeriod,iHRPBar), higherRegionPeriod/_Period, higherRegionColorSupply);
    }
   }
}


bool drawBullRectangle(int candleInt,const double top,const double bottom, int cDuration, color rectColor)
{ 
     bool checkBarCount = true;
    
    const datetime starts=iTime(_Symbol,cDuration,candleInt); 
    const datetime ends=starts+PeriodSeconds()*numBars;
    const string name=prefix+"_"+(candleInt>0?"DEMAND":"SUPPLY")+"_"+TimeToString(starts)+TimeToString(ends);
    if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,cDuration,0,0,0))
    {
        printf("%i %s: failed to create %s. error=%d",__LINE__,__FILE__,name,_LastError);
        return false;
    }
    ObjectSetInteger(0,name,OBJPROP_TIME1,starts);
    ObjectSetInteger(0,name,OBJPROP_TIME2,ends);
    ObjectSetDouble(0,name,OBJPROP_PRICE1,top);
    ObjectSetDouble(0,name,OBJPROP_PRICE2,bottom);
    
    ObjectSetInteger(0,name,OBJPROP_COLOR, rectColor);
   
   ObjectSetInteger(0,name,OBJPROP_STYLE, STYLE_DASHDOT);

   ObjectSetInteger(0,name,OBJPROP_WIDTH,1);

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

bool drawBearRectangle(int candleInt,const double top,const double bottom, int cDuration, color rectColor)
{

    const datetime starts=iTime(_Symbol,cDuration,candleInt); 
    const datetime ends=starts+PeriodSeconds()*numBars;
    
    const string name=prefix+"_"+(candleInt>0?"DEMAND":"SUPPLY")+"_"+TimeToString(starts)+TimeToString(ends);
       
    if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,cDuration,0,0,0))
    {
        printf("%i %s: failed to create %s. error=%d",__LINE__,__FILE__,name,_LastError);
        return false;
    }
    ObjectSetInteger(0,name,OBJPROP_TIME1,starts);
    ObjectSetInteger(0,name,OBJPROP_TIME2,ends);

    ObjectSetDouble(0,name,OBJPROP_PRICE1,bottom);
    ObjectSetDouble(0,name,OBJPROP_PRICE2,top);

    ObjectSetInteger(0,name,OBJPROP_COLOR, rectColor);
   ObjectSetInteger(0,name,OBJPROP_STYLE, STYLE_DASHDOT);
   ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
   ObjectSetInteger(0,name,OBJPROP_FILL, false);

    return true;
}

void OnDeinit(const int reason){ObjectsDeleteAll(0,prefix);}
void OnTick()
{
   
    static datetime currHRBarTime=0; datetime prevHRBarTime = currHRBarTime; currHRBarTime=Time[higherRegionPeriod];
   bool isNewHRBar = currHRBarTime != prevHRBarTime;
   
   static datetime currLRBarTime=0; datetime prevLRBarTime = currLRBarTime; currLRBarTime=Time[higherRegionPeriod];
   bool isNewLRBar = currLRBarTime != prevLRBarTime;
   
   if(isNewHRBar)
      showHRRectangles();
      
   if(isNewLRBar)
      showLRRectangles();  
      

}


 
Seng Joo Thio:

Here's what you should do for lowerRegionPeriod. You can do the same for higherRegionPeriod, then run and see the outcome (you should be able to see bigger rectangles now).

But if your _Period is not M1, your rectangles will not be of the right size... and you'll next have to figure out how to modify the 4th parameter of your calls to drawBuffRectangle() and drawBearRectangle()... (hint: how many _Period equals lowerRegionPeriod?)

Thanks but I still haven't been able to get it working, I just added a comment with my updated code.

 
paul selvan:

there may be many bugs

------------------

but one i found is that

your are using the same static variable for both   hgherRegionPeriod and lowerRegionPeriod

----------------------------

the second :  chart with chartID=0 in which you try to draw hgherRegionPeriod and lowerRegionPeriod rectangles 

What Is the  timeframe where you sketch rectangles ?

-------------------

you must  check if it works  for only one timeframe 

Thanks but I still haven't been able to get it working, I just added a comment with my updated code.

Reason: