En un indicador estándar, usted construiría las matrices del buffer con los datos de los parámetros enviados a través de la función de evento OnCalulate( ... ). Pero, para la multidivisa y/o el marco de tiempo múltiple, usted tendrá que utilizar una de dos soluciones:
- Utilizar el método antiguo de las variaciones de "iFunction", como iTime(), iVolume, iOpen, iClose, etc. pero con un símbolo diferente como "EURUSD", "JPYUSD", etc. en lugar del _Symbol o Symbol() por defecto.
- Utilizando el método más nuevo de la primera variante de la función ArrayCopyRates() junto con los punteros de los arrays de MqlRates. Los arrays "copiados", en realidad no ocuparán ningún espacio y sólo serán punteros a los datos existentes de los distintos símbolos y time-frames.
Sin embargo, para que esto funcione, una de las dos condiciones tiene que existir para que el multisímbolo y/o el multitramo de tiempo funcionen:
- O bien los gráficos respectivos para los símbolos y los marcos temporales ya están abiertos, para que no se genere ningún error,
- o obtendrás un error 4066 (ERR_HISTORY_WILL_UPDATED) la primera vez que solicites los datos, y tendrás que codificar un bucle sleep & retry, para esperar a que se descarguen los datos y volver a solicitarlos.
Mi solución personal sugerida, que encuentro como la manera más eficiente y fácil de manejar el error 4066, es el método ArrayCopyRates() y MqlRates .
Hay más información sobre esto en la documentación y archivos de ayuda de MQL4.
P.D. ¡NB! Cuando acceda a las funciones incorporadas de los indicadores, como iMA(), iATR(), etc. para los distintos símbolos y marcos temporales, recuerde implementar también los bucles de reposo y reintento para no obtener tampoco el error 4066. Aquí hay una cita de la documentación de MQL4:
Recuerde, el OP está preguntando acerca de un indicador. Sleep() se ignora en los indicadores
Lo siento, no lo sabía. Yo uso este método bastante en EA's pero no en Indicadores, así que no sabía de la desventaja del sueño.
En ese caso, tendrá que construir un bucle de reintento en torno a las llamadas sucesivas en cada llamada a la función OnCalculate() (donde el uso de ArrayCopyRates() es la mejor solución).
Alternativamente, si funciona en la función OnInit (), podría ser el método preferido para preparar los datos para el indicador, con un conteo de reintentos muy largo (sin el sleep) para este caso.
...
- o obtendrá un error 4066 (ERR_HISTORY_WILL_UPDATED) la primera vez que solicite los datos, y tendrá que codificar un bucle sleep & retry, para esperar a que se descarguen los datos y volver a solicitarlos.
P.D. ¡NB! Cuando acceda a las funciones incorporadas de los indicadores, como iMA(), iATR(), etc. para los distintos símbolos y marcos temporales, recuerde implementar también los bucles de reposo y reintento para no obtener tampoco el error 4066. Aquí hay una cita de la documentación de MQL4:
A menos que hayan cambiado algo recientemente, obtendrá el error 4066 cada vez desde la primera llamada a la función (y sólo desde esta primera llamada), independientemente de las condiciones o del progreso de la actualización del historial. No tiene ninguna utilidad práctica.
FMIC: En ese caso, tendrá que construir un bucle de reintento en torno a las sucesivas llamadas en cada tick a la función OnCalculate() (donde el uso de ArrayCopyRates() es la mejor solución). Alternativamente, si funciona en la función OnInit(), podría ser el método preferido para preparar los datos para el indicador, con un conteo de reintentos muy largo (sin el sleep) para este caso. |
|
if(pair1[0].time == 0) return;
Esto nunca será cierto.
Si hay algún historial cargado para el símbolo y el marco temporal, la función recuperará el valor más reciente.
Si no hay ningún historial cargado, obtendrá un error de Array out of range.
Lo mismo con iTime, etc.
Esto nunca será cierto.
Si hay algún historial cargado para el símbolo y el marco temporal, la función recuperará el valor más reciente.
Si no hay ningún historial cargado, obtendrá un error de Array out of range.
Lo mismo con iTime, etc.
Estoy de acuerdo.
Personalmente, sólo compruebo el valor de retorno de "ArrayCopyRates()" y después me limito a controlar el tamaño del array antes de acceder a los datos del mismo.
Con respecto a "iTime()" y otras funciones similares, siempre compruebo primero "iBars()".
Esto nunca será cierto.
if(pair1[0].time == 0) return;
Si hay algún historial cargado para el símbolo y el marco temporal, la función recuperará el valor más reciente.
Si no hay ningún historial cargado, obtendrá un error de Array out of range.
Lo mismo con iTime, etc.
Hay muchos ejemplos históricos (antes de la construcción de 600) para mirar un ACR. No hay otra forma de hacerlo. Las llamadas posteriores a ACR o iTime NO devolverán 4066, así que cómo se puede saber si los datos se han descargado.
iTime siempre ha devuelto cero en caso de error.
Hay muchos ejemplos históricos (pre-build 600) de mirar un ACR. No hay otra forma de hacerlo. Las llamadas posteriores a ACR o iTime NO devolverán el 4066, así que cómo se puede saber si los datos han sido descargados.
iTime siempre ha devuelto cero en un error.
¿Qué quieres decir con que "no hay otra forma de hacerlo"?
Comprobar el recuento de retornos de "ArrayCopyRates", y comprobar el tamaño del array, parece ser un método más robusto de comprobación, que hacer "pair1[0].time == 0" que puede devolver fácilmente unerror "Array index is out of range".
EDIT: He eliminado algunas de mis afirmaciones después de releer tu mensaje con más atención.

- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
Quiero elegir ENTRE 1 y 10 monedas diferentes y 5 barras para cada moneda.
Pero no sé cómo hacer esto.