- Registrar arrays
- Arrays dinámicos
- Medición de arrays
- Inicializar y rellenar arrays
- Copiar y editar arrays
- Mover (intercambiar) arrays
- Comparar, ordenar y buscar en arrays
- Dirección de indexación de series temporales en arrays
- Puesta a cero de objetos y arrays
Dirección de indexación de series temporales en arrays
Debido a las especificidades de trading aplicadas, MQL5 aporta características adicionales al trabajo con arrays. Una de ellas es que los elementos del array pueden contener datos correspondientes a puntos temporales. Por ejemplo, arrays con cotizaciones de instrumentos financieros, ticks de precios y lecturas de indicadores técnicos. El orden cronológico de los datos significa que constantemente se añaden nuevos elementos al final del array y sus índices aumentan.
No obstante, desde el punto de vista del trading, es más conveniente contar desde el presente hacia el pasado. Así, el elemento 0 siempre contiene el valor más reciente y actualizado, el elemento 1 siempre contiene el valor anterior, y así sucesivamente.
MQL5 le permite seleccionar y cambiar la dirección de indexación del array z sobre la marcha. Un array numerado del presente al pasado se denomina serie temporal. Si el aumento de la indexación se produce del pasado al presente, se trata de un array regular. En las series temporales, el tiempo disminuye con el crecimiento de los índices. En los arrays ordinarios, el tiempo aumenta, como en la vida real.
Es importante señalar que no es necesario que un array contenga valores relacionados con el tiempo para poder cambiar el orden de direccionamiento del mismo; es solo que esta función es la más demandada y, de hecho, parecía funcionar con datos históricos.
Este atributo de array no afecta a la disposición de los datos en memoria. Sólo cambia el orden de numeración. En concreto, podríamos implementar su análogo en MQL5 nosotros mismos recorriendo el array en un bucle «de atrás hacia adelante». Sin embargo, MQL5 proporciona funciones preparadas para ocultar toda esta rutina a los programadores de aplicaciones.
Series temporales pueden ser cualquier array dinámico unidimensional descrito en un programa MQL, así como arrays externos pasados al programa MQL desde el núcleo de MetaTrader 5, tales como parámetros de funciones de utilidad. Por ejemplo, un tipo especial de programas MQL, los indicadores, reciben arrays con los datos de precios del gráfico actual en el controlador de eventos OnCalculate. Estudiaremos todas las características del uso aplicado de las series temporales más adelante, en la quinta Parte del libro.
Los arrays definidos en un programa MQL no son series temporales por defecto.
Veamos un conjunto de funciones para determinar y modificar el atributo «serie» de u array, así como su «pertenencia» al terminal. El script general de ArrayAsSeries.mq5 con ejemplos se dará después de la descripción.
bool ArrayIsSeries(const void &array[])
La función devuelve un signo de si el array especificado es una serie temporal «real», es decir, controlada y proporcionada por el propio terminal. No se puede modificar esta característica de un array. Tales arrays están disponibles para el programa MQL en el modo «sólo lectura».
En la documentación de MQL5, los términos «timeseries» y «series» se utilizan para describir tanto la indexación inversa de un array como el hecho de que el array puede «pertenecer» al terminal (el terminal le asigna memoria y lo llena de datos). En el libro intentaremos evitar esta ambigüedad y nos referiremos a los arrays con indexación inversa como «timeseries» (series temporales). Y los arrays del terminal serán simplemente los arrays own del terminal.
Puede cambiar la indexación de cualquier array personalizado del terminal a su discreción cambiándola al modo de series temporales o volviendo al estándar. Para ello se utiliza la función ArraySetAsSeries, que es aplicable no sólo a los propios, sino también a los arrays dinámicos personalizados (véase más adelante).
bool ArrayGetAsSeries(const void &array[])
La función devuelve un signo de si el modo de indexación de series temporales está activado para el array especificado, es decir, la indexación aumenta en la dirección del presente al pasado. Puede cambiar la dirección de indexación utilizando la función ArraySetAsSeries.
La dirección de indexación afecta a los valores devueltos por las funciones ArrayBsearch, ArrayMaximum y ArrayMinimum (véase la sección Comparar, ordenar y buscar en arrays).
bool ArraySetAsSeries(const void &array[], bool as_series)
La función establece la dirección de indexación en el array según el parámetro as_series: el valor true significa el orden inverso de indexación, mientras que false significa el orden normal de los elementos.
La función devuelve true en caso de ajuste correcto del atributo, o false en caso de error.
Se admiten arrays de cualquier tipo, pero está prohibido cambiar la dirección de indexación en arrays multidimensionales y de tamaño fijo.
El script ArrayAsSeries.mq5 describe varios arrays pequeños para experimentos relacionados con las funciones anteriores.
#define LIMIT 10
|
Tenemos un array bidimensional array2D, un array fijo y uno dinámico, todos ellos de tipo double, así como arrays de estructuras y objetos de clase. Los arrays fixed y dynamic se rellenan con números enteros consecutivos (utilizando la función auxiliar indexArray) a efectos de demostración. Para otros tipos de arrays sólo comprobaremos la aplicabilidad del modo «serie», ya que la idea del efecto de indexación inversa quedará clara en el ejemplo de los arrays rellenos.
En primer lugar, asegúrese de que ninguno de los arrays sea el propio array del terminal:
PRTS(ArrayIsSeries(array2D)); // false
|
Todas las llamadas a ArrayIsSeries devuelven false, ya que hemos definido todos los arrays en el programa MQL. Veremos el valor true para los arrays de parámetros de la función OnCalculate en indicadores (en la quinta Parte).
A continuación, vamos a comprobar la dirección inicial de indexación del array:
PRTS(ArrayGetAsSeries(array2D)); // false, cannot be true
|
Y de nuevo nos encontraremos con false en todas partes.
Vamos a enviar los arrays fixed y dynamic al diario para ver el orden original de los elementos.
ArrayPrint(fixed, 1);
|
Ahora intentamos cambiar el orden de indexación:
// error: parameter conversion not allowed
|
Una sentencia para el array array2D provoca un error de compilación y, por lo tanto, se comenta.
Una sentencia para el array fixed emite una advertencia del compilador de que no se puede aplicar a un array de tamaño constante. En tiempo de ejecución, las tres últimas sentencias se realizan con éxito (true). Veamos cómo han cambiado los atributos de los arrays:
// attribute checks:
|
Como era de esperar, los arrays no se han convertido en arrays propios del terminal. Sin embargo, tres de cada cuatro arrays han cambiado su indexación al modo de series temporales, incluyendo un array de estructuras y objetos. Para demostrar el resultado, los arrays fixed y dynamic aparecen de nuevo en el registro.
ArrayPrint(fixed, 1); // without changes
|
Como el modo no se aplicó al array de tamaño constante, éste permaneció inalterado. El array dynamic se muestra ahora en orden inverso.
Si pone el array en modo de indexación inversa, lo redimensiona y luego vuelve a la indexación anterior, los elementos añadidos se insertarán al principio del array.