Comportamiento extraño del operador WHILE

 

¡Hola a todos!

Tengo un EA (nunca lo he probado en builds anteriores a la 600 pero el código tiene 2 años) que se bloquea durante un WHILE en la build 625.

El caso es que cuando se inicia el WHILE parece que no puede comprobar las expresiones: el resultado es que nunca sale . Se coloca en la función de inicio.

He probado con un EA muy sencillo para entender lo que pasa:


int counter=0, MaxCount = 10000; 

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

Pues bien, el primer valor del contador suele partir de un valor aleatorio superior a 9500 y no de 0.

¿Por qué es así? ¿Alguna sugerencia?

 

tal vez el contador obtiene otro valor en algún otro lugar dentro de la prueba de EA :

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

¡Hola a todos!

Tengo un EA (nunca lo he probado en builds anteriores a la 600 pero el código tiene 2 años) que se bloquea durante un WHILE en la build 625.

El caso es que cuando se inicia el WHILE parece que no puede comprobar las expresiones: el resultado es que nunca sale . Se coloca en la función de inicio.

He probado con un EA muy sencillo para entender lo que pasa:

Pues bien, el primer valor del contador suele partir de un valor aleatorio superior a 9500 y no de 0.

¿Por qué es así? ¿Alguna sugerencia?

Has declarado el contador de forma global, lo que significa que es estático.

Tu código en OnStart(), counter++ empuja el valor del contador hasta 10.000

Entonces, como es estático, en el siguiente tick tu contador está en 10.000 para empezar.

 
SDC:

Has declarado el contador globalmente, lo que significa que es estático.

Tu código en OnStart(), counter++ empuja el valor del contador hasta 10.000

Entonces, como es estático, en el siguiente tick tu contador está en 10.000 para empezar.


escribió:

lord_hiro:

Bueno, el primer valor del contador suele partir de un valor aleatorio por encima de 9500 y no de 0.

¿Por qué es así? ¿Alguna sugerencia?


esta es mi respuesta


qjol:

tal vez el contador obtiene otro valor en algún otro lugar dentro de la EA tratar :

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

¡Hola a todos!

Tengo un EA (nunca lo he probado en builds anteriores a la 600 pero el código tiene 2 años) que se bloquea durante un WHILE en la build 625.

El caso es que cuando se inicia el WHILE parece que no puede comprobar las expresiones: el resultado es que nunca sale . Se coloca en la función de inicio.

He probado con un EA muy sencillo para entender lo que pasa:


Pues bien, el primer valor del contador suele partir de un valor aleatorio superior a 9500 y no de 0.

¿Por qué es así? ¿Alguna sugerencia?



Lo más probable es que estés buscando en la pestaña de Expertos, que no puede seguir el ritmo de bucles rápidos como éste.

Abra el archivo de registro real.

 

Puedo decirte una cosa, ese bucle while nunca se ejecutaría una segunda vez a menos que en algún lugar del código llames de nuevo a esa variable contador y cambies su valor de nuevo a menos de 10.001. Debes tener cuidado al declarar variables de forma global.

 
lord_hiro: Pues bien, el primer valor del contador suele partir de un valor aleatorio por encima de 9500 y no de 0. ¿A qué se debe? ¿Alguna sugerencia?
Antes de la build 600 las variables no inicializadas se inicializaban a cero. Ahora contienen valores aleatorios, a menos que las inicialices..
 
Sí los inicializó, debe ser otra cosa la que cambia el valor de esa variable del contador...
 
Como dijo GumRai, el registro no puede manejar esa velocidad, se salta la mayoría de los datos reales y te muestra sólo algunos fragmentos.
 

GumRai, tienes razón: el registro informa de todas las salidas empezando por la 1.

La diferencia entre poner la declaración de la variable en el espacio global en lugar de dentro de OnStart() es que en el primer caso el bucle se ejecuta una vez mientras que en el segundo se repite indefinidamente.

Pero... Es evidente que elegí mal el ejemplo de depuración porque el ciclo de conteo se ejecuta bien.

Todo empezó con el siguiente EA.

Aquí está el código:

 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++;
      }

   }

}}

He quitado el otro código no relevante para mayor claridad y se ejecuta hasta el WHILE porque puse algunos puntos de interrupción antes.

Debería comenzar con la condición WHILE siendo verdadera y ciclar el IF ELSE hasta que StringHighStatus se haga verdadero o StringHighShift alcance SwingBarCount.

Lo que veo en cambio es que nunca termina porque después del WHILE hay una serie de comandos COMMENT y PRINT que no devuelven ninguna salida.

Mientras StringHighStatus puede permanecer falso, el contador tiene que alcanzar SwingBarCount.

He tenido que modificar así para que funcione:

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;
   }

No entiendo por qué procesa EndCycle y no la otra condición.

Gracias a todos por vuestras respuestas.

 
if( StringHighStatus == "True" ) EndCycle = TRUE;
else if( SwingHighShift > SwingBarCount ) EndCycle = TRUE;
intente incluir otra cosa.