Odd behaviour of WHILE operator - page 3

 
Does it need to be WHILE while we can use FOR?
 

when is this while starting and

when does this while Stops ???

while (StringHighStatus == "False" && SwingHighShift <= SwingBarCount)
 
This will never be true (The == operand. - MQL4 forum)
if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift)
therefor, this is never executed
StringHighStatus="True";
resulting in an infinite loop.
while(StringHighStatus=="False" || ...
  1. Had you printed your variables and entries before and inside if statements, you would have figured this out.
  2. Don't use strings or ints when you mean boolean.
    string StringHighStatus = "False";
    while (StringHighStatus == "False" || SwingHighShift <= SwingBarCount){
       if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == ...{
          StringHighStatus = "True";
    
    bool StringHighStatus = False;
    while (!StringHighStatus || SwingHighShift <= SwingBarCount){
       if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == ...{
          StringHighStatus = True;
    

 
WHRoeder:
This will never be true (The == operand. - MQL4 forum)
therefor, this is never executed
resulting in an infinite loop.

I thought the same thing until I tested it, suprisingly enough the if(double == double) part of it does work, it makes me wonder if comparison of doubles is handled differently in the new builds.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   for(int i=0; i<100; i++)
   {if(iFractals(NULL, 0, MODE_UPPER, i) == iHigh(NULL, 0, i) && iFractals(NULL, 0, MODE_UPPER, i) > Close[0])
    Print("Fractals conditions met on bar ",i);
  }} 

EURUSD,M15: Fractals conditions met on bar 98
EURUSD,M15: Fractals conditions met on bar 95
EURUSD,M15: Fractals conditions met on bar 91
EURUSD,M15: Fractals conditions met on bar 81
EURUSD,M15: Fractals conditions met on bar 77
EURUSD,M15: Fractals conditions met on bar 68
EURUSD,M15: Fractals conditions met on bar 61
EURUSD,M15: Fractals conditions met on bar 48
EURUSD,M15: Fractals conditions met on bar 39
EURUSD,M15: Fractals conditions met on bar 24
EURUSD,M15: Fractals conditions met on bar 19
EURUSD,M15: Fractals conditions met on bar 12
EURUSD,M15: Fractals conditions met on bar 4

 
lord_hiro:

Thank you GumRai for your patience.

Maybe I'm wrong and hard headed but I can't understand the logic...

If the first IF turns, as you suggest, the string to "true" at say SwinghHighShift=10 then the counted doesn't increase in that cycle; after that the control gets back to the WHILE: the cycle should end at this point because the WHILE contains a logical OR and one of it's condition is satisfied.

Conversely if the variable stays false the counter should reach its maximum value and again you have the exit condition.

I think your consideration would be true with an AND operator.

Following your interpretation I could skip the OR inside the WHILE; I could just put the first IF condition on the string: if turns to "true" then the break will end the WHILE, otherwise the counter would go on on till its maximum.

The code will turn to:


But this is still a workaround and, sadly, it does not explain (to me) why the WHILE doesn't take care of the OR.

There is nothing wrong with WHILE or logical OR, you have two conditions in your WHILE, BOTH of them must be broken before the WHILE can exit.

This is why it gets stuck

  • Code enters WHILE loop. Both condtions are true to begin with.
  • Code cycles through the WHILE loop incrementing SwingHighShift++ until a bar is found with fractals to satisfy the IF conditions.
  • Sooner or later Code enters IF operators when fractals meet the conditions.
  • StringHighStatus is changed to false so the first WHILE condition is broken.
  • SwingHighShift++; is NOT incremented because it is in the ELSE part of the IF operator (the IF condition was met so ELSE is ignored).
  • Second WHILE condition is still true so code cycles again STILL ON THE SAME BAR AS LAST TIME.
  • the same fractal meets the IF conditions again just like it did last time.
  • Code is now stuck forever looping on that bar with fractal that meet the IF conditions because SwingHighShift++ in the ELSE part does not get incremented when the IF conditions are true.

There is only a slim chance that while loop could ever exit and that is when the IF condition is not met for the entire 100 Bars (SwingBarCount) so the 2nd WHILE condition is broken before the 1st. Then subsequently the Fractals satisfy the IF condition and the code to break the 1st WHILE condition (modify StringHighStatus) is executed.

You either need to take SwingHighShift++; out of the ELSE and put it by itself in the while loop after the IF operator so regardless of what happens with the IF conditions it still increments so the loop can move on to the next bar, or use break after the object drawing code block to break out of the while once the object is drawn.

You also need to give your object a way to create different names for itself otherwise it will only be drawn once. (unless you only want it to be drawn once).

 
I read back over your posts in this thread I see where your confusion arises now. You are thinking the logic of WHILE and OR in reverse. The OR it is not about stopping the WHILE. It is about keeping it going when either condition is valid... It is like this, you have two lights turned on. Your instruction is, While light 1 OR light 2 is on, keep doing something. Obviously both lights have to be off before you quit, not just one of them.
 
SDC:

I thought the same thing until I tested it, suprisingly enough the if(double == double) part of it does work, it makes me wonder if comparison of doubles is handled differently in the new builds.

EURUSD,M15: Fractals conditions met on bar 98
EURUSD,M15: Fractals conditions met on bar 95
EURUSD,M15: Fractals conditions met on bar 91
EURUSD,M15: Fractals conditions met on bar 81
EURUSD,M15: Fractals conditions met on bar 77
EURUSD,M15: Fractals conditions met on bar 68
EURUSD,M15: Fractals conditions met on bar 61
EURUSD,M15: Fractals conditions met on bar 48
EURUSD,M15: Fractals conditions met on bar 39
EURUSD,M15: Fractals conditions met on bar 24
EURUSD,M15: Fractals conditions met on bar 19
EURUSD,M15: Fractals conditions met on bar 12
EURUSD,M15: Fractals conditions met on bar 4


The reason it works is because the code is effectively comparing the same value

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift) )

The fractal buffer will either have an Empty value or it will take it's value from the high of the relevant bar.

The code is effectively

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE && iHigh(NULL,0,SwingHighShift==iHigh(NULL,0,SwingHighShift) 

I see no reason that it can't be replaced by

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE)
 
GumRai:

I see no reason that it can't be replaced by

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE)
Yes I think that is a better way of doing it.
 
SDC:
I read back over your posts in this thread I see where your confusion arises now. You are thinking the logic of WHILE and OR in reverse. The OR it is not about stopping the WHILE. It is about keeping it going when either condition is valid... It is like this, you have two lights turned on. Your instruction is, While light 1 OR light 2 is on, keep doing something. Obviously both lights have to be off before you quit, not just one of them.


That's it!

Shame on me... :-)

Moreover it's not the first time I use WHILE but I started thinking in reverse and never came out of MY OWN loop :-/

And so the deVries' suggestion of replacing || with && turns right.

A lot of other things to take care of came out from this topic, i.e. whit the IF( == ) works.

Thank you all for your patience and the time you spent to make me understand.

 

I woulkd have do it that way, with a break, to break the while loop, is it correct ?

  int counter=0, MaxCount = 10000;
  while( true )
     {
      Print("Counter ", counter);
      counter++;
      if( counter == MaxCount ) break;
      }
   
Reason: