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

前端 未结 2 1158
有刺的猬
有刺的猬 2020-12-14 11:11

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

相关标签:
2条回答
  • 2020-12-14 11:36

    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.

    0 讨论(0)
  • 2020-12-14 11:38
         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);
         }
    
    
    0 讨论(0)
提交回复
热议问题