Wrong drawing with fibonacci retracement !!!

 

Hi All,

I'm working on fibonacci retracement and i stuck. I need help.

What's my question? if we are past d2 line, cancel retracement and find a new one,go back case:1 and find new retracement and draw but it is not.

How can i solve this problem?

 

Thank you. 

 

void OnTick()
{
  
   // We only run the EA after a full tick!
   static datetime tmp;
   if (tmp != Time[0])
   {
      tmp =  Time[0];
      cHigh = iHigh(NULL,0,1);
      cLow = iLow(NULL,0,1);
      
      bool minmaxChangeLow = FALSE;
      bool minmaxChangeHigh = FALSE;
      switch(state) {
         
         // 1 = Find Retracement
         case 1:
            // Decrement initBuffer if it is over 0
            if (initBuffer > 0) {initBuffer--;}
            // Did max or min change? If yes then recalc Retracement
            minmaxChangeLow = FALSE;
            minmaxChangeHigh = FALSE;
            if (cHigh > max){
               max = cHigh;
               maxt = Time[1];
               upTrend = TRUE;
               minmaxChangeHigh = TRUE;
               Print("cHigh > max... upTrend:" + IntegerToString(upTrend));
            }
            if (cLow < min){
               min = cLow;
               mint = Time[1];
               upTrend = FALSE;
               minmaxChangeLow = TRUE;
               Print("cLow < min... upTrend:" + IntegerToString(upTrend));
            }
            // SPECIAL CASE: BOTH MIN AND MAX CANNOT BE CHANGED AT THE SAME TIME...
            // If they both changes, ignore...
            if ((minmaxChangeHigh && !minmaxChangeLow) || (!minmaxChangeHigh && minmaxChangeLow)){
               Print("Min Max changes!");
               CalcRetracement();
               // If we are over the init buffer, go to next state...
               if (initBuffer == 0) {
                  trendMin = 1000;
                  trendMax = 0;
                  state = 2;
               }
               break;
            }
            // If we are below D2, cancel Retracement and find a new one...
            if(upTrend) {
               if (cLow < D2) {
                  min = cLow;
                  mint = Time[1];
                  upTrend = False;
                  CalcRetracement();
                  break;
               }
            } else {
               if (cHigh > D2) {
                  max = cHigh;
                  maxt = Time[1];
                  upTrend = True;
                  CalcRetracement();
                  break;
               }
            }
         break;
         
         // 2 = Find trend line
         case 2:
            // If we are between D1-D2 we have a trend line, go to next state...
            // If we are past D2, the retracement is cancelled and we go back to previous state!
            if (CheckD1D2()) {
               CalcTrend();
               state = 3;
               break;
            }
            if (CheckD2()) {
               trendMin = 1000;
               trendMax = 0;
               state = 1;
               break;
            }
            if (CheckMinMax()) {
               CalcRetracement();
               trendMin = 1000;
               trendMax = 0;
               state = 1;
               break;
            }
         break;
         
         // 3 = Find buy line...
         case 3:
            // Check buy line... If buy line reached, chase H1...
            if (CheckBuyline()) {
               Print("Buy line!!!");
               state = 4;
               break;
            }
            // Check if busted (below or above retracement's D2)
            if (CheckD2()) {
               trendMin = 1000;
               trendMax = 0;
               state = 1;
               break;
            }
            // Update trend line if between D1 and D2....
            if (CheckD1D2()) {
               CalcTrend();
               break;
            }
         break;
            
         // 4 = chase H1...
         case 4:
            if (CheckH1()) {
               Print("H1!!!");
               state = 5;
               break;
            }
            // Check if busted (below or above retracement's D2)
            if (CheckD2()) {
               trendMin = 1000;
               trendMax = 0;
               state = 1;
               break;
            }
            // Update trend line if between D1 and D2....
            if (CheckD1D2()) {
               CalcTrend();
               break;
            }
            
            break;
         // 5 = Find H2
         case 5:
            if (CheckH2()) {
               Print("H2!!!");
               state = 1;
               break;
            }
            // Check if busted (below or above retracement's D2)
            if (CheckD2()) {
               trendMin = 1000;
               trendMax = 0;
               state = 1;
               break;
            }
            // Update trend line if between D1 and D2....
            if (CheckD1D2()) {
               CalcTrend();
               break;
            }
         break;
         
      }
   Comment("State:" + IntegerToString(state) + " upTrend:" + IntegerToString(upTrend) + " cHigh:" + DoubleToStr(cHigh) + " cLow:" + DoubleToStr(cLow));
   }

}
//+------------------------------------------------------------------+

int start() {

   return(0);
   
}

bool CheckLevelR(double lev) {
   
   bool res = FALSE;
   
   if(upTrend){
      if (cLow < lev && cHigh > lev) {res=TRUE;}
   } else {
      if (cLow < lev && cHigh > lev) {res=TRUE;}
   }
   
   return(res);

}

void CalcRetracement(){

   double delta;
   delta = max - min;
   ObjectDelete("TREND");
   ObjectDelete("RETR");
   
   if (upTrend) {
      D1 = max - initD1 * delta;
      D2 = max - initD2 * delta;
      H1 = max - initH1 * delta;
      H2 = max - initH2 * delta;
      StopLoss = D2 - 0.0001;
      FiboLevelsCreate(0,"RETR",0,mint,min,maxt,max,255,0,1,FALSE,TRUE,FALSE,FALSE,TRUE,0);
   }
   else {
      D1 = min + initD1 * delta;
      D2 = min + initD2 * delta;
      H1 = min + initH1 * delta;
      H2 = min + initH2 * delta;
      StopLoss = D2 + 0.0001;
      FiboLevelsCreate(0,"RETR",0,maxt,max,mint,min,255,0,1,FALSE,TRUE,FALSE,FALSE,TRUE,0);
   }

   SetupRetrFibo();

   Print("Retracement (time/value):" + TimeToStr(mint) + ", " + DoubleToStr(min) + ", " + TimeToStr(maxt) + ", " + DoubleToStr(max) );
}

void CalcTrend(){

   double delta;
   delta = max - min;
   ObjectDelete("TREND");
   
   if (upTrend) {
      buyTrigger = cLow + initD2 * (max - cLow);
      trendMin = cLow;
      FiboLevelsCreate(0,"TREND",0,maxt,max,Time[1],cLow,200,0,1,FALSE,TRUE,FALSE,FALSE,TRUE,0);
   }
   else {
      buyTrigger = cLow + initD2 * (max - cLow);
      trendMax = cHigh;
      FiboLevelsCreate(0,"TREND",0,mint,min,Time[1],cHigh,200,0,1,FALSE,TRUE,FALSE,FALSE,TRUE,0);
   }

   SetupTrendFibo();

   Comment("Trend:" + TimeToStr(mint) + ", " + DoubleToStr(min) + ", " + TimeToStr(maxt) + ", " + DoubleToStr(max) );
}

bool CheckD1D2() {
   bool myCheck = False;
   if(upTrend) {
      if (cLow < D1 && cLow > D2) {myCheck = True;}
   } else {
      if (cHigh > D1 && cHigh < D2) {myCheck = True;}
   }
   return(myCheck);
}

bool CheckD2() {
   bool myCheck = False;
   if(upTrend) {
      if (cLow < D2) {myCheck = True;}
   } else {
      if (cHigh > D2) {myCheck = True;}
   }
   return(myCheck);
}

bool CheckMinMax() {
   bool myCheck = False;
   bool minmaxChangeHigh = FALSE;
   bool minmaxChangeLow = FALSE;
   if (cHigh > max){
      max = cHigh;
      maxt = Time[1];
      upTrend = TRUE;
      minmaxChangeHigh = TRUE;
   }
   if (cLow < min){
      min = cLow;
      mint = Time[1];
      upTrend = FALSE;
      minmaxChangeLow = TRUE;
   }
   if ((minmaxChangeHigh && !minmaxChangeLow) || (!minmaxChangeHigh && minmaxChangeLow)){myCheck = True;}
   return(myCheck);
}

bool CheckBuyline() {
   bool myCheck = False;
   if(upTrend) {
      if (cHigh > buyTrigger) {myCheck = True;}
   } else {
      if (cLow < buyTrigger) {myCheck = True;}
   }
   return(myCheck);
}

bool CheckH1() {
   bool myCheck = False;
   if(upTrend) {
      if (cHigh > H1) {myCheck = True;}
   } else {
      if (cLow < H1) {myCheck = True;}
   }
   return(myCheck);
}

bool CheckH2() {
   bool myCheck = False;
   if(upTrend) {
      if (cHigh > H2) {myCheck = True;}
   } else {
      if (cLow < H2) {myCheck = True;}
   }
   return(myCheck);
}

bool FiboLevelsCreate(const long            chart_ID=0,        // chart's ID
                      const string          name="FiboLevels", // object name
                      const int             sub_window=0,      // subwindow index 
                      datetime              time1=0,           // first point time
                      double                price1=0,          // first point price
                      datetime              time2=0,           // second point time
                      double                price2=0,          // second point price
                      const color           clr=clrRed,        // object color
                      const ENUM_LINE_STYLE style=STYLE_SOLID, // object line style
                      const int             width=1,           // object line width
                      const bool            back=false,        // in the background
                      const bool            selection=true,    // highlight to move
                      const bool            ray_left=false,    // object's continuation to the left
                      const bool            ray_right=false,   // object's continuation to the right
                      const bool            hidden=true,       // hidden in the object list
                      const long            z_order=0)         // priority for mouse click
{
   //--- set anchor points' coordinates if they are not set
      ChangeFiboLevelsEmptyPoints(time1,price1,time2,price2);
   //--- reset the error value
      ResetLastError();
   //--- Create Fibonacci Retracement by the given coordinates
      if(!ObjectCreate(chart_ID,name,OBJ_FIBO,sub_window,time1,price1,time2,price2))
        {
         Print(__FUNCTION__,
               ": failed to create \"Fibonacci Retracement\"! Error code = ",GetLastError());
         return(false);
        }
   //--- set color
      ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
   //--- set line style
      ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
   //--- set line width
      ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
   //--- display in the foreground (false) or background (true)
      ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
   //--- enable (true) or disable (false) the mode of highlighting the channel for moving
   //--- when creating a graphical object using ObjectCreate function, the object cannot be
   //--- highlighted and moved by default. Inside this method, selection parameter
   //--- is true by default making it possible to highlight and move the object
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
   //--- enable (true) or disable (false) the mode of continuation of the object's display to the left
      ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
   //--- enable (true) or disable (false) the mode of continuation of the object's display to the right
      ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
   //--- hide (true) or display (false) graphical object name in the object list
      ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
   //--- set the priority for receiving the event of a mouse click in the chart
      ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
   //--- successful execution
      return(true);
}

bool FiboLevelsSet(int             levels,            // number of level lines
                   double          &values[],         // values of level lines
                   color           &colors[],         // color of level lines
                   ENUM_LINE_STYLE &styles[],         // style of level lines
                   int             &widths[],         // width of level lines
                   const string    &names[],
                   const long      chart_ID=0,        // chart's ID
                   const string    name="FiboLevels") // object name
{
   //--- check array sizes
      if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
         levels!=ArraySize(widths) || levels!=ArraySize(widths))
        {
         Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
         return(false);
        }
   //--- set the number of levels
      ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
   //--- set the properties of levels in the loop
      for(int i=0;i<levels;i++)
        {
         //--- level value
         ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
         //--- level color
         ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
         //--- level style
         ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
         //--- level width
         ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
         //--- level description
         ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,names[i]);
        }
   //--- successful execution
      return(true);
}

void SetupRetrFibo() {
   double v[4];
   color c[4];
   ENUM_LINE_STYLE s[4];
   int w[4];
   string n[4];
   v[0] = 0.5;c[0] = 255;s[0] = 1;w[0] = 1;n[0] = "d1"; 
   v[1] = 0.618; c[1] = 255; s[1] = 1; w[1] = 1;n[1] = "d2";
   v[2] = -0.236; c[2] = 255; s[2] = 1; w[2] = 1;n[2] = "h1";
   v[3] = -0.618; c[3] = 255; s[3] = 1; w[3] = 1;n[3] = "h2";
   FiboLevelsSet(4,v,c,s,w,n,0,"RETR");
}

void SetupTrendFibo() {
   double v[1];
   color c[1];
   ENUM_LINE_STYLE s[1];
   int w[1];
   string n[1];
   v[0] = 0.618;c[0] = 200;s[0] = 2;w[0] = 1;n[0] = "buy";
   FiboLevelsSet(1,v,c,s,w,n,0,"TREND");
}

void ChangeFiboLevelsEmptyPoints(datetime &time1,double &price1,
                                 datetime &time2,double &price2)
{
   //--- if the second point's time is not set, it will be on the current bar
      if(!time2)
         time2=TimeCurrent();
   //--- if the second point's price is not set, it will have Bid value
      if(!price2)
         price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
   //--- if the first point's time is not set, it is located 9 bars left from the second one
      if(!time1)
        {
         //--- array for receiving the open time of the last 10 bars
         datetime temp[10];
         CopyTime(Symbol(),Period(),time2,10,temp);
         //--- set the first point 9 bars left from the second one
         time1=temp[0];
        }
   //--- if the first point's price is not set, move it 200 points below the second one
      if(!price1)
         price1=price2-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}