Capítulo 14: Trabajo con Arrays y Matrices
En este capítulo, aprenderemos a trabajar con arrays y matrices multidimensionales en MQL5. Estas estructuras de datos son esenciales para almacenar y manipular grandes volúmenes de información, como datos históricos de precios o resultados de cálculos técnicos. También exploraremos ejemplos prácticos de su uso en análisis técnico.
14.1. Declaración y Manipulación de Arrays
Un array es una colección de elementos del mismo tipo que se almacenan en memoria de forma contigua. En MQL5, los arrays pueden ser unidimensionales o multidimensionales y se utilizan comúnmente para almacenar datos históricos, como precios de cierre, indicadores o resultados de cálculos.
Ejemplo Práctico: Almacenamiento de Precios Históricos
//+------------------------------------------------------------------+
//| Ejemplo de declaración y manipulación de arrays |
//+------------------------------------------------------------------+
void OnStart() {
// Declaración de un array dinámico para almacenar precios de cierre
double closePrices[];
// Obtener el número total de barras disponibles
int bars = Bars(_Symbol, _Period);
// Redimensionar el array para almacenar los precios de las últimas 100 barras
ArrayResize(closePrices, 100);
// Llenar el array con los precios de cierre
for (int i = 0; i < 100; i++) {
closePrices[i] = Close[bars - 100 + i];
}
// Mostrar los precios almacenados en el array
Print("Precios de cierre almacenados:");
for (int i = 0; i < 100; i++) {
Print("Barra ", i, ": ", DoubleToString(closePrices[i], _Digits));
}
}
Explicación del Código
- Declaración de Arrays:
double closePrices[];declara un array dinámico para almacenar precios de cierre.- Los arrays dinámicos no tienen un tamaño fijo inicial y pueden redimensionarse según sea necesario.
- Redimensionamiento del Array:
- La función
ArrayResize()ajusta el tamaño del array para almacenar los últimos 100 precios de cierre.
- La función
- Llenado del Array:
- Usamos un bucle
forpara llenar el array con los precios de cierre de las últimas 100 barras.
- Usamos un bucle
- Acceso a los Elementos:
- Los elementos del array se acceden mediante índices (por ejemplo,
closePrices[i]).
- Los elementos del array se acceden mediante índices (por ejemplo,
14.2. Uso de Matrices Multidimensionales
Una matriz multidimensional es un array que tiene más de una dimensión. Por ejemplo, una matriz bidimensional puede representar una tabla con filas y columnas. En MQL5, estas matrices son útiles para realizar cálculos matriciales o almacenar datos estructurados.
Ejemplo Práctico: Cálculo de Medias Móviles en una Matriz Bidimensional
//+------------------------------------------------------------------+
//| Ejemplo de uso de matrices multidimensionales |
//+------------------------------------------------------------------+
void OnStart() {
// Declaración de una matriz bidimensional para almacenar medias móviles
double movingAverages[3][10]; // 3 períodos diferentes, 10 valores por período
// Definir los períodos de las medias móviles
int periods[3] = {10, 20, 50};
// Calcular las medias móviles para cada período
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 10; j++) {
movingAverages[i][j] = iMA(_Symbol, _Period, periods[i], 0, MODE_SMA, PRICE_CLOSE, j);
}
}
// Mostrar los resultados en la ventana de resultados
Print("Medias móviles calculadas:");
for (int i = 0; i < 3; i++) {
Print("Período ", periods[i], ":");
for (int j = 0; j < 10; j++) {
Print("Valor ", j, ": ", DoubleToString(movingAverages[i][j], _Digits));
}
}
}
Explicación del Código
- Declaración de Matrices:
double movingAverages[3][10];declara una matriz bidimensional con 3 filas (para 3 períodos) y 10 columnas (para 10 valores por período).
- Cálculo de Medias Móviles:
- Usamos un bucle anidado para calcular las medias móviles simples (
iMA) para cada período y almacenar los resultados en la matriz.
- Usamos un bucle anidado para calcular las medias móviles simples (
- Visualización de Resultados:
- Los resultados se imprimen en la ventana de resultados, mostrando las medias móviles para cada período.
14.3. Ejemplos Prácticos en Análisis Técnico
Los arrays y matrices son herramientas poderosas para implementar cálculos técnicos complejos. A continuación, mostramos un ejemplo práctico de cómo usar arrays para detectar cruces de medias móviles.
Ejemplo Práctico: Detección de Cruces de Medias Móviles
//+------------------------------------------------------------------+
//| Detección de cruces de medias móviles usando arrays |
//+------------------------------------------------------------------+
void OnStart() {
// Declaración de arrays para almacenar medias móviles rápidas y lentas
double fastMA[], slowMA[];
// Redimensionar los arrays para almacenar los últimos 100 valores
ArrayResize(fastMA, 100);
ArrayResize(slowMA, 100);
// Calcular las medias móviles rápidas y lentas
for (int i = 0; i < 100; i++) {
fastMA[i] = iMA(_Symbol, _Period, 10, 0, MODE_SMA, PRICE_CLOSE, i); // Media rápida (10 períodos)
slowMA[i] = iMA(_Symbol, _Period, 50, 0, MODE_SMA, PRICE_CLOSE, i); // Media lenta (50 períodos)
}
// Detectar cruces de medias móviles
for (int i = 1; i < 100; i++) {
if (fastMA[i - 1] <= slowMA[i - 1] && fastMA[i] > slowMA[i]) {
Print("Cruce alcista detectado en la barra ", i);
} else if (fastMA[i - 1] >= slowMA[i - 1] && fastMA[i] < slowMA[i]) {
Print("Cruce bajista detectado en la barra ", i);
}
}
}
Explicación del Código
- Almacenamiento de Datos:
- Los arrays
fastMAyslowMAalmacenan los valores de las medias móviles rápidas y lentas para las últimas 100 barras.
- Los arrays
- Detección de Cruces:
- Un bucle compara los valores de las medias móviles en barras consecutivas para detectar cruces alcistas o bajistas.
- Resultados:
- Los cruces se imprimen en la ventana de resultados, lo que permite identificar puntos de entrada o salida.
Interactividad: Ejercicios Prácticos
Ejercicio 1: Modifica el código de almacenamiento de precios históricos para incluir también los precios de apertura, máximo y mínimo.
Ver solución:Ocultar soluciónA continuación, te proporciono el código modificado para incluir los precios de apertura, máximo y mínimo , además de los precios de cierre. He añadido comentarios detallados para explicar cada cambio realizado.
//+------------------------------------------------------------------+
//| Almacenamiento de precios históricos (Open, High, Low, Close) |
//+------------------------------------------------------------------+
void OnStart() {
// Declaración de arrays dinámicos para almacenar precios
double openPrices[], highPrices[], lowPrices[], closePrices[];
// Obtener el número total de barras disponibles
int bars = Bars(_Symbol, _Period);
// Redimensionar los arrays para almacenar los datos de las últimas 100 barras
ArrayResize(openPrices, 100);
ArrayResize(highPrices, 100);
ArrayResize(lowPrices, 100);
ArrayResize(closePrices, 100);
// Llenar los arrays con los precios de apertura, máximo, mínimo y cierre
for (int i = 0; i < 100; i++) {
openPrices[i] = Open[bars - 100 + i]; // Precios de apertura
highPrices[i] = High[bars - 100 + i]; // Precios máximos
lowPrices[i] = Low[bars - 100 + i]; // Precios mínimos
closePrices[i] = Close[bars - 100 + i]; // Precios de cierre
}
// Mostrar los precios almacenados en los arrays
Print("Precios históricos almacenados:");
for (int i = 0; i < 100; i++) {
Print("Barra ", i, ":");
Print(" Apertura: ", DoubleToString(openPrices[i], _Digits));
Print(" Máximo: ", DoubleToString(highPrices[i], _Digits));
Print(" Mínimo: ", DoubleToString(lowPrices[i], _Digits));
Print(" Cierre: ", DoubleToString(closePrices[i], _Digits));
}
}
Explicación del Código
- Declaración de Arrays:
- Se declaran cuatro arrays dinámicos (
openPrices,highPrices,lowPrices,closePrices) para almacenar los precios de apertura, máximo, mínimo y cierre, respectivamente. - Los arrays son dinámicos, lo que significa que su tamaño puede ajustarse según sea necesario.
- Se declaran cuatro arrays dinámicos (
- Redimensionamiento de Arrays:
- La función
ArrayResize()se utiliza para ajustar el tamaño de cada array a 100 elementos, correspondientes a las últimas 100 barras.
- La función
- Llenado de Arrays:
- Un bucle
foritera sobre las últimas 100 barras y almacena los valores de apertura (Open), máximo (High), mínimo (Low) y cierre (Close) en sus respectivos arrays.
- Un bucle
- Visualización de Datos:
- Los datos almacenados en los arrays se imprimen en la ventana de resultados usando la función
Print(). - Cada barra muestra sus precios de apertura, máximo, mínimo y cierre en un formato claro y legible.
- Los datos almacenados en los arrays se imprimen en la ventana de resultados usando la función
Resultado Esperado
Cuando ejecutes este código, verás una salida similar a la siguiente en la ventana de resultados:
Precios históricos almacenados:
Barra 0:
Apertura: 1.2000
Máximo: 1.2050
Mínimo: 1.1980
Cierre: 1.2020
Barra 1:
Apertura: 1.2020
Máximo: 1.2060
Mínimo: 1.2000
Cierre: 1.2040
...
Interpretación del Cambio
Este ejercicio amplía el código original para incluir no solo los precios de cierre, sino también los precios de apertura, máximo y mínimo. Esto es útil porque:
- Proporciona una visión completa de los datos históricos de cada barra.
- Facilita el análisis técnico avanzado, como el cálculo de patrones de velas o indicadores basados en rangos de precios.
- Permite implementar estrategias que dependan de múltiples componentes del precio, como el rango (diferencia entre el máximo y el mínimo).
Casos Prácticos
Este código puede ser utilizado para:
- Analizar patrones de velas japonesas (por ejemplo, doji, martillo).
- Calcular indicadores técnicos como el ATR (Average True Range) o el rango diario.
- Implementar estrategias basadas en rupturas de máximos/mínimos o patrones de reversión.
¡Espero que este ejemplo te ayude a entender cómo trabajar con múltiples arrays en MQL5!
Ejercicio 2: Implementa una matriz tridimensional para almacenar datos de múltiples símbolos y temporalidades.
Ver solución:Ocultar solución//+------------------------------------------------------------------+
//| Matriz tridimensional para almacenar datos de símbolos y temporalidades |
//+------------------------------------------------------------------+
void OnStart() {
// Declaración de la matriz tridimensional
double data[3][4][10]; // [Símbolo][Temporalidad][Datos]
// Definir los símbolos y temporalidades
string symbols[] = {"EURUSD", "GBPUSD", "USDJPY"}; // Símbolos
int timeframes[] = {PERIOD_M15, PERIOD_H1, PERIOD_H4, PERIOD_D1}; // Temporalidades
// Llenar la matriz con precios de cierre para cada símbolo y temporalidad
for (int i = 0; i < ArraySize(symbols); i++) {
for (int j = 0; j < ArraySize(timeframes); j++) {
for (int k = 0; k < 10; k++) {
// Obtener el precio de cierre para la barra k en la temporalidad j del símbolo i
data[i][j][k] = iClose(symbols[i], timeframes[j], k);
}
}
}
// Mostrar los datos almacenados en la matriz
Print("Datos almacenados en la matriz tridimensional:");
for (int i = 0; i < ArraySize(symbols); i++) {
Print("Símbolo: ", symbols[i]);
for (int j = 0; j < ArraySize(timeframes); j++) {
Print(" Temporalidad: ", EnumToString((ENUM_TIMEFRAMES)timeframes[j]));
for (int k = 0; k < 10; k++) {
Print(" Barra ", k, ": ", DoubleToString(data[i][j][k], _Digits));
}
}
}
}
Explicación del Código
- Declaración de la Matriz Tridimensional:
double data[3][4][10];declara una matriz tridimensional:- La primera dimensión (
3) representa los símbolos. - La segunda dimensión (
4) representa las temporalidades. - La tercera dimensión (
10) representa los últimos 10 valores de cierre para cada combinación de símbolo y temporalidad.
- La primera dimensión (
- Definición de Símbolos y Temporalidades:
- Los símbolos se almacenan en un array (
symbols[]) con tres elementos:"EURUSD","GBPUSD"y"USDJPY". - Las temporalidades se almacenan en un array (
timeframes[]) con cuatro elementos:PERIOD_M15,PERIOD_H1,PERIOD_H4yPERIOD_D1.
- Los símbolos se almacenan en un array (
- Llenado de la Matriz:
- Un bucle anidado itera sobre los símbolos, temporalidades y barras para llenar la matriz con los precios de cierre (
iClose). - La función
iClose()obtiene el precio de cierre para una barra específica en una temporalidad y símbolo dados.
- Un bucle anidado itera sobre los símbolos, temporalidades y barras para llenar la matriz con los precios de cierre (
- Visualización de Datos:
- Los datos almacenados en la matriz se imprimen en la ventana de resultados usando la función
Print(). - La salida incluye el símbolo, la temporalidad y los precios de cierre para las últimas 10 barras.
- Los datos almacenados en la matriz se imprimen en la ventana de resultados usando la función
Resultado Esperado
Cuando ejecutes este código, verás una salida similar a la siguiente en la ventana de resultados:
Datos almacenados en la matriz tridimensional:
Símbolo: EURUSD
Temporalidad: PERIOD_M15
Barra 0: 1.2000
Barra 1: 1.2010
...
Temporalidad: PERIOD_H1
Barra 0: 1.2020
Barra 1: 1.2030
...
Símbolo: GBPUSD
Temporalidad: PERIOD_M15
Barra 0: 1.3800
Barra 1: 1.3810
...
...
Interpretación del Cambio
Este ejercicio implementa una matriz tridimensional para almacenar datos de múltiples símbolos y temporalidades. Esto es útil porque:
- Permite organizar y acceder eficientemente a grandes volúmenes de datos estructurados.
- Facilita el análisis técnico multitemporal y multisímbolo, lo que es esencial para estrategias avanzadas como arbitraje o correlaciones entre pares de divisas.
- Proporciona una base sólida para desarrollar EAs que operen simultáneamente en múltiples activos y marcos temporales.
Casos Prácticos
Este código puede ser utilizado para:
- Analizar correlaciones entre diferentes símbolos en distintas temporalidades.
- Implementar estrategias de trading multitemporal, como cruces de medias móviles en múltiples marcos temporales.
- Desarrollar sistemas de arbitraje que comparen precios entre símbolos relacionados.
¡Espero que este ejemplo te ayude a entender cómo trabajar con matrices tridimensionales en MQL5!
Ejercicio 3: Crea un EA que use arrays para detectar divergencias entre el precio y un oscilador como el RSI.
Ver solución:Ocultar solución//+------------------------------------------------------------------+
//| EA para detectar divergencias entre precio y RSI |
//+------------------------------------------------------------------+
// Parámetros de entrada
input int RSIPeriod = 14; // Período del RSI
input int LookbackBars = 5; // Número de barras para buscar divergencias
// Arrays para almacenar datos históricos
double priceHighs[], priceLows[], rsiValues[];
// Función principal que se ejecuta en cada tick
void OnTick() {
// Redimensionar los arrays para almacenar los datos de las últimas barras
ArrayResize(priceHighs, LookbackBars);
ArrayResize(priceLows, LookbackBars);
ArrayResize(rsiValues, LookbackBars);
// Llenar los arrays con los precios máximos, mínimos y valores del RSI
for (int i = 0; i < LookbackBars; i++) {
priceHighs[i] = High[i]; // Precios máximos
priceLows[i] = Low[i]; // Precios mínimos
rsiValues[i] = iRSI(_Symbol, _Period, RSIPeriod, PRICE_CLOSE, i); // Valores del RSI
}
// Detectar divergencias alcistas y bajistas
DetectDivergences();
}
// Función para detectar divergencias
void DetectDivergences() {
// Divergencia alcista: Precio baja, RSI sube
if (priceLows[0] < priceLows[1] && rsiValues[0] > rsiValues[1]) {
Print("Divergencia alcista detectada en la barra 0.");
Alert("¡Divergencia alcista detectada!");
}
// Divergencia bajista: Precio sube, RSI baja
if (priceHighs[0] > priceHighs[1] && rsiValues[0] < rsiValues[1]) {
Print("Divergencia bajista detectada en la barra 0.");
Alert("¡Divergencia bajista detectada!");
}
}
Explicación del Código
- Parámetros de Entrada:
RSIPeriod: Define el período del RSI (por defecto, 14).LookbackBars: Define el número de barras a analizar para detectar divergencias (por defecto, 5).
- Declaración de Arrays:
priceHighs[]: Almacena los precios máximos de las últimas barras.priceLows[]: Almacena los precios mínimos de las últimas barras.rsiValues[]: Almacena los valores del RSI para las últimas barras.
- Redimensionamiento y Llenado de Arrays:
- La función
ArrayResize()ajusta el tamaño de los arrays al número de barras especificado (LookbackBars). - Un bucle
forllena los arrays con los precios máximos, mínimos y valores del RSI usando las funcionesHigh[],Low[]yiRSI().
- La función
- Detección de Divergencias:
- Divergencia Alcista: Ocurre cuando el precio forma un mínimo más bajo (
priceLows[0] < priceLows[1]) mientras el RSI forma un mínimo más alto (rsiValues[0] > rsiValues[1]). - Divergencia Bajista: Ocurre cuando el precio forma un máximo más alto (
priceHighs[0] > priceHighs[1]) mientras el RSI forma un máximo más bajo (rsiValues[0] < rsiValues[1]).
- Divergencia Alcista: Ocurre cuando el precio forma un mínimo más bajo (
- Alertas:
- Si se detecta una divergencia, se imprime un mensaje en la ventana de resultados y se muestra una alerta visual usando la función
Alert().
- Si se detecta una divergencia, se imprime un mensaje en la ventana de resultados y se muestra una alerta visual usando la función
Resultado Esperado
Cuando ejecutes este EA, verás lo siguiente:
- Si se detecta una divergencia alcista :
Divergencia alcista detectada en la barra 0.
¡Divergencia alcista detectada!
- Si se detecta una divergencia bajista :
Divergencia bajista detectada en la barra 0.
¡Divergencia bajista detectada!
Además, aparecerá una ventana emergente con la alerta correspondiente.
Interpretación del Cambio
Este ejercicio implementa un sistema para detectar divergencias entre el precio y el RSI utilizando arrays. Esto es útil porque:
- Las divergencias son señales técnicas poderosas que pueden indicar posibles cambios en la tendencia.
- El uso de arrays permite organizar y comparar datos históricos de manera eficiente.
- Las alertas visuales facilitan la toma de decisiones en tiempo real.
Casos Prácticos
Este EA puede ser utilizado para:
- Identificar oportunidades de compra o venta basadas en divergencias alcistas o bajistas.
- Integrar señales de divergencia en estrategias automatizadas.
- Monitorear múltiples activos y temporalidades para detectar divergencias en diferentes contextos.
¡Espero que este ejemplo te ayude a entender cómo usar arrays para detectar divergencias en MQL5!
Conclusión: El uso de arrays y matrices en MQL5 es fundamental para manejar grandes volúmenes de datos y realizar cálculos técnicos avanzados. Al dominar estas estructuras de datos, puedes:
* Almacenar y procesar datos históricos de manera eficiente.
* Implementar cálculos matriciales para análisis técnico complejo.
* Desarrollar EAs más robustos y flexibles.
En el próximo capítulo, exploraremos cómo integrar APIs externas para ampliar las capacidades de tus EAs.
¡Sigue practicando y perfeccionando tus habilidades en MQL5!
