Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use CopyRates() to search and filter through several timeframes for Bullish Engulfing pattern

I am trying to use CopyRates() to search for a bullish engulfing candlestick pattern (bearish candle followed by a bigger bullish candle) on several timeframes (all timeframes H2 to M10 within an H4 bullish candle after it closes). I read the definition of CopyRates() but I'm finding it a bit challenging to implement. The idea here is from the patterns I want to filter the pattern that has the biggest bearish to bullish candle pair ratio. See what I've done so far below:

In the OnTick():

for (int i=ArraySize(timeframes); i>=1; i--)   {
    
    if(CopyRates(Symbol(), timeframes[i - 1], 1, MyPeriod, rates)!=MyPeriod) {
        Print("Error CopyRates errcode = ",GetLastError()); 
        return;
    }

    // Using bullish engulfing pattern:
    if ((rates[numCandle].open < rates[numCandle].close) &&
        (rates[numCandle + 1].open > rates[numCandle + 1].close) &&
        (rates[numCandle + 1].open < rates[numCandle].close) &&
        (rates[numCandle + 1].close > rates[numCandle].open)) {

        // Not too certain what should be done here
    }
}

Here's the other related code:

input int numCandle=0; 
MqlRates rates[];
ENUM_TIMEFRAMES timeframes[7] = {PERIOD_H2, PERIOD_H1, PERIOD_M30, PERIOD_M20, PERIOD_M15, PERIOD_M12, PERIOD_M10};

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

UPDATED

Below is the definition of the bullish engulfing pattern:

enter image description here

The bullish engulfing pattern as shown in the above image is a bearish candle followed by a bullish candle. The bearish candle’s open less than the bullish candle’s close and the bearish candle’s close is greater than the bullish candle’s open. Please note that in several cases, the bearish candle's close is greater than the bullish candle's open by only a fraction. Each of the candles has a body size bigger than it’s upper and lower wicks combined.

like image 458
SuperHueman Avatar asked Jun 23 '20 06:06

SuperHueman


People also ask

How can you tell bullish and bearish engulfing?

The bullish engulfing candle signals reversal of a downtrend and indicates a rise in buying pressure when it appears at the bottom of a downtrend. The bearish engulfing signals reversal of the uptrend and indicates a fall in prices by the sellers who exert the selling pressure when it appears at the top of an uptrend.

What is bullish engulf?

A bullish engulfing pattern is a candlestick pattern that forms when a small black candlestick is followed the next day by a large white candlestick, the body of which completely overlaps or engulfs the body of the previous day's candlestick.

What is bearish engulfing bearish reversal?

A Bearish Engulfing pattern is a two day bearish reversal pattern that consists of a small white candlestick with short shadows or tails followed by a large black candlestick that eclipses or "engulfs" the small white one. A bearish engulfing pattern is usually seen at the end of an upward trend.


1 Answers

     ENUM_TIMEFRAMES timeframes[7] = {PERIOD_H2, PERIOD_H1, PERIOD_M30, PERIOD_M20, PERIOD_M15, PERIOD_M12, PERIOD_M10};
     //ENUM_TIMEFRAMES timeframes[4] = {PERIOD_H1, PERIOD_M30, PERIOD_M15, PERIOD_M5};
     //---
     const int LONG=1, SHORT=-1, NO_DIR=0;
     const ENUM_TIMEFRAMES timeframeHighest = PERIOD_H4;
     string bestRatioObjectName="bestBullish2BearishPattern!";
     
     datetime lastCandleTime=0;
     
     void OnTick()
     {
        if(!isNewBar(PERIOD_H4))
           return;
        //most likely you will call this block after new bar check?
        MqlRates rates[];
        ArraySetAsSeries(rates,true);
        if(CopyRates(_Symbol,timeframeHighest,0,2,rates)==-1)
        {
           printf("%i %s: failed to load/copy rates on %d. error=%d",__LINE__,__FILE__,PeriodSeconds(timeframeHighest)/60,_LastError);
           return;
        }
        if(getCandleDir(rates[1])!=LONG)
           return;
        const datetime timeStart=rates[1].time, timeEnd=rates[0].time;   //within a bullish H4 candle - DONE
        
        double bestRatio = -1;//once a bearish2bullish ratio is higher, we'll move to new place
        for(int i=ArraySize(timeframes)-1;i>=0;i--)
        {
           if(CopyRates(_Symbol,timeframes[i],timeStart,timeEnd,rates)<0)
           {
              printf("%i %s: failed to copy rates on %d. error=%d",__LINE__,__FILE__,PeriodSeconds(timeframeHighest)/60,_LastError);
              return;
           }
           processRates(rates,bestRatio,bestRatioObjectName);
        }
        printf("%i %s: best=%.5f, objName =%s: %.5f-%.5f",__LINE__,__FILE__,bestRatio,bestRatioObjectName,
         ObjectGetDouble(0,bestRatioObjectName,OBJPROP_PRICE1),ObjectGetDouble(0,bestRatioObjectName,OBJPROP_PRICE2));
        //ExpertRemove();//for scripting, a one time call
     }
     bool isNewBar(const ENUM_TIMEFRAMES tf)
       {
        const datetime time=iTime(_Symbol,tf,0);
        if(time>lastCandleTime)
          {
           lastCandleTime=time;
           return true;
          }
        return false;
       }
     int getCandleDir(const MqlRates& rate) // candle direction: +1 for BULL, -1 for BEAR
       {
        if(rate.close-rate.open>_Point/2.)
           return 1;
        if(rate.open-rate.close>_Point/2.)
           return-1;
        return 0;
       }
     void processRates(const MqlRates& rates[],double &best,const string bestObjName)
     {
        for(int i=ArraySize(rates)-2; i>0; /* no sense to catch last candle - we cant compare it with anybody */ i--)
        {
           if(getCandleDir(rates[i])!=LONG)
              continue;//current - bullish
           if(getCandleDir(rates[i+1])!=SHORT)
              continue;//prev - bearish
           if(rates[i].close-rates[i+1].open>_Point/2.){}
           else continue;
           if(rates[i+1].close-rates[i].open>_Point/2.){}
           else continue;
           const double body=rates[i].close-rates[i].open, twoWicks = rates[i].high-rates[i].low- body;
           if(body<twoWicks)
              continue;   //Each of the candles has a body size bigger than it’s upper and lower wicks combined.
     //---
           const double prevBody = rates[i+1].open - rates[i+1].close;
           const double newRatio = body / prevBody;
           if(newRatio>best) // eventually we'll find best bull2bear ratio
           {
              moveRectangle(rates[i+1],rates[i].time,bestObjName);
              best = newRatio;
           }
        }
     }
     void moveRectangle(const MqlRates& rate,const datetime rectEnd,const string objectName)
     {
        if(ObjectFind(0,objectName)<0)
        {
           if(!ObjectCreate(0,objectName,OBJ_RECTANGLE,0,0,0,0,0))
           {
              printf("%i %s: failed to draw %s. error=%d",__LINE__,__FILE__,objectName,_LastError);
              return;
           }
           //add GUI things like how to display the rectangle
        }
        //moving the rectangle to a new place, even for the first time
        ObjectSetDouble(0,objectName,OBJPROP_PRICE,0,rate.open);
        ObjectSetDouble(0,objectName,OBJPROP_PRICE,1,rate.close);
        ObjectSetInteger(0,objectName,OBJPROP_TIME,0,rate.time);
        ObjectSetInteger(0,objectName,OBJPROP_TIME,1,rectEnd);
     }

like image 165
Daniel Kniaz Avatar answered Sep 27 '22 23:09

Daniel Kniaz