# Wrong drawing with fibonacci retracement !!!

24

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...
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 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);
}
```