Comportamento strano dell'operatore WHILE - pagina 3

 
Deve essere WHILE mentre possiamo usare FOR?
 

quando è questo mentre si avvia e

quando questo mentre si ferma?

while (StringHighStatus == "False" && SwingHighShift <= SwingBarCount)
 
Questo non sarà mai vero (L'operando ==. - MQL4 forum)
if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift)
quindi, questo non viene mai eseguito
StringHighStatus="True";
risultando in un ciclo infinito.
while(StringHighStatus=="False" || ...
  1. Se aveste stampato le vostre variabili e voci prima e dentro le dichiarazioni if, lo avreste capito.
  2. Non usare stringhe o ints quando intendi booleano.
    string StringHighStatus = "False";
    while (StringHighStatus == "False" || SwingHighShift <= SwingBarCount){
       if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == ...{
          StringHighStatus = "True";
    
    bool String HighStatus = False;
    while (!String HighStatus || SwingHighShift <= SwingBarCount){
       if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == ...{
          String HighStatus = True;
    

 
WHRoeder:
Questo non sarà mai vero (L'operando ==. - MQL4 forum)
quindi, questo non viene mai eseguito
risultando in un ciclo infinito.

Ho pensato la stessa cosa finché non l'ho testato, abbastanza sorprendentemente la parte if(double == double) funziona, mi fa pensare che il confronto dei doppi sia gestito diversamente nelle nuove versioni.

//+------------------------------------------------------------------+
//| 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: Condizioni frattali soddisfatte sulla barra 98
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 95
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 91
EURUSD,M15: Condizioni frattali soddisfatte nella barra 81
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 77
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 68
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 61
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 48
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 39
EURUSD,M15: Condizioni frattali soddisfatte nella barra 24
EURUSD,M15: Condizioni frattali soddisfatte nella barra 19
EURUSD,M15: Condizioni frattali soddisfatte nella barra 12
EURUSD,M15: Condizioni frattali soddisfatte nella barra 4

 
lord_hiro:

Grazie GumRai per la tua pazienza.

Forse mi sbaglio e ho la testa dura ma non riesco a capire la logica...

Se il primo IF trasforma, come suggerisci tu, la stringa in "true" a diciamo SwinghHighShift=10 allora il contatore non aumenta in quel ciclo; dopo di che il controllo torna al WHILE: il ciclo dovrebbe finire a questo punto perché il WHILE contiene un OR logico e una delle sue condizioni è soddisfatta.

Viceversa se la variabile rimane falsa il contatore dovrebbe raggiungere il suo valore massimo e di nuovo si ha la condizione di uscita.

Penso che la tua considerazione sarebbe vera con un operatore AND.

Seguendo la tua interpretazione potrei saltare l'OR all'interno del WHILE; potrei semplicemente mettere la prima condizione IF sulla stringa: se diventa "vero" allora il break terminerà il WHILE, altrimenti il contatore andrebbe avanti fino al suo massimo.

Il codice si trasformerà in:


Ma questo è ancora un workaround e, purtroppo, non spiega (a me) perché il WHILE non si occupa dell'OR.

Non c'è niente di sbagliato nel WHILE o nell'OR logico, hai due condizioni nel tuo WHILE, ENTRAMBI devono essere rotti prima che il WHILE possa uscire.

Ecco perché si blocca

  • Il codice entra nel ciclo WHILE. Entrambe le condizioni sono vere per cominciare.
  • Il codice attraversa il ciclo WHILE incrementando SwingHighShift++ fino a trovare una barra con frattali che soddisfino le condizioni IF.
  • Prima o poi il codice entra negli operatori IF quando i frattali soddisfano le condizioni.
  • StringHighStatus è cambiato in false quindi la prima condizione WHILE è interrotta.
  • SwingHighShift++; NON viene incrementato perché è nella parte ELSE dell'operatore IF (la condizione IF è stata soddisfatta quindi ELSE viene ignorata).
  • La seconda condizione WHILE è ancora vera quindi il codice cicla di nuovo SULLA STESSA BARRA COME L'ULTIMA VOLTA.
  • lo stesso frattale incontra di nuovo le condizioni IF proprio come ha fatto l'ultima volta.
  • Il codice è ora bloccato per sempre in loop su quella barra con il frattale che soddisfa le condizioni IF perché SwingHighShift++ nella parte ELSE non viene incrementato quando le condizioni IF sono vere.

C'è solo una piccola possibilità che il ciclo while possa mai uscire e cioè quando la condizione IF non è soddisfatta per tutte le 100 barre (SwingBarCount), quindi la seconda condizione WHILE è rotta prima della prima. Quindi successivamente i frattali soddisfano la condizione IF e il codice per rompere la 1a condizione WHILE (modificare StringHighStatus) viene eseguito.

Avete bisogno di togliere SwingHighShift++; da ELSE e metterlo da solo nel ciclo while dopo l'operatore IF in modo che, indipendentemente da ciò che accade con le condizioni IF, esso continui ad aumentare in modo che il ciclo possa passare alla prossima barra, o usare break dopo il blocco di codice del disegno dell'oggetto per uscire dal while una volta che l'oggetto è stato disegnato.

Dovete anche dare al vostro oggetto un modo per creare diversi nomi per se stesso, altrimenti sarà disegnato solo una volta. (a meno che non vogliate che venga disegnato solo una volta).

 
Rileggendo i tuoi post in questo thread ho capito dove nasce la tua confusione ora. State pensando la logica del WHILE e dell'OR al contrario. L'OR non riguarda l'arresto del WHILE. Si tratta di tenerlo in corso quando una delle due condizioni è valida... È così, avete due luci accese. La tua istruzione è: Mentre la luce 1 O la luce 2 è accesa, continua a fare qualcosa. Ovviamente entrambe le luci devono essere spente prima che tu smetta, non solo una delle due.
 
SDC:

Ho pensato la stessa cosa finché non l'ho testato, abbastanza sorprendentemente la parte if(double == double) funziona, mi fa pensare che il confronto dei doppi sia gestito diversamente nelle nuove build.

EURUSD,M15: Condizioni frattali soddisfatte sulla barra 98
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 95
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 91
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 81
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 77
EURUSD,M15: Condizioni frattali soddisfatte sulla barra 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


Il motivo per cui funziona è che il codice sta effettivamente confrontando lo stesso valore

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

Il buffer frattale avrà un valore vuoto o prenderà il suo valore dal massimo della barra in questione.

Il codice è effettivamente

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

Non vedo perché non possa essere sostituito da

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

Non vedo perché non possa essere sostituito da

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE)
Sì, penso che sia un modo migliore di farlo.
 
SDC:
Rileggendo i tuoi post in questo thread ho capito dove nasce la tua confusione ora. State pensando la logica di WHILE e OR al contrario. L'OR non serve a fermare il WHILE. Si tratta di tenerlo in corso quando una delle due condizioni è valida... È così, avete due luci accese. La tua istruzione è: Mentre la luce 1 O la luce 2 è accesa, continua a fare qualcosa. Ovviamente entrambe le luci devono essere spente prima che tu smetta, non solo una delle due.


Questo è quanto!

Vergogna... :-)

Inoltre non è la prima volta che uso WHILE ma ho iniziato a pensare al contrario e non sono mai uscito dal MIO ciclo :-/

E così il suggerimento di deVries di sostituire || con && risulta giusto.

Un sacco di altre cose di cui occuparsi sono venute fuori da questo topic, cioè come funziona l'IF( == ).

Grazie a tutti per la vostra pazienza e il tempo che avete speso per farmi capire.

 

Avrei dovuto farlo così, con una pausa, per interrompere il ciclo while, è corretto?

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