iFractals redrawing with shift of 3

 

When using the iFractals function of MQL4 I am getting some unexpected redrawing of the fractal moves when using a shift of 3 (I am drawing lines).

Used in an indicator like so:

int start() {
   int    counted_bars=IndicatorCounted();
   int i=Bars-counted_bars-1;
 
   while(i>=0) {
      double upFrac=iFractals(NULL,0,MODE_UPPER,i+3);     
      double loFrac=iFractals(NULL,0,MODE_LOWER,i+3);
      if(upFrac>0) {
         GlobalVariableSet(Symbol()+Period()+"upfrac",upFrac);
      }
      else if(loFrac>0) {
         GlobalVariableSet(Symbol()+Period()+"lofrac",loFrac);
      }
      UpBuffer[i+3] = GlobalVariableGet(Symbol()+Period()+"upfrac");
      DownBuffer[i+3] = GlobalVariableGet(Symbol()+Period()+"lofrac");
      i--;
   }
   return(0);
}

This normally works like it should, drawing the line of the current fractal value, occasionally though it is drawing a line, a trade is placed partially based on it and then that fractal line redraws in a different position before the the chart moves onto the next bar (15M Bars).

I thought that if a shift of 3 is used, this means that it shouldn't be reading any High / Low values from the current bar (which could change), thus the values it is reading during the course of one bar shouldn't change, therefore it shouldn't redraw.

Am I misunderstanding or is there something going on in the iFractals method that is using a value from the current bar as part of its calculation?

Thanks!

 

Not sure if it is a concern or if it is related to your conundrum but I wouldn't force a conditional either/or assignment regarding whether or not lofrac is evaluated.

int start() {
   int    counted_bars=IndicatorCounted();
   int i=Bars-counted_bars-1;

   while(i>=0) {
      double upFrac=iFractals(NULL,0,MODE_UPPER,i+3);     
      double loFrac=iFractals(NULL,0,MODE_LOWER,i+3);
      if(upFrac>0) {
         GlobalVariableSet(Symbol()+Period()+"upfrac",upFrac);
      }
//      else if(loFrac>0) { <- not a good idea perchance both lofrac and upfrac change values at same time
      if(loFrac>0) {  // this lets both upfrac and lofrac have the potential for changing in same evaluation bar
         GlobalVariableSet(Symbol()+Period()+"lofrac",loFrac);
      }
      UpBuffer[i+3] = GlobalVariableGet(Symbol()+Period()+"upfrac");
      DownBuffer[i+3] = GlobalVariableGet(Symbol()+Period()+"lofrac");
      i--;
   }
   return(0);
}
The next concern I'd have if I were you (I use iFractals) is that the iFractal value is a double but machine-precision double zero is never guaranteed to be identical to integer zero. Evaluating "lofrac>0" can be problematic if lofrac is intended to be zero but us actually 0.0000000000000001.

My solution to this is to take into account the fact that the value returned by iFractals is in fact supposed to be the High/Low market value of the financial instrument under evaluation. Meaning the value should have no more precision than that of a market price such as Ask or Bid.

Thus I do the following:
int start() {
   int    counted_bars=IndicatorCounted();
   int i=Bars-counted_bars-1;

   while(i>=0) {
      int upFrac=NormalizeDouble(iFractals(NULL,0,MODE_UPPER,i+3),Digits)/Point; // convert to integer value so that 0 == 0
      int loFrac=NormalizeDouble(iFractals(NULL,0,MODE_LOWER,i+3),Digits)/Point; // convert to integer value so that 0 == 0
      if(upFrac!=0) { // evaluate expression against !=0 instead of >0
         GlobalVariableSet(Symbol()+Period()+"upfrac",upFrac*Point); // multiply the integer value by point to convert back to market price
      }
//      else if(loFrac>0) {
      if(loFrac!=0) { // evaluate expression against !=0 instead of >0
         GlobalVariableSet(Symbol()+Period()+"lofrac",loFrac*Point); // multiply the integer value by point to convert back to market price
      }
      UpBuffer[i+3] = GlobalVariableGet(Symbol()+Period()+"upfrac");
      DownBuffer[i+3] = GlobalVariableGet(Symbol()+Period()+"lofrac");
      i--;
   }
   return(0);
}