Rara vez, pero hay situaciones en las que las cotizaciones de un instrumento se congelan durante mucho tiempo (vi una situación de este tipo en el yen). Y si el Asesor Experto se cuelga en este par, estás en problemas si no has traducido todo el código en OnTime().
Si usted trabaja en OOP o utilizar ciertos algoritmos, usted no tendrá que traducir el código. Pero estoy de acuerdo en que es más conveniente obtener ticks en tiempo real para todos los pares en la visión general (y no inventar algo propio)....
Lizar:
Un evento así se puede recibir usando TimeCuurent(), pero qué hacer con él después, cómo sincronizarlo es una incógnita.
Interesting: ¿Qué tiene que ver TimeCuurent() con esto?
La ayuda dice:
En el manejador OnTick( ), esta función devolverá el tiempo del tick entrante procesado. En otros casos (por ejemplo, llamada en los manejadores OnInit(), OnDeinit(), OnTimer(), etc.) esta es la hora de llegada de la última cotizaciónpara cualquier símbolo disponible en la ventana "Observación del Mercado", la misma hora que se muestra en el título de esta ventana.
En el manejador OnTick( ), esta función devolverá la hora de llegada del tick que se está procesando. En otros casos (por ejemplo, llamada en los manejadores OnInit(), OnDeinit(), OnTimer() y demás) será la hora de llegada de la última cotizaciónpara cualquier símbolo disponible en la ventana "Observación del Mercado", la misma hora que se muestra en la cabecera de esta ventana.
Sí, está claro. sólo que si lo ponemos en OnTime podemos actualizar la hora no más de una vez por minuto, y si lo ponemos en el OnTick() actual corremos el riesgo de perder ticks en algunos de los pares (en mults).
Y lo que hay que hacer en el bloque de procesamiento está claro (para mults) - Obtenemos un nuevo valor, lo comparamos con el existente y sacamos conclusiones sobre si hubo un nuevo tick o no.
Elevento NewTick se genera sólo para los Asesores Expertos cuando se recibe un nuevo tick en el símbolo, a cuyo gráfico está unido el Asesor Experto.
Una vez más. Estamos hablando de un Asesor Experto que se cuelga de algún símbolo. Se activa mediante el evento
void OnTick() {}
Si usted está dentro de esta función, y no hay ticks en este par durante más de una hora, no se puede hacer nada dentro de una hora. Hasta ahora, la única salida es hacerlo en un temporizador, se inicia independientemente de la llegada de ticks en el instrumento.
Pero si lo ponemos en OnTime podemos actualizar la hora no más de una vez por minuto, y si lo ponemos en el actual OnTick() corremos el riesgo de perder ticks en algunos de los pares (en mults).
Ese es el punto, podemos obtener el evento, pero no podemos usarlo.
Una vez más. Estamos hablando de un Asesor Experto que se cuelga de algún símbolo. Se lanza mediante el evento
void OnTick() {}
Si estás dentro de esta función, y no hay ticks en este par durante más de una hora, no puedes hacer nada en una hora. Hasta ahora, la única salida es hacerlo en el temporizador, se inicia independientemente de la llegada de ticks en el instrumento.
Sí, si actuamos en el marco de este https://www.mql5.com/es/docs/basis/function/events, estoy de acuerdo en que la mejor opción, como vemos ahora, es OnTime. Pero sólo nos salvará de la dependencia de la llegada de ticks. Y no nos salvará del single-threadedness: mientras estamos procesando una señal para un instrumento, corremos el riesgo de perder o retrasar el procesamiento de otros instrumentos. Esto es especialmente cierto cuando "el tiempo de procesamiento de las órdenes comerciales es de 2 a 7 segundos" + recotizaciones.
Me acordé de TimeCuurent() porque Interesante empezó a hablar de ticks en tiempo real para todos los pares en la revisión del mercado.
If you call this prototype function from one place, then we have what we need. But if we want to use this function, for example, again in another place in the same calculation loop, it will always return false, which means that there is no bar. And this will not always be true. Static variable in this case imposes an artificial limit on the number of prototype function calls.
Tienes razón. Pero llamar varias veces a una función como isnewbar() durante 1 tick es una mala práctica. Llámala una sola vez y guarda el resultado en una variable.
Un problema es que la solución que aportas, usando una clase sin variable estática, no resuelve lo que has recalcado. E incluso la situación es ahora peor. Tienes que declarar la instancia de tu clase como una variable global (objeto), también tienes que inicializarla en el OnInit(). Quien vaya ausar tu clasedebe conocerel funcionamiento:
Utilizar siempreunavariableglobal
Inicializar siempre, incluso si elsímbolo y el períodoson los predeterminados (para el gráfico de tiempo).
Por último, "si queremos utilizar esta función, por ejemplo, de nuevo en otro lugar en el mismo bucle de cálculo". Aún así SIEMPRE DEVUELVE FALSE.
Has sustituido una variable local estática por una variable global, que es lo mismo y no has resuelto tu problema.
No obstante, tuartículo tiene el méritode empujara pensar yofrecerideas interesantes.
Buen artículo, ¡gracias por compartirlo! ¡Todo eso fue muy útil!
De todas formas, he cogido tu función isNewBar y me lanza el siguiente mensaje al compilar:"posible pérdida de datos debido a la conversión de tipos".
Así que he cambiado los tipos var de datetime a long de esta forma:
//+------------------------------------------------------------------+//| Devuelve true si ha aparecido una nueva barra para un par símbolo/periodo ||//+------------------------------------------------------------------+bool isNewBar()
{
//--- memoriza la hora de apertura del último compás en la variable estáticastaticlong last_time=0;
//--- hora actuallong lastbar_time=SeriesInfoInteger(CurrencyPair,Period01,SERIES_LASTBAR_DATE);
//--- si es la primera llamada de la funciónif(last_time==0)
{
//--- fijar la hora y salir
last_time=lastbar_time;
return(false);
}
//--- si la hora difiereif(last_time!=lastbar_time)
{
//--- memoriza la hora y devuelve true
last_time=lastbar_time;
return(true);
}
//--- si pasamos a esta línea, entonces la barra no es nueva; return falsereturn(false);
}
Ahora compila sin ningún aviso y parece que funciona bien. Gracias.
Prival:
Rara vez, pero hay situaciones en las que las cotizaciones de un instrumento se congelan durante mucho tiempo (vi una situación de este tipo en el yen). Y si el Asesor Experto se cuelga en este par, estás en problemas si no has traducido todo el código en OnTime().
Lizar:
Un evento así se puede recibir usando TimeCuurent(), pero qué hacer con él después, cómo sincronizarlo es una incógnita.
¿Qué tiene que ver TimeCuurent() con esto?
La ayuda dice:
En el manejador OnTick( ), esta función devolverá el tiempo del tick entrante procesado. En otros casos (por ejemplo, llamada en los manejadores OnInit(), OnDeinit(), OnTimer(), etc.) esta es la hora de llegada de la última cotización para cualquier símbolo disponible en la ventana "Observación del Mercado", la misma hora que se muestra en el título de esta ventana.
La Sinopsis dice:
En el manejador OnTick( ), esta función devolverá la hora de llegada del tick que se está procesando. En otros casos (por ejemplo, llamada en los manejadores OnInit(), OnDeinit(), OnTimer() y demás) será la hora de llegada de la última cotización para cualquier símbolo disponible en la ventana "Observación del Mercado", la misma hora que se muestra en la cabecera de esta ventana.
Sí, está claro. sólo que si lo ponemos en OnTime podemos actualizar la hora no más de una vez por minuto, y si lo ponemos en el OnTick() actual corremos el riesgo de perder ticks en algunos de los pares (en mults).
Y lo que hay que hacer en el bloque de procesamiento está claro (para mults) - Obtenemos un nuevo valor, lo comparamos con el existente y sacamos conclusiones sobre si hubo un nuevo tick o no.
Pero dime, ¿por qué hacerlo en el Asesor Experto?
La Sinopsis dice:
error. esto es lo que dice la ayuda https://www.mql5.com/es/docs/basis/function/events
Elevento NewTick se genera sólo para los Asesores Expertos cuando se recibe un nuevo tick en el símbolo, a cuyo gráfico está unido el Asesor Experto.
Una vez más. Estamos hablando de un Asesor Experto que se cuelga de algún símbolo. Se activa mediante el evento
void OnTick() {}
Si usted está dentro de esta función, y no hay ticks en este par durante más de una hora, no se puede hacer nada dentro de una hora. Hasta ahora, la única salida es hacerlo en un temporizador, se inicia independientemente de la llegada de ticks en el instrumento.
Pero si lo ponemos en OnTime podemos actualizar la hora no más de una vez por minuto, y si lo ponemos en el actual OnTick() corremos el riesgo de perder ticks en algunos de los pares (en mults).
error. Esto es lo que dice la ayuda https://www.mql5.com/es/docs/basis/function/events.
Una vez más. Estamos hablando de un Asesor Experto que se cuelga de algún símbolo. Se lanza mediante el evento
void OnTick() {}
Si estás dentro de esta función, y no hay ticks en este par durante más de una hora, no puedes hacer nada en una hora. Hasta ahora, la única salida es hacerlo en el temporizador, se inicia independientemente de la llegada de ticks en el instrumento.
Sí, si actuamos en el marco de este https://www.mql5.com/es/docs/basis/function/events, estoy de acuerdo en que la mejor opción, como vemos ahora, es OnTime. Pero sólo nos salvará de la dependencia de la llegada de ticks. Y no nos salvará del single-threadedness: mientras estamos procesando una señal para un instrumento, corremos el riesgo de perder o retrasar el procesamiento de otros instrumentos. Esto es especialmente cierto cuando "el tiempo de procesamiento de las órdenes comerciales es de 2 a 7 segundos" + recotizaciones.
Me acordé de TimeCuurent() porque Interesante empezó a hablar de ticks en tiempo real para todos los pares en la revisión del mercado.
Un artículo muy interesante. Gracias por compartir todo esto.
Sin embargo, algunas observaciones:
Hablando de esta función, usted dice :
If you call this prototype function from one place, then we have what we need. But if we want to use this function, for example, again in another place in the same calculation loop, it will always return false, which means that there is no bar. And this will not always be true. Static variable in this case imposes an artificial limit on the number of prototype function calls.
Has sustituido una variable local estática por una variable global, que es lo mismo y no has resuelto tu problema.
No obstante, tu artículo tiene el mérito de empujar a pensar y ofrecer ideas interesantes.
Buen artículo, ¡gracias por compartirlo! ¡Todo eso fue muy útil!
De todas formas, he cogido tu función isNewBar y me lanza el siguiente mensaje al compilar:"posible pérdida de datos debido a la conversión de tipos".
Así que he cambiado los tipos var de datetime a long de esta forma:
Ahora compila sin ningún aviso y parece que funciona bien. Gracias.