Comportamento strano dell'operatore WHILE

 

Ciao a tutti!

Ho un EA (mai testato su build precedenti alla 600 ma il codice è vecchio di 2 anni) che si blocca durante un WHILE sulla build 625.

Il fatto è che quando parte il WHILE sembra non riuscire a controllare le espressioni: il risultato è che non esce mai. Si posiziona nella funzione di avvio.

Ho provato un EA molto semplice per capire cosa succede:


int counter=0, MaxCount = 10000; 

void start()
  {
  while( counter <= MaxCount )
   {Print("Counter ", counter);
   counter++;
   }
   return;
  }

Ebbene, il primo valore del contatore di solito parte da un valore casuale superiore a 9500 e non da 0.

Perché? Qualche suggerimento?

 

forse il contatore ottiene un altro valore da qualche altra parte all'interno dell'EA:

void start()
  {
  int counter=0, MaxCount = 10000;
  while( counter <= MaxCount )
   {Print("Counter ", counter);
   counter++;
   }
   return;
  }
 
lord_hiro:

Ciao a tutti!

Ho un EA (mai testato su build precedenti alla 600 ma il codice è vecchio di 2 anni) che si blocca durante un WHILE sulla build 625.

Il fatto è che quando parte il WHILE sembra non riuscire a controllare le espressioni: il risultato è che non esce mai. Si posiziona nella funzione di avvio.

Ho provato un EA molto semplice per capire cosa succede:

Ebbene, il primo valore del contatore di solito parte da un valore casuale superiore a 9500 e non da 0.

Perché? Qualche suggerimento?

Hai dichiarato il contatore a livello globale, il che significa che è statico.

Il tuo codice in OnStart(), counter++ spinge il valore del contatore fino a 10.000

Quindi, poiché è statico, al prossimo tick il tuo contatore è a 10.000 per cominciare.

 
SDC:

Avete dichiarato il contatore a livello globale, il che significa che è statico.

Il tuo codice in OnStart(), counter++ spinge il valore del contatore fino a 10.000

Quindi, poiché è statico, al prossimo tick il tuo contatore è a 10.000 per cominciare.


ha scritto:

lord_hiro:

Beh, il primo valore del contatore di solito parte da un valore casuale sopra 9500 e non da 0.

Perché è così? Qualche suggerimento?


Quindi, questa è la mia risposta


qjol:

forse il contatore prende un altro valore da qualche altra parte all'interno dell'EA prova:

void start()
  {
  int counter=0, MaxCount = 10000;
  while( counter <= MaxCount )
   {Print("Counter ", counter);
   counter++;
   }
   return;
  }
 
lord_hiro:

Ciao a tutti!

Ho un EA (mai testato su build precedenti alla 600 ma il codice è vecchio di 2 anni) che si blocca durante un WHILE sulla build 625.

Il fatto è che quando parte il WHILE sembra non riuscire a controllare le espressioni: il risultato è che non esce mai. Si posiziona nella funzione di avvio.

Ho provato un EA molto semplice per capire cosa succede:


Ebbene, il primo valore del contatore di solito parte da un valore casuale superiore a 9500 e non da 0.

Perché? Qualche suggerimento?



Molto probabilmente state cercando nella scheda Experts, che non può tenere il passo con cicli veloci come questo.

Aprite il file di log attuale.

 

Posso dirvi una cosa, quel ciclo while non verrebbe mai eseguito una seconda volta a meno che da qualche altra parte nel codice non chiamiate di nuovo quella variabile contatore e ne cambiate il valore a meno di 10.001. Dovresti fare attenzione a dichiarare le variabili globalmente.

 
lord_hiro: Bene, il primo valore del contatore di solito parte da un valore casuale sopra 9500 e non da 0. Perché? Qualche suggerimento?
Prima della build 600 le variabili non inizializzate erano inizializzate a zero. Ora contengono valori casuali, a meno che non le inizializzi...
 
Li ha inizializzati, deve essere qualcos'altro che cambia il valore di quella variabile del contatore...
 
Come ha detto GumRai, il log non può gestire quella velocità, salta la maggior parte dei dati reali e ti mostra solo alcuni frammenti.
 

GumRai, hai ragione: il log riporta tutte le uscite a partire da 1.

La differenza tra mettere la dichiarazione della variabile nello spazio globale invece che dentro OnStart() è che nel primo caso il ciclo viene eseguito una sola volta mentre nel secondo si ripete all'infinito.

Ma... È evidente che ho scelto l'esempio di debug sbagliato perché il ciclo di conteggio viene eseguito bene.

Tutto è iniziato con il seguente EA.

Ecco il codice:

 extern int SwingBarCount = 100;
int start()



{

int SwingHighShift = 0;
string StringHighStatus = "False";
int SwingHigh = 0;


while (StringHighStatus == "False" || SwingHighShift <= SwingBarCount)
   {
   
   if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == iHigh(NULL, 0, SwingHighShift) && iFractals(NULL, 0, MODE_UPPER, SwingHighShift) > Close[0])
      {
      StringHighStatus = "True";
      SwingHigh = SwingHighShift;
      ObjectDelete("SwingHigh");
      ObjectCreate("SwingHigh", OBJ_VLINE, 0, Time[SwingHigh], 0);
      ObjectSet("SwingHigh", OBJPROP_COLOR, Red);
      }
      else
      {
      SwingHighShift++;
      }

   }

}}

Ho rimosso l'altro codice non rilevante per chiarezza e viene eseguito fino al WHILE perché ho messo dei breakpoint prima.

Dovrebbe iniziare con la condizione WHILE vera e ciclare l'IF ELSE fino a quando StringHighStatus diventa vero o StringHighShift raggiunge SwingBarCount.

Quello che vedo invece è che non finisce mai perché dopo il WHILE c'è una serie di comandi COMMENT e PRINT che non restituiscono alcun output.

Mentre StringHighStatus può rimanere falso, il contatore deve raggiungere SwingBarCount.

Ho dovuto modificare in questo modo perché funzionasse:

while (!EndCycle)
   {
   
   if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == iHigh(NULL, 0, SwingHighShift) && iFractals(NULL, 0, MODE_UPPER, SwingHighShift) > Close[0])
      {
      StringHighStatus = "True";
      SwingHigh = SwingHighShift;
      ObjectDelete("SwingHigh");
      ObjectCreate("SwingHigh", OBJ_VLINE, 0, Time[SwingHigh], 0);
      ObjectSet("SwingHigh", OBJPROP_COLOR, Red);
      }
      else
      {
      SwingHighShift++;
      }
      if( StringHighStatus == "True" ) EndCycle = TRUE;
      if( SwingHighShift > SwingBarCount ) EndCycle = TRUE;
   }

Non capisco perché elabora EndCycle e non l'altra condizione.

Grazie a tutti per le vostre risposte!

 
if( StringHighStatus == "True" ) EndCycle = TRUE;
else if( SwingHighShift > SwingBarCount ) EndCycle = TRUE;
provare a includere altro.