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

北慕城南 提交于 2020-07-01 10:43:24

问题


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 candle). 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:

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.


回答1:


  ENUM_TIMEFRAMES timeframes[7] = {PERIOD_H2, PERIOD_H1, PERIOD_M30, PERIOD_M20, PERIOD_M15, PERIOD_M12, PERIOD_M10};
  //---
  const int LONG=1, SHORT=-1, NO_DIR=0;
  const ENUM_TIMEFRAMES timeframeHighest = PERIOD_H4;
  string bestRatioObjectName="bestBullish2BearishPattern!";
  
  void OnTick()
  {
     //most likely you will call this block after new bar check?
     MqlRates rates[];
     ArraySetAsSeries(rates,true);
     if(CopyRates(_Symbol,timeframeHighest,1,0,rates)==-1)
     {
        printf("%i %s: failed to load/copy rates on %d. error=%d",__LINE__,__FILE__,PeriodSeconds(timeframeHighest)/60,_LastError);
        return;
     }
     if(getCandleDir(rates[0])!=LONG)
        return;
     const datetime timeStart=rates[0].time, timeEnd=TimeCurrent();   //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);
     }
        
     ExpertRemove();//for scripting, a one time call
  }
  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)-1; 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);
  }



回答2:


Assuming that MyPeriod is initialized to 2, the rest of the code seems correct. You should create a variable to keep the timeframe that had the greatest ratio. Inside your if you have to calculate the candlestick body size for candle+1 and candle and calculate the ratio, then if the calculated ratio is greater than the previous calculated you change the value AND update the timeframe in which you find it.

By the end of your for loop you may decide in which timeframe you want to put your order.



来源:https://stackoverflow.com/questions/62528297/how-to-use-copyrates-to-search-and-filter-through-several-timeframes-for-bulli

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!