How to search for a candlestick pattern on multiple timeframes

 

I have an EA that draws rectangle on a specifically defined bearish pinbar followed by a bullish candle. Please see the code below. It basically shows the rectangle on the timeframe displayed on the chart.

How can I search for this candlestick pattern on timeframes within an H1 candlestick down to M2 in such a way that I can filter the pattern that has the longest bearish pinbar from all timeframes?


string prefix="PBar";
int magicnumber = 12345;

bool drawBearPinbarRectangle(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;
}

bool isBearPinBarType(int candleInt, ENUM_TIMEFRAMES cDuration, double maxLowerWickSize, double maxBodySize)  {
   
   if (iOpen(  _Symbol, cDuration, candleInt ) > iClose( _Symbol, cDuration, candleInt )) {
   
   double upperWick = iHigh(  _Symbol, cDuration, candleInt ) - iOpen( _Symbol, cDuration, candleInt );
   double body = iOpen(  _Symbol, cDuration, candleInt ) - iClose( _Symbol, cDuration, candleInt );
   double lowerWick = iClose(  _Symbol, cDuration, candleInt ) - iLow( _Symbol, cDuration, candleInt );
   
   double totalCandle = upperWick + body + lowerWick;
   
   if (((lowerWick > 0.0) && (lowerWick <= totalCandle*maxLowerWickSize)) && ((body > 0.0) && (body <= totalCandle*maxBodySize)))
      return true;
      
   return false; 
  
   }
   
   else
      return false;
}


bool isBullPinBarType(int candleInt, ENUM_TIMEFRAMES cDuration, double maxLowerWickSize, double maxBodySize)  {
   
   if ((iHigh(  _Symbol, cDuration, candleInt ) - iClose( _Symbol, cDuration, candleInt )) > 0) {
   
   double upperWick = iHigh(  _Symbol, cDuration, candleInt ) - iOpen( _Symbol, cDuration, candleInt );
   double body = iOpen(  _Symbol, cDuration, candleInt ) - iClose( _Symbol, cDuration, candleInt );
   double lowerWick = iClose(  _Symbol, cDuration, candleInt ) - iLow( _Symbol, cDuration, candleInt );
   
   double totalCandle = upperWick + body + lowerWick;
   
   if (((lowerWick > 0.0) && (lowerWick <= totalCandle*maxLowerWickSize)) && ((body > 0.0) && (body <= totalCandle*maxBodySize)))
      return true;
      
   return false; 
  
   }
   
   else
      return false;
}

void showPinbarRectOnDispTime() {

 
    for (int i=NumOfDisplayBars;i>=1;i--)   {
      
      double barOpen = iOpen(_Symbol,0,i + 1);
       double barHigh = iHigh(_Symbol,0,i + 1);
    
    
     if (isBearPinBarType(i + 2, 0, 0.15, 0.3)
      && 
    (iOpen(_Symbol,0,i + 1) < iClose(_Symbol,0,i + 1))) {
      
      drawBearPinbarRectangle(i +2,iHigh(_Symbol,0,i + 2),iLow(_Symbol,0,i + 2), 0, clrCyan);
      
      
      
      
      }
   }

}

bool isBearPinBarWithOpenAndClose(int numCandle, ENUM_TIMEFRAMES cDuration, double maxLowerWickSize, double maxBodySize,
double candleOpen, double candleHigh)  {
   
   
   
   if ((NormalizeDouble((iOpen(  _Symbol, cDuration, numCandle)), 2) == NormalizeDouble(candleOpen, 2)) && 
   (NormalizeDouble((iHigh(  _Symbol, cDuration, numCandle)), 2) == NormalizeDouble(candleHigh, 2)) && 
   ((iHigh(  _Symbol, cDuration, numCandle ) - iClose( _Symbol, cDuration, numCandle )) > 0)) {
   
   double upperWick = iHigh(  _Symbol, cDuration, numCandle ) - iOpen( _Symbol, cDuration, numCandle );
   double body = iOpen(  _Symbol, cDuration, numCandle ) - iClose( _Symbol, cDuration, numCandle );
   double lowerWick = iClose(  _Symbol, cDuration, numCandle ) - iLow( _Symbol, cDuration, numCandle );
   
   double totalCandle = upperWick + body + lowerWick;
   
   if (((lowerWick > 0.0) && (lowerWick <= totalCandle*maxLowerWickSize)) && ((body > 0.0) && (body <= totalCandle*maxBodySize)))
      return true;
      
   return false; 
  
   }
   
   else
      return false;
      
     
}

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


void OnTick()
{
   
   

     showPinbarRectOnDispTime();
       
}
 

The bar has a start time. Its duration is known, meaning you can calculate the time of its end. There are functions for finding bars by time: iBarShift () and CopyRates (), CopyClose (), etc.

If I understand your question correctly.

 

Greetings! Please see this sample:


input int numCandle=0; input double maxLowerWickSize=1.0; input double maxBodySize=1.0; input int Myperiod=15;
MqlRates   rates[];

int OnInit()
  { 
 ArraySetAsSeries(rates, true);
}

void OnDeinit(const int reason)
  {
  ArrayFree(rates);
}

 void OnTick()
  {bool resultM15=false; bool resultM30=false;

//- for PERIOD_M15
if(CopyRates(Symbol(), PERIOD_M15, 1, MyPeriod, rates)!=MyPeriod)
    {Print("Error CopyRates errcode = ",GetLastError()); return;}
  //code of function isBullPinBarType(...) ,included to OnTick()
 if (rates[numCandle].high-rates[numCandle].close > 0) {
       double upperWick = rates[numCandle].high-rates[numCandle].open;
       double body = rates[numCandle].open-rates[numCandle].close;
       double lowerWick = rates[numCandle].close-rates[numCandle].low;
  
       double totalCandle = upperWick + body + lowerWick;
  
   if (lowerWick > 0.0 && lowerWick <= totalCandle*maxLowerWickSize && body > 0.0 && body <= totalCandle*maxBodySize)
    {resultM15=true;}
         }

//- for PERIOD_M30
if(CopyRates(Symbol(), PERIOD_M30, 1, MyPeriod, rates)!=MyPeriod)
    {Print("Error CopyRates errcode = ",GetLastError()); return;}
  //code of function isBullPinBarType(...) ,included to OnTick()
 if (rates[numCandle].high-rates[numCandle].close > 0) {
        upperWick = rates[numCandle].high-rates[numCandle].open;
        body = rates[numCandle].open-rates[numCandle].close;
        lowerWick = rates[numCandle].close-rates[numCandle].low;
  
        totalCandle = upperWick + body + lowerWick;
  
   if (lowerWick > 0.0 && lowerWick <= totalCandle*maxLowerWickSize && body > 0.0 && body <= totalCandle*maxBodySize)
    {resultM30=true;}
         }

}

Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / History Data Structure
Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / History Data Structure
  • www.mql5.com
Constants, Enumerations and Structures / Data Structures / History Data Structure - Reference on algorithmic/automated trading language for MetaTrader 5
Reason: