función sueño alternativa

 

Hola comunidad MQL4,

He encontrado un problema al ejecutar un EA que incluye la función Sleep() en el probador de estrategias. Aparentemente el probador no ejecutará el EA correctamente con la inclusión de la función Sleep() incrustada en el código.

¿Algún codificador presente ha descubierto un método alternativo a la función Sleep() para codificar un EA para "esperar" una cierta cantidad de tiempo mientras el EA se ejecuta en el probador?


Gracias

 
WhooDoo22:

Hola comunidad MQL4,

He encontrado un problema al ejecutar un EA que incluye la función Sleep() en el probador de estrategias. Al parecer, el probador no ejecutará el EA correctamente con la inclusión de la función Sleep() incrustada en el código.

¿Algún codificador presente ha descubierto un método alternativo a la función Sleep() para codificar un EA para "esperar" una cierta cantidad de tiempo mientras el EA se ejecuta en el probador?

No hay ninguna razón lógica para que la función Sleep() funcione en el Probador de Estrategias... ¿qué está tratando de hacer? si está tratando de cronometrar un evento entonces use el tiempo y no trate de hacer una pausa por el tiempo requerido, eso no es para lo que sirve la función Sleep().
 

Simon,

Una de las razones por las que elegí utilizar la función 'Sleep()' fue porque Seconds() devuelve los valores de la última hora conocida del servidor (recuperar los datos de la última hora conocida del servidor hace que los segundos se salten y/o hagan una pausa). Deseo fiabilidad, no generalidad.

¿Qué opinas de esto?


Gracias

 
WhooDoo22:

Simon,

Una de las razones por las que elegí utilizar la función 'Sleep()' fue porque Seconds() devuelve los valores de la última hora conocida del servidor (recuperar los datos de la última hora conocida del servidor hace que los segundos se salten y/o se pausen).

¿Cuál es su prueba para esto? Usted sólo puede "ver" el tiempo para los tiempos que tienen ticks, si no hay ticks durante 30 segundos entonces usted verá un salto de 30 segundos ... no hay nada que pueda hacer sobre esto, es como es. Los tiempos de los ticks en el Probador de Estrategias deberían ser razonablemente uniformes ya que los ticks no son reales sino sintetizados.
 

Simón,

Por lo que escribes, una razón por la que puedo estar llamando a estos "saltos" y/o "pausas" en los segundos es porque no se crean ticks entre [segundos x] y [segundos y]. En términos simples, se crea un tick, ahora se guarda "segundos x". No se crea ningún tic durante tres segundos y luego se crea un tic. Ahora se guarda 'seconds y'. ('segundos y' = (segundos x +tres segundos)) como ('segundos x' = (segundos y-tres segundos)).

¿Qué me decís de esto?


Por el momento voy a considerar mis opciones.

Muchas gracias por sus respuestas.

 
  1. Hasta que regrese del inicio. No se crean NUNCA ticks en el probador. Guarde el TimeCurrent() en una variable estática/común(global). Siguiente tick int deltaSec = TimeCurrent() - anterior.
  2. https://www.mql5.com/en/forum/127483 informó que DayOfWeek() siempre devuelve 5 en el probador (definitivamente no es lo mismo en los indicadores, como es Ask y Bid) . Nunca uso NINGUNO de los Seconds(), DayOfWeek() etc. porque no quieres la hora actual del servidor, quieres la hora del tick del tester. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..
 
WhooDoo22:

Simón,

Por lo que escribes, una razón por la que puedo estar llamando a estos "saltos" y/o "pausas" en los segundos es porque no se crean ticks entre [segundos x] y [segundos y]. En términos simples, se crea un tick, ahora se guarda "segundos x". No se crea ningún tic durante tres segundos y luego se crea un tic. Ahora se guarda 'seconds y'. ('segundos y' = (segundos x +tres segundos)) como ('segundos x' = (segundos y-tres segundos)).

¿Qué te parece esto?

Sí, podría haber fácilmente 3 segundos entre los ticks, al igual que en el mundo real, echa un vistazo a cualquier par de divisas en la medianoche GMT, verás un montón de grandes tiempos de varios segundos entre los ticks ... incluso se puede obtener sin ticks durante más de un minuto y la falta de barras M1 ... no es una cosa rara.
 

William,

Muchas gracias por tu respuesta.

1. Hasta que no regrese del inicio. No se crean NUNCA ticks en el probador. Guarda el TimeCurrent() en una variable estática/común(global). Siguiente tick int deltaSec = TimeCurrent() - anterior.

No entiendo lo que quieres decir con "Hasta que vuelva del inicio". ¿Podría explicarlo?


"Nunca se crean ticks en el probador"

¿No quieres decir que no se crean ticks reales en el probador? ¿No está de acuerdo en que se crean ticks artificiales en el probador?


"Guarda el TimeCurrent() en una variable estática/común(global). Siguiente tick int deltaSec = TimeCurrent() - anterior".

Guardar TimeCurrent() enuna variable. Cuando llegue el siguiente tick, int deltaSec =TimeCurrent() - anterior.

¿No sería la variable "anterior" la variable en la que se guarda TimeCurrent()?

deltaSec = TimeCurrent() -(TimeCurrent() guardado en una variable anterior)

Por favor, aclara William.


https://www.mql5.com/en/forum/127483 informó que DayOfWeek() siempre devuelve 5 en el probador. Nunca uso NINGUNO de los Seconds(), DayOfWeek() etc. porque ahora quieres la hora actual del servidor, quieres la hora del tick del tester. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..


"quieres el tiempo del tick del probador".

Sí, CREO que esto es EXACTAMENTE lo que quiero al probar un EA en el probador de estrategias debido al post de Simon que describe el razonamiento detrás de por qué los segundos parecen saltar y/o hacer una pausa.


now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..

En otras palabras...

sec = TimeSeconds(TimeCurrent()); y DOW = TimeDayOfWeek(TimeCurrent());

¿Qué opinas de esto?


Gracias
 
WhooDoo22:

now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..

En otras palabras...

sec = TimeSeconds(TimeCurrent()); y DOW = TimeDayOfWeek(TimeCurrent());

Mira lo que te da TimeSeconds(), luego piensa en lo que te da TimeCurrent() . . ¿cuál necesita y por qué?
 
WhooDoo22:

No entiendo lo que quiere decir con "hasta que vuelva de la partida". ¿Podría explicarlo?"

No se crean garrapatas en el probador" ¿No quiere decir que no se crean garrapatas reales en el probador? ¿No está de acuerdo en que se crean garrapatas artificiales en el probador?

  1. int start(){
       // do something
       return; // Return from start.
    }
    int start(){
       // do something
       // Fall off the end is a Return from start.
    }

  2. No se crean ticks de ningún tipo hasta que vuelves y se crea el siguiente y se llama a tu start(). Si computa durante 5 minutos y devuelve el volumen (cuenta de ticks) en la siguiente llamada será +1. En un gráfico en vivo, si computa para 5 minutos, entonces perderá 5 minutos de ticks y en la M1 se habrán formado varias barras nuevas.
 
RaptorUK:
No hay ninguna razón lógica para que sleep() funcione en el Probador de Estrategias ...

ten cuidado con esa afirmación. siempre hay una razón lógica para ejecutar sleep(). en el Tester e incluso en los indicadores. cierto, para el caso de uso del OP no se debe jugar con sleep pero no se puede generalizar eso para todos los MQL.

¿cuándo necesitamos dormir en Tester? si, por ejemplo, pruebo un script que interactúa con un EA bajo prueba podría tener la necesidad de sincronizar el estado. estoy hablando de mutexes. para adquirir un mutex de una manera limpia ambas partes necesitan la capacidad de esperar, es decir, usar sleep.

lo mismo ocurre con los indicadores. no importa que el indicador se ejecute en el hilo de la interfaz de usuario. si dos hilos necesitan sincronizarse ambos necesitan la capacidad de "dormir". y sleep() es la única solución limpia si tienes que esperar una cantidad determinada de ciclos de CPU, las construcciones "for" sólo demuestran una falta de conocimiento.

ok, pongamos un ejemplo práctico: mis EA's pueden mostrar el estado de las órdenes (flechas dibujadas por ellos mismos, etc). lo hacen respondiendo a comandos externos "enviados" a través de descripciones de texto de los objetos del gráfico (1-órdenes pendientes, 2-posiciones abiertas, 3-operaciones cerradas, 4-todo junto), por eso lo llamo comandos del gráfico. o pueden iniciar/parar/reanudar secuencias de operaciones respondiendo a otros comandos ("iniciar", "parar", "reanudar"). para leer los comandos necesitan sincronizar el acceso a esos objetos gráficos (crear objeto gráfico + establecer propiedad de texto no es una operación atómica). y por supuesto me gustaría probar este comportamiento en Tester, así que necesito sleep() para esperar.

lo mismo para los indicadores que se ejecutan en Tester o en línea. si hacen algo similar "tengo" que detener el hilo de la interfaz de usuario para obtener un estado limpio, 10 miilisegundos no importan. por cierto: una implementación de mutex limpio comprueba el tiempo que ya está esperando, sale del bucle y señala un error si no puede obtener un bloqueo de sincronización después de digamos unos pocos segundos.

int seconds;

// run until the lock is aquired
while (true) {
   ...
   // warn every second and cancel after 10 seconds
   duration = GetTickCount() - startTime;
   if (duration >= seconds*1000) {
      if (seconds >= 10)
         return(_false(catch("AquireLock(5)   failed to get lock for mutex \""+ mutexName +"\" after "+ DoubleToStr(duration/1000.0, 3) +" sec., giving up", ERR_RUNTIME_ERROR)));
      warn(StringConcatenate("AquireLock(6)   couldn't get lock for mutex \"", mutexName, "\" after ", DoubleToStr(duration/1000.0, 3), " sec., retrying..."));
      seconds++;
   }
   //debug("AquireLock()   couldn't get lock for mutex \""+ mutexName +"\", retrying...");

   if (IsTesting() || IsIndicator()) SleepEx(100, true);          // expert or indicator under test
   else                              Sleep(100);
}

Yo utilizo esos comandos escribiendo un script y asignándole una tecla de acceso rápido. entonces, si quiero controlar un experto/indicador sólo tengo que pulsar una tecla, por ej. ALT-O para cambiar el modo de visualización de la orden entre todos los valores posibles. o tengo un script "start" y otro "stop" en los favoritos y arranco/detengo/reanudo un ea con un clic del ratón.

en tester por ejemplo un ea con VisualMode=On en plena velocidad se estrellará casi inmediatamente si no está bien sincronizado.