Problemas con Time()

 
¡Hola Comunidad MQL4!

Este es mi primer post. En primer lugar, por favor, no soy un desarrollador de MQL. Soy un comerciante, que utiliza una herramienta para ayudarme a construir EAs. Esa herramienta permite el uso de alguna estructura MQL, pero no se ejecuta en funciones MQL explícitas. Simplemente toma el código MQL, evalúa si la condición basada en MQL es verdadera/falsa, y luego ejecuta una función personalizada como OpenBuy, OpenSell, CloseBuy, CloseSell, DeletePendingBuy, DeletePendingSell, etc. Pero, no ejecuta el código MQL explícitamente. Por ejemplo, puede utilizar la función Imprimir o Comentar para que aparezca algo en la ventana del gráfico de MT4 (sólo un ejemplo).

Por lo tanto, sé un poco acerca de MQL, que es lo suficiente para permitirme utilizar la herramienta de desarrollo de EA que utilizo para construir mis EAs. Hasta ahora, he construido 10 EAs utilizando la herramienta y he abandonado 7 de ellos debido a la falta de rentabilidad, que es alrededor del 30% mejor que mi ratio de prototipos exitosos que solía obtener con la construcción de sistemas de trading en Excel. Normalmente espero que 7-8 ideas de 10 no sean tan rentables como se esperaba, dejando 2-3 diseños lo suficientemente rentables como para comenzar el proceso de optimización. Bien, ya es suficiente sobre mí y mi forma de trabajar.

¡Aquí está mi problema y espero que he venido al lugar correcto para la ayuda!

Estoy ejecutando este código [b]para cerrar operaciones:[/b]

Day() == 1 || Day() == 2 || Day() == 3 || Day() == 4 && TimeHour(TimeCurrent()) >=23 && TimeMinute(TimeCurrent()) >=57 || Day() == 5 && TimeHour(TimeCurrent()) >=21 && TimeMinute(TimeCurrent()) >=57

Nota: El problema es que todas las operaciones permanecen abiertas de lunes a jueves, hasta las 23:57. Además, todas las operaciones permanecen abiertas el viernes, hasta las 21:57.


También estoy ejecutando este código a través de un bloque MQL [b]para abrir operaciones:[/b]

TimeHour(TimeCurrent()) == 00 && TimeMinute(TimeCurrent()) <= 05

Nota: La única operación que se abre entre las 00:00 y las 00:05, es la primera operación de la prueba retrospectiva, al hacer clic en el botón de inicio de la prueba. Esa operación se abre precisamente a las 00:00. Sin embargo, ninguna de las otras operaciones se abre entre las 00:00 y las 00:05, más adelante en la semana.

En resumen:

- Una operación se abre después de hacer clic en el botón Tester Start a las 00:00.
- Ninguna operación se cierra posteriormente a las 23:57 (de lunes a jueves) o a las 21:57 (viernes).
- Nunca se abre una operación entre las 00:00 y las 00:05.

Todas las horas mostradas arriba tienen un amplio flujo de ticks disponibles. Por lo tanto, no hay lagunas en los datos utilizados por Tester.

Se agradece cualquier ayuda. ¿Por qué estas operaciones no se cierran a la hora codificada? ¿Por qué no se ejecuta ninguna operación cuando siempre hay una señal de operación disponible entre las 00:00 y las 00:05, de lunes a viernes?

Gracias.
cfx
 

¿Qué sentencias de depuración Print ha añadido a su código para averiguar qué se ejecuta y qué no? por ejemplo, ¿falla la función OrderClose() o es el código que lleva a la función OrderClose()? ¿se fija en los valores de retorno e imprime cualquier error relevante?

¿Qué son los valores de retorno de las funciones? ¿Cómo los utilizo?

¿Funciona correctamente Day() en el Probador de Estrategias? ¿ha probado que funciona? puede utilizar TimeDayOfWeek() en su lugar...

 

>Estoy ejecutando este código [b]para cerrar operaciones:[/b]

Day() == 1 || Day() == 2 || Day() == 3 || Day() == 4 && TimeHour(TimeCurrent()) >=23 && TimeMinute(TimeCurrent()) >=57 || Day() == 5 && TimeHour(TimeCurrent()) >=21 && TimeMinute(TimeCurrent()) >=57

>Nota: El problema es que todas las operaciones permanecen abiertas de lunes a jueves, hasta las 23:57. Además, todas las operaciones permanecen abiertas el viernes, hasta las 21:57.

Este es un error muy común con los principiantes; tratar de encajar toda la expresión lógica en una línea. Es imposible de depurar.

El truco es dividir la prueba en pequeños trozos y comprobar cada uno de ellos (con sentencias Print o de otro tipo).

¿Puedes conseguir que se cierre después de las 23:57 de cualquier día? No hay que preocuparse por los días de la semana con esa prueba. Una vez que consigas que una prueba funcione correctamente, puedes aventurarte más. Pero utilice varias líneas siempre que sea posible para permitir las sentencias Print entre ellas para la depuración. Cuando funcione, elimine las sentencias Print pero deje el código en líneas separadas. El código es más eficiente cuando se escribe en varias líneas (se ejecuta más rápido).

 
  1.  Day() == 1 || Day() == 2 || Day() == 3 || Day() == 4 && TimeHour(TimeCurrent()) >=23 && TimeMinute(TimeCurrent()) >=57 || Day() == 5 && TimeHour(TimeCurrent()) >=21 && TimeMinute(TimeCurrent()) >=57
    ¿a cuál de ellas se refería?
    Day() == 1 || Day() == 2 || Day() == 3 || ( Day() == 4 && TimeHour(TimeCurrent()) >=23) && TimeMinute(TimeCurrent()) >=57 || Day() == 5 && TimeHour(TimeCurrent()) >=21 && TimeMinute(TimeCurrent()) >=57
    ( Day() == 1 || Day() == 2 || Day() == 3 || Day() == 4) && TimeHour(TimeCurrent()) >=23 && TimeMinute(TimeCurrent()) >=57 || Day() == 5 && TimeHour(TimeCurrent()) >=21 && TimeMinute(TimeCurrent()) >=57
    Siempre paréntesis completamente o simplificar y autodocumentarse
    #define HR2157 79020 // 21 * 3600 + 57 * 60
    #define HR2357 86220
    datetime now = TimeCurrent();
    int      tod = now % 86400;
    bool     isFriday = TimeDayOfWeek(now) == 5;
    if (isFriday) int todClose = HR215700;
    else              todClose = HR235700
    if (now >= todClose) ...
    

  2. https://www.mql5.com/en/forum/127483 informó que DayOfWeek() siempre devuelve 5 en el probador, por lo que sólo uso las versiones de Timexxx().
 
WHRoeder:
  1. ¿a cuál de ellas se refería?
El OP obviamente quiere decir O todos los días de la semana excepto el viernes. Claramente está tratando de forzar un cierre antes del final del día de negociación, pero siendo el viernes más corto. No se ha dado cuenta de que la prueba de utilizar el OR de los cuatro días es redundante, ya que siempre podemos cerrar si la hora es posterior a las 23:57. No es necesario excluir el viernes.
 
RaptorUK:

¿Qué sentencias de depuración Print ha añadido a su código para averiguar qué se ejecuta y qué no? por ejemplo, ¿falla la función OrderClose() o es el código que lleva a la función OrderClose()? ¿se fija en los valores de retorno e imprime cualquier error relevante?

¿Qué son los valores de retorno de las funciones? ¿Cómo los utilizo?

¿Funciona correctamente Day() en el Probador de Estrategias? ¿ha probado que funciona? puede utilizar TimeDayOfWeek() en su lugar...


No he utilizado ninguna sentencia Print para tal fin. He cometido una errata en mi post original. La herramienta que estoy usando [b]no puede[/b] (originalmente escribí "puede") usar funciones MQL como Print, o Comment. Por lo tanto, me disculpo por el error tipográfico, que afectó a su respuesta.

Sin embargo, puedo mirar fácilmente el Diario de Pruebas y ver que el EA no está preparando ninguna operación cuando debería (a las 00:00), y no está instanciando el Cierre de ninguna operación cuando debería (de lunes a jueves a las 23:59, o el viernes a las 21:57). Esencialmente, puedo ver la carga del EA en el tiempo de ejecución del Probador, la información obligatoria sobre la Cuenta Demo, y finalmente, puedo ver que todos los Marcos de Tiempo para el(los) indicador(es) utilizado(s) por el EA están siendo cargados correctamente y sin error. Normalmente no obtengo errores de ningún tipo con mis EAs, en absoluto. Y, rutinariamente pruebo los EAs de Multi-Time Frame todo el tiempo.

Sólo parece que estoy teniendo un problema con la función Time().

Dado que la única posición que se abre es la primera operación que el EA ve después de hacer clic en el botón de inicio del probador, no puedo decir si Day() está funcionando o no a partir de la salida que viene de la impresión o del comentario. Sin embargo, como prueba aleatoria, eliminé la línea [b]TimeMinute(TimeCurrent()) <= 05[/b] del segmento de código que controla la Apertura de Posiciones a las 00:00, de lunes a viernes. Cuando hice eso, el siguiente código empezó a funcionar como estaba diseñado:

Day() == 1 || Day() == 2 || Day() == 3 || Day() == 4 && TimeHour(TimeCurrent()) >=23 && TimeMinute(TimeCurrent()) >=57 | Day() == 5 && TimeHour(TimeCurrent()) >=21 && TimeMinute(TimeCurrent()) >=57

Esto me dice que, efectivamente, Day() funciona por deducción. De hecho, todo ese segmento de código que cierra posiciones, sí funciona. Pero, por alguna razón, no cuando [b]TimeMinute(TimeCurrent()) <= 05[/b] se utiliza en el segmento de código que controla la Apertura de posiciones. Esta ironía no tiene sentido para mí, no puedo entender por qué esto sería el caso.

¡Gracias!

cfx

 
dabbler:

>Estoy ejecutando este código [b]para cerrar las operaciones:[/b]

>Nota: El problema es que todas las operaciones permanecen abiertas de lunes a jueves, hasta las 23:57. También, todas las operaciones permanecen abiertas el viernes, hasta las 21:57.

Este es un error muy común con los principiantes; tratar de encajar toda la expresión lógica en una línea. Es imposible de depurar.

El truco es dividir la prueba en pequeños trozos y comprobar cada uno de ellos (con sentencias Print o de otro modo).

¿Puede conseguir que se cierre después de las 23:57 de cualquier día? No hay necesidad de preocuparse por los días de la semana con esa prueba. Una vez que consigas que una prueba funcione correctamente, puedes aventurarte más. Pero utilice varias líneas siempre que sea posible para permitir las sentencias Print entre ellas para la depuración. Cuando funcione, elimine las sentencias Print pero deje el código en líneas separadas. El código es realmente más eficiente cuando se escribe en muchas líneas (se ejecuta más rápido).


Por cierto, ¡gracias a todos por las respuestas!


El control de cierre funciona. Cuando quité el [b]TimeMinute(TimeCurrent()) <= 05[/b] del Control de Apertura, efectivamente funciona. La primera posición que se ejecutó DESPUÉS de hacer clic en el botón de Inicio del Probador, efectivamente se cierra a las 23:57 (de lunes a jueves). El problema es que nunca se abren nuevas posiciones a las 00:00, tal y como requiere el control de apertura por diseño ([b]TimeHour(TimeCurrent()) == 00 && TimeMinute(TimeCurrent()) <= 05[/b]. Incluso cuando quito la función [b]TimeMinute(TimeCurrent()<=5[/b] como mera comprobación de cordura.

Pensé que hacer el código lo más compacto posible, sería la mejor alternativa, pero intentaré ampliar cada función, segmento, componente, etc., para ver si eso ayuda.


Gracias.

cfx

 
WHRoeder:
  1. ¿a cuál de ellas se refería?
    Siempre paréntesis completamente o simplificar y autodocumentar
  2. https://www.mql5.com/en/forum/127483 informó que DayOfWeek() siempre devuelve 5 en el probador, por lo que sólo uso las versiones de Timexxx().

Quería decir:

( Day() == 1 || Day() == 2 || Day() == 3 || Day() == 4) && TimeHour(TimeCurrent()) >=23 && TimeMinute(TimeCurrent()) >=57 || Day() == 5 && TimeHour(TimeCurrent()) >=21 && TimeMinute(TimeCurrent()) >=57


Parece que falta un paréntesis en este segmento de código. Si puedes corregirlo por mí, te lo agradecería. La herramienta que utilizo me avisa cuando falta un paréntesis, pero no me dice dónde.


Gracias.

 
dabbler:
El OP obviamente quiere decir O todos los días de la semana excepto el viernes. Claramente está tratando de forzar un cierre antes del final del día de negociación, pero con el viernes siendo más corto. No se ha dado cuenta de que la prueba de utilizar el OR de los cuatro días es redundante, ya que siempre podemos cerrar si la hora es posterior a las 23:57. No es necesario excluir el viernes.

Tengo que aislar el viernes, de lo contrario no habrá distinción entre los horarios de cierre del lunes al jueves y el del viernes. Ambas horas de cierre se distinguen por el día de la semana en que se producen y no sólo por la hora del día en que se producen.

Así, necesito cerrar de lunes a jueves a las 23:57, y el viernes a las 21:57, respectivamente. Si incluyo el cierre del viernes con el de lunes a jueves, entonces todas las operaciones se cerrarán a la hora más temprana vista por el EA, que será las 21:57, dos horas completas antes de las horas de cierre requeridas de lunes a jueves.

Por favor, aclare su afirmación. Gracias.

cfx

 

¡LOL!


Estoy empezando a pensar que la mayoría de las funciones basadas en el "Tiempo" en MT4 son seriamente defectuosas.


Quiero decir, si reajusto toda mi lógica de control de posición a algo tan mundano como TimeHour(TimeCurrent()) == 23 && TimeHour(TimeCurrent()) == 59, y no ser capaz de conseguir un comercio solitario cerrado en absoluto (el EA simplemente ignora el código!), entonces yo diría que MT4 tiene algunos problemas que deben ser corregidos con respecto a este tipo de funciones.


También realicé una serie de pruebas utilizando lo siguiente: DayOfWeek() != 0 && DayOfWeek() !=, ¡y ni una sola operación se abrió de lunes a viernes! De hecho, no se abrió ni una sola operación. Pero, ¿qué crees que le pasó al EA cuando eliminé por completo todas las funciones basadas en el tiempo? Por supuesto, se ejecuta como diseñado sin error. No soy un desarrollador de MQL, pero soy muy bueno en el desarrollo de construcciones lógicas y puedo detectar un problema sistémico cuando lo percibo. Percibo que MetaQuotes tiene un problema con sus funciones Time(), y punto. No puedo ser tan despistado en algo tan fácil de codificar y he visto a otras personas que codifican en MQL, tener dificultades con las funciones basadas en el tiempo en MT4.

No sé exactamente cuál es el problema, pero cuando quito TimeMinute(TimeCurrent()) <= 05, de la lógica de Control de Apertura (esa pieza de código que controla la apertura de todas las operaciones), y consigo que SOLO la primera operación se cierre a la hora correcta, y sin embargo TODAS las demás operaciones impulsadas por la misma lógica de Control de Apertura son sumariamente ignoradas por el EA posteriormente, entonces sé que algo está sistémicamente mal con la función misma.

¡El código no puede ser más simple! Estoy instruyendo al EA para que abra la maldita operación entre las 00:00 y las 00:05. Eso no es algo difícil de codificar. Un niño de seis años podría codificar eso. Aquí está de nuevo: [b]TimeHour(TimeCurrent()) == 00 && TimeHour(TimeCurrent()) <= 05[/b].


Ya está. Lo acabo de codificar. ¡Entonces suelto ese código en la herramienta que estoy usando y la herramienta me dice que la sintaxis del código es correcta! Bien, ¿y ahora qué? Bueno, compilo el maldito archivo .ex4 por MILLÓN de veces y ejecuto el M4 Tester. Bien, ¿y ahora qué? Bueno, la primera operación se lanza a las 00:00. Impresionante, ¿verdad? ¡NOOOOO! ¿Por qué? Porque a las 23:59 de un lunes, la maldita posición sigue abierta. ¿Y luego qué? Bueno, a las 00:00 de la siguiente sesión de negociación (la siguiente barra D1), el bueno de [b]TimeHour(TimeCurrent()) == 00 && TimeHour(TimeCurrent()) <= 05[/b] se abrirá paso donde el Control de Cierre falló, ¿verdad? No es así. ¿Por qué? Porque, desde las 00:00 hasta las 00:05, ¡¡¡no se abre ninguna maldita operación por parte del EA!!!

¡Pasé dos (2) días en este código simple y nadie ha sido capaz de decirme por qué no funciona - ni siquiera los expertos MQL! Esto me dice que MetaQuotes tiene un problema.

Ok, ya he terminado de desahogarme. Han sido dos días de frustración acumulada y tenía que desahogarme.

Yo NUNCA tengo problemas con mis EAs y he sido capaz de armar algunos diseños bastante sofisticados usando todos los marcos de tiempo excepto W1 y MN. Todos mis EAs utilizan diseños iCustom que construí e investigué desde cero.

De repente, después de funcionar como un motor V8 bien engrasado y afinado, empiezo a usar funciones Time() y se desata el infierno... Hay algo que no cuadra. Estoy usando estas funciones basadas en el tiempo de la manera más simple posible, ¿y todavía no funcionan? 48 horas en algo como esto fue una enorme cantidad de tiempo para mí para perder. Frustrado y cabreado, intentaré vivir sin "Tiempo", a si que es posible.

Voy a tener que aprender a desarrollar la lógica comercial en torno a las funciones Time().

Irreales.

 

CFx 2012.05.31 03:41

¡¡¡LOL!!!


Estoy empezando a pensar que la mayoría de las funciones basadas en el "Tiempo" en MT4 son seriamente defectuosas.


Quiero decir, si reajusto toda mi lógica de control de posición a algo tan mundano como: TimeHour(TimeCurrent()) == 23 && TimeHour(TimeCurrent()) == 59, y no ser capaz de conseguir un comercio solitario cerrado en absoluto (el EA simplemente ignora el código!), entonces yo diría que MT4 tiene algunos problemas que deben ser corregidos con respecto a este tipo de funciones.


También realicé una serie de pruebas utilizando lo siguiente: DayOfWeek() != 0 && DayOfWeek() !=, ¡y ni una sola operación se abrió de lunes a viernes! De hecho, no se abrió ni una sola operación. Pero, ¿qué crees que le pasó al EA cuando eliminé por completo todas las funciones basadas en el tiempo? Por supuesto, se ejecuta como diseñado sin error. No soy un desarrollador de MQL, pero soy muy bueno en el desarrollo de construcciones lógicas y puedo detectar un problema sistémico cuando lo percibo. Percibo que MetaQuotes tiene un problema con sus funciones Time(), y punto. No puedo ser tan despistado en algo tan fácil de codificar y he visto a otras personas que codifican en MQL, tener dificultades con las funciones basadas en el tiempo en MT4.

No sé exactamente cuál es el problema, pero cuando elimino TimeMinute(TimeCurrent()) <= 05, de la lógica de Control de Apertura (esa pieza de código que controla la apertura de todas las operaciones), y consigo que SOLO la primera operación se cierre a la hora correcta, y sin embargo TODAS las demás operaciones impulsadas por la misma lógica de Control de Apertura son sumariamente ignoradas por el EA posteriormente, entonces sé que algo está sistémicamente mal con la función en sí.

¡El código no puede ser más simple! Estoy instruyendo al EA para que abra la maldita operación entre las 00:00 y las 00:05. Eso no es algo difícil de codificar. Un niño de seis años podría codificar eso. Aquí está de nuevo: [b]TimeHour(TimeCurrent()) == 00 && TimeHour(TimeCurrent()) <= 05[/b].


Ya está. Lo acabo de codificar. ¡Entonces suelto ese código en la herramienta que estoy usando y la herramienta me dice que la sintaxis del código es correcta! Bien, ¿y ahora qué? Bueno, compilo el maldito archivo .ex4 por MILLÓN de veces y ejecuto el M4 Tester. Bien, ¿y ahora qué? Bueno, la primera operación se lanza a las 00:00. Impresionante, ¿verdad? ¡NOOOOO! ¿Por qué? Porque a las 23:59 de un lunes, la maldita posición sigue abierta. ¿Y luego qué? Bueno, a las 00:00 de la siguiente sesión de negociación (la siguiente barra D1), el bueno de [b]TimeHour(TimeCurrent()) == 00 && TimeHour(TimeCurrent()) <= 05[/b] se abrirá paso donde el Control de Cierre falló, ¿verdad? No es así. ¿Por qué? Porque, desde las 00:00 hasta las 00:05, ¡¡¡no se abre ninguna maldita operación por parte del EA!!!

¡Pasé dos (2) días en este código simple y nadie ha sido capaz de decirme por qué no funciona - ni siquiera los expertos MQL! Esto me dice que MetaQuotes tiene un problema.

Ok, ya he terminado de desahogarme. Han sido dos días de frustración acumulada y tenía que desahogarme.

Yo NUNCA tengo problemas con mis EAs y he sido capaz de armar algunos diseños bastante sofisticados usando todos los marcos de tiempo excepto W1 y MN. Todos mis EAs utilizan diseños iCustom que construí e investigué desde cero.

De repente, después de funcionar como un motor V8 bien engrasado y afinado, empiezo a usar funciones Time() y se desata el infierno... Hay algo que no cuadra. Estoy usando estas funciones basadas en el tiempo de la manera más simple posible, ¿y todavía no funcionan? 48 horas en algo como esto fue una enorme cantidad de tiempo para mí para perder. Frustrado y cabreado, intentaré vivir sin "Tiempo", a si que es posible.

Voy a tener que aprender a desarrollar la lógica comercial en torno a las funciones Time().

Irreal.

LOL. Usted es el que irreal. Este código tuyo ...

if (TimeHour(TimeCurrent()) == 00 && TimeHour(TimeCurrent()) <= 05)

... nunca devolverá verdadero.

Usted es el que necesita para desarrollar aún más "su" construcción lógica.

Y construir esto ...

if (TimeHour(TimeCurrent()) >= 00 && TimeHour(TimeCurrent()) <= 05)