De novato a experto: Noticias animadas utilizando MQL5 (X) Vista multigráfico de múltiples símbolos para el trading de noticias
Contenido:
- Introducción
- Estrategia de implementación
- Pruebas y resultados
- Conclusión
- Lecciones clave
- Archivos adjuntos
Introducción
En el artículo anterior, presentamos una función de gestión de múltiples símbolos que permite a los traders seleccionar rápidamente sus pares de trading preferidos. Esto redujo el tiempo dedicado a cambiar de gráfico solo para configurar un par para operar.
Sin embargo, seguía habiendo un problema: aunque los traders podían gestionar los pares seleccionados, seguían sin poder acceder directamente a la API de gráficos de esos pares, por lo que no podían visualizar cómodamente su precio para el análisis. Para solucionar esto, hoy perfeccionamos nuestra estrategia de trading con múltiples símbolos mediante el desarrollo de una clase específica para la visualización de múltiples gráficos, que puede controlarse directamente desde el gráfico y se integra como parte del conjunto más amplio de funciones del EA News Headline.
Si en este momento te sientes perdido, aquí tienes un breve resumen de lo que hemos avanzado hasta ahora. También te animo a volver a consultar nuestras publicaciones anteriores sobre este tema para profundizar en el tema.
La primera versión del EA «News Headline» se centraba en reproducir los eventos programados del calendario en carriles claramente definidos en el gráfico, clasificados por orden de importancia. El concepto de «lanes» se amplió rápidamente: integramos una API de noticias de Alpha Vantage, añadimos análisis basados en modelos de IA alojados localmente y creamos «lanes» para ofrecer análisis integrados basados en indicadores. Partiendo de esta base, hemos incorporado funciones de trading automatizado basado en noticias, incluyendo funciones específicas para operar el NFP (Non-Farm Payrolls), combinadas con la integración de botones de trading manual.
Recientemente, hemos dado un paso adelante hacia el trading con múltiples símbolos, diseñado para la toma de decisiones a gran velocidad durante episodios de volatilidad. Esta función facilitó considerablemente la gestión y la operativa con múltiples pares en condiciones de mercado volátiles.
Hoy nos centramos en perfeccionar este enfoque de trading con múltiples símbolos, proporcionando a los traders vistas de múltiples gráficos en tiempo real directamente desde el EA.
Estrategia de implementación
Una de nuestras principales prioridades es transmitir los conocimientos de tal manera que incluso un lector sin experiencia pueda comprender fácilmente los conceptos con claridad. En esta sección, analizaremos el enfoque y la implementación que aplicaremos para alcanzar ese objetivo.
A medida que nuestro programa crece, es importante adoptar un enfoque estructurado y fácil de mantener a la hora de integrar nuevas funciones. Una de mis técnicas favoritas es la modularización, que garantiza un desarrollo fluido y nos permite crear utilidades reutilizables en forma de encabezados y clases.
Para un programa tan sofisticado como el News Headline EA, sigo un flujo de trabajo sistemático:
- Comenzar desarrollando un miniprograma independiente dedicado a probar la nueva función.
- Una vez que se compruebe que la función es viable y estable, proceder a su integración en el EA principal.
Este proceso ofrece un flujo de trabajo bien definido, reduce los errores y garantiza que las nuevas funciones se incorporen sin problemas, sin afectar al funcionamiento de las funciones existentes.
Hoy, nuestra tarea de diseño consiste en crear una clase CChartMiniTiles, que se encargará de mostrar gráficos de varios símbolos dentro de un único gráfico, cada uno con unas dimensiones personalizables. A continuación, implementaremos la clase en un EA de prueba (MiniChartsEA) para validar el concepto. Una vez confirmada, la clase se integrará en el EA «News Headline» y se adaptará para garantizar un funcionamiento fluido.
Por último, ten en cuenta que nombres como «CChartMiniTiles» y «MiniChartsEA» son simplemente nombres de ejemplo que he elegido para este tutorial; puedes utilizar nombres diferentes, siempre y cuando comprendas cómo funciona el programa.
En las cuatro subsecciones siguientes, nos centraremos en la implementación:
- Encabezado de ChartMiniTiles
- Ejemplo de EA (MiniChartsEA) para probar el encabezado
- Pruebas iniciales
- Integración de ChartsMiniTiles en el EA «News Headline»
1.0 Encabezado de ChartMiniTiles
Este archivo de encabezado define la clase CChartMiniTiles, una utilidad reutilizable diseñada para mostrar y gestionar varios minigráficos dentro de un único gráfico de MetaTrader 5. El objetivo de esta clase es simplificar la integración de vistas gráficas de múltiples símbolos en proyectos de mayor envergadura, como el EA «News Headline», al tiempo que se mantiene el código modular y fácil de mantener.
Al aislar esta funcionalidad en un archivo de encabezado independiente, nos aseguramos de que la función se pueda probar de forma independiente (por ejemplo, con un EA de prueba) y, posteriormente, integrarse a la perfección en sistemas más complejos. Este enfoque mejora el flujo de trabajo y reduce la probabilidad de que se produzcan errores durante el desarrollo.
En los siguientes apartados, desglosaremos el proceso de desarrollo del código en pasos numerados, cada uno de los cuales se centrará en un aspecto concreto de la estructura y la funcionalidad del programa.
1.1. Descripción general y objetivo de la clase
Este bloque inicial describe la finalidad del archivo de encabezado y define los valores predeterminados en tiempo de compilación que se utilizan en toda la clase. El uso de macros permite centralizar el diseño, los parámetros temporales y los valores predeterminados del conmutador, de modo que los responsables del mantenimiento puedan ajustar rápidamente el comportamiento sin tener que profundizar en los detalles de la implementación. El encabezado del comentario describe las características: minigráficos anclados en la parte inferior creados con OBJ_CHART, resolución automática de símbolos para diferentes brókeres, un botón de alternancia para controlar rápidamente la visibilidad, cálculo de diseño adaptativo y una opción de área reservada en la parte superior para evitar conflictos con otros elementos de la interfaz de usuario. Esta sección sirve para que el lector se familiarice con la estructura de la clase y con sus objetivos.
//+------------------------------------------------------------------+ //| ChartMiniTilesClass.mqh | //| Class wrapper for ChartMiniTiles functionality | //| - CChartMiniTiles class | //| - bottom-anchored mini-chart tiles using OBJ_CHART | //| - broker-adaptive symbol lookup, toggle button, responsive layout | //| - supports top-reserved area to avoid overlapping top UI | //+------------------------------------------------------------------+ #ifndef __CHART_MINI_TILES_CLASS_MQH__ #define __CHART_MINI_TILES_CLASS_MQH__ //--- compile-time defaults (macros are safe in MQL5) #define CMT_DEFAULT_WIDTH 120 #define CMT_DEFAULT_HEIGHT 112 // quadrupled default #define CMT_DEFAULT_X_OFFSET 10 #define CMT_DEFAULT_Y_OFFSET 40 // bottom offset from bottom #define CMT_DEFAULT_SPACING 6 #define CMT_DEFAULT_PERIOD PERIOD_M1 #define CMT_DEFAULT_CHART_SCALE 2 // toggle button defaults #define CMT_TOG_X 8 #define CMT_TOG_Y 6 #define CMT_TOG_W 72 #define CMT_TOG_H 20 #define CMT_TOG_NAME "CMT_ToggleButton"
1.2. Constructor y destructor
El constructor inicializa la clase a un estado conocido y seguro utilizando los valores predeterminados de tiempo de compilación. Prepara las matrices internas, los tamaños y desplazamientos predeterminados de los minigráficos, y la configuración de los botones de alternancia, y establece m_top_reserved en cero (sin área reservada por defecto). El destructor llama a Delete() para garantizar que todos los objetos creados por la clase se eliminen cuando la instancia quede fuera del ámbito. Esta configuración y destrucción deterministas evitan que queden objetos residuales en el gráfico y reducen los problemas a la hora de depurar.
//+------------------------------------------------------------------+ //| CChartMiniTiles class declaration | //+------------------------------------------------------------------+ class CChartMiniTiles { public: CChartMiniTiles(void); ~CChartMiniTiles(void); bool Init(const string majorSymbols, const int width = -1, const int height = -1, const int xOffset = -1, const int yOffset = -1, // bottom offset (pixels from bottom) const int spacing = -1, const int period = -1, const bool dateScale = true, const bool priceScale = false, const int chartScale = -1); void UpdateLayout(void); void Delete(void); bool HandleEvent(const int id,const string sparam); // forward OnChartEvent void SetToggleButtonPos(const int x,const int y); void SetTilesVisible(const bool visible); void Toggle(void); // NEW: reserve top area height (pixels from top) that tiles must NOT cover void SetTopReservedHeight(const int pixels); private: // state string m_object_names[]; // object names created string m_symbols[]; // resolved broker symbols int m_count; int m_width; int m_height; int m_xoffset; int m_yoffset; // bottom offset int m_spacing; int m_period; bool m_date_scale; bool m_price_scale; int m_chart_scale; bool m_visible; int m_tog_x; int m_tog_y; int m_tog_w; int m_tog_h; string m_tog_name; // NEW int m_top_reserved; // pixels from top that must be left free for other UI private: // helpers string MakeObjectName(const string base); string TrimString(const string s); string FindBrokerSymbol(const string baseSymbol); int ComputeBaseYFromTop(void); void CreateToggleButton(void); void DeleteToggleButton(void); void CollapseAll(void); }; //+------------------------------------------------------------------+ //| Constructor / Destructor | //+------------------------------------------------------------------+ CChartMiniTiles::CChartMiniTiles(void) { m_count = 0; ArrayResize(m_object_names,0); ArrayResize(m_symbols,0); m_width = CMT_DEFAULT_WIDTH; m_height = CMT_DEFAULT_HEIGHT; m_xoffset = CMT_DEFAULT_X_OFFSET; m_yoffset = CMT_DEFAULT_Y_OFFSET; m_spacing = CMT_DEFAULT_SPACING; m_period = CMT_DEFAULT_PERIOD; m_date_scale = false; m_price_scale = false; m_chart_scale = CMT_DEFAULT_CHART_SCALE; m_visible = true; m_tog_x = CMT_TOG_X; m_tog_y = CMT_TOG_Y; m_tog_w = CMT_TOG_W; m_tog_h = CMT_TOG_H; m_tog_name = CMT_TOG_NAME; m_top_reserved = 0; // default: no reserved area } CChartMiniTiles::~CChartMiniTiles(void) { Delete(); }
1.3. Métodos auxiliares
Estas funciones auxiliares específicas normalizan las entradas y ocultan las peculiaridades del bróker para que el resto de la clase pueda ser más sencilla. MakeObjectName depura las cadenas para convertirlas en nombres de objetos seguros (sustituyendo los espacios y los caracteres especiales). TrimString elimina los espacios en blanco al principio y al final, incluidos los tabuladores y los saltos de línea. FindBrokerSymbol intenta realizar una búsqueda exacta mediante SymbolSelect y, en caso de no encontrarla, lleva a cabo una búsqueda sin distinguir entre mayúsculas y minúsculas en la lista de símbolos del bróker para encontrar una coincidencia; esto es fundamental para garantizar la portabilidad entre brókeres que añaden sufijos o utilizan convenciones de nomenclatura diferentes. ComputeBaseYFromTop determina la línea de base vertical para los minigráficos anclados en la parte inferior, al tiempo que evita valores de altura de gráfico no válidos.
//+------------------------------------------------------------------+ //| Helpers implementation | //+------------------------------------------------------------------+ string CChartMiniTiles::MakeObjectName(const string base) { string name = base; StringReplace(name, " ", "_"); StringReplace(name, ".", "_"); StringReplace(name, ":", "_"); StringReplace(name, "/", "_"); StringReplace(name, "\\", "_"); return(name); } string CChartMiniTiles::TrimString(const string s) { if(s == NULL) return(""); int len = StringLen(s); if(len == 0) return(""); int left = 0; int right = len - 1; while(left <= right) { int ch = StringGetCharacter(s, left); if(ch == 32 || ch == 9 || ch == 10 || ch == 13) left++; else break; } while(right >= left) { int ch = StringGetCharacter(s, right); if(ch == 32 || ch == 9 || ch == 10 || ch == 13) right--; else break; } if(left > right) return(""); return StringSubstr(s, left, right - left + 1); } string CChartMiniTiles::FindBrokerSymbol(const string baseSymbol) { if(StringLen(baseSymbol) == 0) return(""); if(SymbolSelect(baseSymbol, true)) return(baseSymbol); string baseUpper = baseSymbol; StringToUpper(baseUpper); int total = SymbolsTotal(true); for(int i = 0; i < total; i++) { string s = SymbolName(i, true); if(StringLen(s) == 0) continue; string sUpper = s; StringToUpper(sUpper); if(StringFind(sUpper, baseUpper) >= 0) return(s); } return(""); } int CChartMiniTiles::ComputeBaseYFromTop(void) { int chartTotalHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); if(chartTotalHeight <= 0) chartTotalHeight = 600; int base_y_from_top = chartTotalHeight - m_yoffset - m_height; if(base_y_from_top < 0) base_y_from_top = 0; if(base_y_from_top + m_height > chartTotalHeight) base_y_from_top = MathMax(0, chartTotalHeight - m_height); return base_y_from_top; }
1.4. Control mediante botón de alternancia
El control interactivo se realiza mediante un botón de alternancia. CreateToggleButton comprueba que exista un objeto botón (y lo crea si no existe) y establece las propiedades visuales: posición, tamaño, fuente, color de fondo, color del texto, capacidad de selección y el texto del estado inicial determinado por m_visible. DeleteToggleButton lo elimina por completo. «CollapseAll» es un método ligero para ocultar elementos que, en lugar de eliminarlos, los oculta de forma eficaz desplazándolos fuera de la pantalla y estableciendo su tamaño en cero; de este modo, se conserva su estado para poder volver a mostrarlos rápidamente y se evita la sobrecarga que supone volver a crear los objetos.
//+------------------------------------------------------------------+ //| Toggle button helpers | //+------------------------------------------------------------------+ void CChartMiniTiles::CreateToggleButton(void) { if(ObjectFind(ChartID(), m_tog_name) == -1) ObjectCreate(ChartID(), m_tog_name, OBJ_BUTTON, 0, 0, 0, 0, 0); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_XDISTANCE, m_tog_x); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_YDISTANCE, m_tog_y); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_XSIZE, m_tog_w); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_YSIZE, m_tog_h); ObjectSetString(ChartID(), m_tog_name, OBJPROP_FONT, "Arial"); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_FONTSIZE, 10); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_BGCOLOR, clrDarkSlateGray); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_COLOR, clrWhite); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_SELECTABLE, 1); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_STATE, m_visible ? 1 : 0); ObjectSetString(ChartID(), m_tog_name, OBJPROP_TEXT, m_visible ? "Tiles: ON" : "Tiles: OFF"); } void CChartMiniTiles::DeleteToggleButton(void) { if(ObjectFind(ChartID(), m_tog_name) >= 0) ObjectDelete(ChartID(), m_tog_name); } void CChartMiniTiles::CollapseAll(void) { for(int i = 0; i < ArraySize(m_object_names); i++) { string name = m_object_names[i]; if(StringLen(name) == 0) continue; if(ObjectFind(ChartID(), name) == -1) continue; ObjectSetInteger(ChartID(), name, OBJPROP_XDISTANCE, -1); ObjectSetInteger(ChartID(), name, OBJPROP_YDISTANCE, -1); ObjectSetInteger(ChartID(), name, OBJPROP_XSIZE, 0); ObjectSetInteger(ChartID(), name, OBJPROP_YSIZE, 0); } }
1.5. Inicialización de minigráficos
Init es la rutina de configuración principal: primero borra cualquier estado anterior, aplica los parámetros pasados (recurriendo a los valores predeterminados si es necesario), analiza la lista de símbolos principales separada por comas, recorta y resuelve cada uno de ellos en un símbolo específico del bróker mediante FindBrokerSymbol, y crea la matriz m_symbols. Calcula las restricciones de diseño a partir del ancho del gráfico y las dimensiones de los minigráficos, y luego aplica un límite de filas para evitar invadir m_top_reserved (el área superior reservada). Por cada símbolo resuelto, crea un objeto OBJ_CHART, establece sus propiedades (símbolo, periodo, distancias, tamaños, escalas de fecha/precio y escala del gráfico) y guarda el nombre del objeto creado para futuras actualizaciones o su eliminación. Tras su creación, genera el botón de alternancia, respeta el indicador de visibilidad inicial, vuelve a dibujar el gráfico y devuelve un resultado satisfactorio. Este método incluye el registro de la resolución de símbolos y de los objetos creados, de modo que el comportamiento en tiempo de ejecución es transparente.
//+------------------------------------------------------------------+ //| NEW: set top reserved height (pixels from top) | //+------------------------------------------------------------------+ void CChartMiniTiles::SetTopReservedHeight(const int pixels) { m_top_reserved = MathMax(0, pixels); } //+------------------------------------------------------------------+ //| Init: create mini tiles | //+------------------------------------------------------------------+ bool CChartMiniTiles::Init(const string majorSymbols, const int width, const int height, const int xOffset, const int yOffset, const int spacing, const int period, const bool dateScale, const bool priceScale, const int chartScale) { Delete(); m_width = (width <= 0) ? CMT_DEFAULT_WIDTH : width; m_height = (height <= 0) ? CMT_DEFAULT_HEIGHT : height; m_xoffset = (xOffset <= 0) ? CMT_DEFAULT_X_OFFSET : xOffset; m_yoffset = (yOffset <= 0) ? CMT_DEFAULT_Y_OFFSET : yOffset; m_spacing = (spacing <= 0) ? CMT_DEFAULT_SPACING : spacing; m_period = (period <= 0) ? CMT_DEFAULT_PERIOD : period; m_date_scale = dateScale; m_price_scale = priceScale; m_chart_scale = (chartScale <= 0) ? CMT_DEFAULT_CHART_SCALE : chartScale; ArrayFree(m_object_names); ArrayFree(m_symbols); m_count = 0; string raw[]; StringSplit(majorSymbols, ',', raw); int rawCount = ArraySize(raw); if(rawCount == 0) return(false); for(int i = 0; i < rawCount; i++) { string base = TrimString(raw[i]); if(StringLen(base) == 0) continue; string resolved = FindBrokerSymbol(base); if(resolved == "") { PrintFormat("CMT: symbol not found on this broker: %s", base); continue; } int n = ArraySize(m_symbols); ArrayResize(m_symbols, n + 1); m_symbols[n] = resolved; } m_count = ArraySize(m_symbols); PrintFormat("CMT: %d symbols resolved for mini-tiles.", m_count); for(int i=0;i<m_count;i++) PrintFormat("CMT: symbol[%d] = %s", i, m_symbols[i]); if(m_count == 0) return(false); ArrayResize(m_object_names, m_count); for(int i = 0; i < m_count; i++) m_object_names[i] = ""; int base_y_from_top = ComputeBaseYFromTop(); int chartW = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); if(chartW <= 0) chartW = 800; int columns = MathMax(1, chartW / (m_width + m_spacing)); // --- NEW: limit rows to avoid top reserved region int rows = (m_count + columns - 1) / columns; int availableAbove = MathMax(0, base_y_from_top - m_top_reserved); int maxRowsAllowed = 1 + (availableAbove / (m_height + m_spacing)); // bottom row + how many rows can fit above if(maxRowsAllowed < 1) maxRowsAllowed = 1; if(rows > maxRowsAllowed) { // increase columns to fit within allowed rows columns = (m_count + maxRowsAllowed - 1) / maxRowsAllowed; if(columns < 1) columns = 1; rows = (m_count + columns - 1) / columns; } // --- int createdCount = 0; for(int i = 0; i < m_count; i++) { string sym = m_symbols[i]; string objName = MakeObjectName("CMT_" + sym + "_" + IntegerToString(i)); m_object_names[i] = objName; int col = i % columns; int row = i / columns; int xdist = m_xoffset + col * (m_width + m_spacing); int ydist = base_y_from_top - row * (m_height + m_spacing); if(ydist < 0) ydist = 0; bool created = ObjectCreate(ChartID(), objName, OBJ_CHART, 0, 0, 0, 0, 0); if(!created) { PrintFormat("CMT: failed to create OBJ_CHART for %s (obj=%s)", sym, objName); m_object_names[i] = ""; continue; } ObjectSetString(ChartID(), objName, OBJPROP_SYMBOL, sym); ObjectSetInteger(ChartID(), objName, OBJPROP_PERIOD, m_period); ObjectSetInteger(ChartID(), objName, OBJPROP_XDISTANCE, xdist); ObjectSetInteger(ChartID(), objName, OBJPROP_YDISTANCE, ydist); ObjectSetInteger(ChartID(), objName, OBJPROP_XSIZE, m_width); ObjectSetInteger(ChartID(), objName, OBJPROP_YSIZE, m_height); ObjectSetInteger(ChartID(), objName, OBJPROP_DATE_SCALE, (int)m_date_scale); ObjectSetInteger(ChartID(), objName, OBJPROP_PRICE_SCALE, (int)m_price_scale); ObjectSetInteger(ChartID(), objName, OBJPROP_SELECTABLE, 1); ObjectSetInteger(ChartID(), objName, OBJPROP_CHART_SCALE, m_chart_scale); createdCount++; } PrintFormat("CMT: created %d / %d mini-chart objects.", createdCount, m_count); CreateToggleButton(); if(!m_visible) SetTilesVisible(false); ChartRedraw(); return(true); }
1.6. Actualizaciones de diseño
UpdateLayout vuelve a calcular las posiciones y los tamaños cuando cambia la geometría o la visibilidad del gráfico. En primer lugar, gestiona el estado oculto colapsando los minigráficos y actualizando el botón de alternancia a «OFF». Cuando está visible, vuelve a calcular las columnas a partir del ancho del gráfico, aplica la restricción de espacio reservado en la parte superior (para que las filas nunca invadan el espacio reservado) y actualiza cada OBJ_CHART con los valores adecuados de OBJPROP_XDISTANCE, OBJPROP_YDISTANCE, los tamaños y la escala del gráfico. Por último, actualiza el estado del botón de alternancia a «ON» y llama a ChartRedraw() para que se actualice la interfaz de usuario. Este método está pensado para ejecutarse cada vez que se cambie el tamaño del gráfico o cuando el EA necesite actualizar la disposición.
//+------------------------------------------------------------------+ //| UpdateLayout - reposition tiles (respects m_visible and top reserved)| //+------------------------------------------------------------------+ void CChartMiniTiles::UpdateLayout(void) { if(!m_visible) { CollapseAll(); if(ObjectFind(ChartID(), m_tog_name) >= 0) { ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_XDISTANCE, m_tog_x); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_YDISTANCE, m_tog_y); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_STATE, 0); ObjectSetString(ChartID(), m_tog_name, OBJPROP_TEXT, "Tiles: OFF"); } ChartRedraw(); return; } if(m_count == 0) return; int chartW = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); if(chartW <= 0) chartW = 800; int chartTotalHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); if(chartTotalHeight <= 0) chartTotalHeight = 600; int columns = MathMax(1, chartW / (m_width + m_spacing)); int base_y_from_top = ComputeBaseYFromTop(); // --- NEW: ensure rows don't surpass top-reserved area int rows = (m_count + columns - 1) / columns; int availableAbove = MathMax(0, base_y_from_top - m_top_reserved); int maxRowsAllowed = 1 + (availableAbove / (m_height + m_spacing)); if(maxRowsAllowed < 1) maxRowsAllowed = 1; if(rows > maxRowsAllowed) { columns = (m_count + maxRowsAllowed - 1) / maxRowsAllowed; if(columns < 1) columns = 1; rows = (m_count + columns - 1) / columns; } // --- for(int i = 0; i < m_count; i++) { string name = m_object_names[i]; if(StringLen(name) == 0) continue; if(ObjectFind(ChartID(), name) == -1) continue; int col = i % columns; int row = i / columns; int xdist = m_xoffset + col * (m_width + m_spacing); int ydist = base_y_from_top - row * (m_height + m_spacing); if(ydist < 0) ydist = 0; ObjectSetInteger(ChartID(), name, OBJPROP_XDISTANCE, xdist); ObjectSetInteger(ChartID(), name, OBJPROP_YDISTANCE, ydist); ObjectSetInteger(ChartID(), name, OBJPROP_XSIZE, m_width); ObjectSetInteger(ChartID(), name, OBJPROP_YSIZE, m_height); ObjectSetInteger(ChartID(), name, OBJPROP_CHART_SCALE, m_chart_scale); } if(ObjectFind(ChartID(), m_tog_name) >= 0) { ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_XDISTANCE, m_tog_x); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_YDISTANCE, m_tog_y); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_STATE, 1); ObjectSetString(ChartID(), m_tog_name, OBJPROP_TEXT, "Tiles: ON"); } ChartRedraw(); }
1.7. Visibilidad y alternancia
Este pequeño conjunto de métodos controla el estado de visibilidad de los minigráficos. SetTilesVisible actualiza el indicador m_visible y, en función del nuevo estado, vuelve a colocar los minigráficos o los oculta; además, actualiza el estado y el texto del botón de alternancia. Toggle es un envoltorio práctico que alterna la visibilidad y llama a SetTilesVisible. SetToggleButtonPos permite reposicionar dinámicamente el botón de alternancia; si el botón ya existe, actualiza sus propiedades OBJPROP_XDISTANCE y OBJPROP_YDISTANCE. Estos métodos son los puntos de acceso programáticos y de la interfaz de usuario para mostrar, ocultar y cambiar la posición de los controles de mosaico.
//+------------------------------------------------------------------+ //| Set visibility programmatically | //+------------------------------------------------------------------+ void CChartMiniTiles::SetTilesVisible(const bool visible) { m_visible = visible; if(m_count == 0) { if(ObjectFind(ChartID(), m_tog_name) >= 0) { ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_STATE, m_visible ? 1 : 0); ObjectSetString(ChartID(), m_tog_name, OBJPROP_TEXT, m_visible ? "Tiles: ON" : "Tiles: OFF"); ChartRedraw(); } return; } if(m_visible) UpdateLayout(); else { CollapseAll(); ChartRedraw(); } if(ObjectFind(ChartID(), m_tog_name) >= 0) { ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_STATE, m_visible ? 1 : 0); ObjectSetString(ChartID(), m_tog_name, OBJPROP_TEXT, m_visible ? "Tiles: ON" : "Tiles: OFF"); } } //+------------------------------------------------------------------+ //| Toggle | //+------------------------------------------------------------------+ void CChartMiniTiles::Toggle(void) { SetTilesVisible(!m_visible); } //+------------------------------------------------------------------+ //| Set toggle position | //+------------------------------------------------------------------+ void CChartMiniTiles::SetToggleButtonPos(const int x,const int y) { m_tog_x = x; m_tog_y = y; if(ObjectFind(ChartID(), m_tog_name) >= 0) { ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_XDISTANCE, m_tog_x); ObjectSetInteger(ChartID(), m_tog_name, OBJPROP_YDISTANCE, m_tog_y); } }
1.8. Limpieza y gestión de eventos
Por último, la función Delete lleva a cabo una limpieza exhaustiva: recorre la matriz de nombres de objetos y elimina cada objeto OBJ_CHART creado, retira el botón de alternancia, libera las matrices con ArrayFree, restablece m_count y vuelve a dibujar el gráfico. HandleEvent es el método de reenvío de eventos diseñado para ser invocado desde el método OnChartEvent de un EA; filtra en busca de CHARTEVENT_OBJECT_CLICK y del nombre del botón de alternancia; si se ha pulsado el botón, invoca a Toggle() y devuelve «true» para indicar que el evento ha sido gestionado. Esto simplifica la integración con EA: reenvía los eventos y llama a Init/Delete en OnInit/OnDeinit.
//+------------------------------------------------------------------+ //| Delete all objects | //+------------------------------------------------------------------+ void CChartMiniTiles::Delete(void) { for(int i = 0; i < ArraySize(m_object_names); i++) { string name = m_object_names[i]; if(StringLen(name) == 0) continue; if(ObjectFind(ChartID(), name) >= 0) ObjectDelete(ChartID(), name); } DeleteToggleButton(); ArrayFree(m_object_names); ArrayFree(m_symbols); m_count = 0; ChartRedraw(); } //+------------------------------------------------------------------+ //| HandleEvent - forward OnChartEvent to class (returns true if handled)| //+------------------------------------------------------------------+ bool CChartMiniTiles::HandleEvent(const int id,const string sparam) { if(id != CHARTEVENT_OBJECT_CLICK) return(false); if(StringLen(sparam) == 0) return(false); if(sparam == m_tog_name) { Toggle(); return(true); } return(false); } //+------------------------------------------------------------------+ #endif // __CHART_MINI_TILES_CLASS_MQH__
Encontrarás el código fuente completo de este encabezado al final de este artículo, junto con los demás archivos a los que se hace referencia a lo largo del mismo.
2.0 Ejemplo de EA (MiniChartsEA) para probar el encabezado
2.1. Descripción general y finalidad del EA
Este EA sirve como banco de pruebas para la clase CChartMiniTiles. Crea una instancia de la clase, inicializa minigráficos para varios símbolos y comprueba el correcto funcionamiento de las funciones de activación/desactivación, cambio de tamaño y actualización antes de integrarla en proyectos más amplios.
//+------------------------------------------------------------------+ //| MiniChartsEA.mq5| //| Dummy EA to test CChartMiniTiles (ChartMiniTilesClass) | //+------------------------------------------------------------------+ #property copyright "2025" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property description "Mini-charts EA using CChartMiniTiles class" // --- Include the class header #include <ChartMiniTiles.mqh>
2.2. Entradas y variables globales
En esta sección se definen los parámetros y las variables de estado que controlan los minigráficos (lista de símbolos, dimensiones y comportamiento de actualización).
//--- Inputs input string MajorSymbols = "EURUSD,GBPUSD,USDJPY,USDCHF,USDCAD,AUDUSD,NZDUSD"; input int BarsWidth = 20; // bars used to estimate tile pixel width input int TileHeightPx = 112; // tile height in pixels input int HorizontalSpacing = 6; // spacing between tiles input int UpdateInterval = 1000; // ms timer update interval input int XOffset = 10; // left margin in pixels input int BottomOffset = 40; // distance from bottom in pixels input int ToggleButtonX = 8; // toggle button X input int ToggleButtonY = 6; // toggle button Y input bool DateScale = false;// show date scale input bool PriceScale = false;// show price scale input int ChartScale = 2; // chart zoom level //--- object instance of our class CChartMiniTiles tiles; //--- internal state int pixelWidth = 120;
2.3. Métodos auxiliares
Este método calcula dinámicamente el ancho de los minigráficos en píxeles en función del número de barras que están visibles en ese momento.
//+------------------------------------------------------------------+ //| Helper: estimate pixel width from BarsWidth | //+------------------------------------------------------------------+ int CalculateChartWidthFromBars(int barsWidth) { int mainChartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); int visibleBars = (int)ChartGetInteger(0, CHART_VISIBLE_BARS); if(visibleBars <= 0 || mainChartWidth <= 0) return MathMax(80, BarsWidth * 6); // fallback return MathMax(80, barsWidth * mainChartWidth / visibleBars); }
2.4. Control mediante botón de alternancia
Se gestiona mediante el objeto de minigráficos (CChartMiniTiles). El propio EA solo establece la posición inicial del botón de alternancia.
// Inside OnInit we call:
tiles.SetToggleButtonPos(ToggleButtonX, ToggleButtonY);
2.5. Inicialización de minigráficos
En esta etapa se crean todos los minigráficos con los ajustes definidos por el usuario.
//+------------------------------------------------------------------+ //| Expert initialization | //+------------------------------------------------------------------+ int OnInit() { // compute pixel width from BarsWidth heuristic pixelWidth = CalculateChartWidthFromBars(BarsWidth); // set toggle button position tiles.SetToggleButtonPos(ToggleButtonX, ToggleButtonY); // initialize tiles bool ok = tiles.Init(MajorSymbols, pixelWidth, TileHeightPx, XOffset, BottomOffset, HorizontalSpacing, PERIOD_M1, DateScale, PriceScale, ChartScale); if(!ok) { Print("MiniChartsEA: tiles.Init() failed. Check Experts log for symbol issues."); return(INIT_FAILED); } // start timer for adaptive updates EventSetMillisecondTimer(UpdateInterval); Print("MiniChartsEA initialized."); return(INIT_SUCCEEDED); }
2.6. Actualizaciones de diseño
Esto garantiza que los minigráficos cambien de tamaño y se reubiquen correctamente cuando el gráfico cambie o avance el tiempo.
//+------------------------------------------------------------------+ //| Timer: update layout | //+------------------------------------------------------------------+ void OnTimer() { tiles.UpdateLayout(); }
2.7. Visibilidad y alternancia
En este caso, el EA transfiere los clics del botón a la clase y detecta los cambios en el gráfico para mantener todo sincronizado.
//+------------------------------------------------------------------+ //| Chart events - forward to tiles | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Let tiles handle toggle button clicks if(tiles.HandleEvent(id, sparam)) return; // If chart resized or layout changed, reflow tiles if(id == CHARTEVENT_CHART_CHANGE) tiles.UpdateLayout(); }
2.8. Limpieza y gestión de eventos
Esto garantiza una eliminación correcta de los objetos cuando se detiene el EA.
//+------------------------------------------------------------------+ //| Deinitialization | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { EventKillTimer(); tiles.Delete(); Print("MiniChartsEA deinitialized."); }
3.0 Pruebas iniciales
En este punto, añadimos nuestro EA de ejemplo al gráfico y observamos los resultados. En mi prueba, el gráfico mostraba minigráficos para los pares principales que había seleccionado, cada uno de ellos adaptado al formato de símbolo de mi bróker (con el sufijo .0). El botón de alternancia funcionaba a la perfección, lo que me permitía activar y desactivar los minigráficos con facilidad. Esta función ofrece a los operadores la flexibilidad de ver el gráfico principal en pantalla completa cuando lo necesiten: un control sencillo pero muy útil.
Esta funcionalidad cobrará aún más valor una vez que la clase se integre en el EA News Headline, donde la combinación de varios componentes creará un entorno gráfico más complejo. La posibilidad de alternar rápidamente entre los minigráficos garantizará un espacio de trabajo más ordenado y manejable.
Consulte la imagen siguiente para ver la implementación y los resultados de MiniChartsEA.

Figura 1: Resultados de las pruebas del MiniChartsEA en el gráfico del EURUSD.
Ahora podemos continuar con la integración de la clase CChartMiniTiles en el EA News Headline. En la siguiente sección, analizaremos el código actualizado en detalle y, a continuación, revisaremos el comportamiento resultante en el gráfico.
4.0 Integración de ChartsMiniTiles en NewsHeadlineEA
4.1. Incluye el encabezado ChartMiniTiles: haz que la clase esté disponible para el EA
Para utilizar la clase «mini-tiles», debes incluir su archivo de encabezado en la parte superior del EA. De este modo, la declaración y la implementación de la clase pasan a formar parte de la unidad de compilación de EA, lo que te permite crear una instancia y llamar a sus métodos. Colocar el archivo «include» junto con los demás encabezados (TradingButtons, Canvas, Trade) permite mantener las importaciones organizadas y deja clara la dependencia a los futuros responsables del mantenimiento. Si el archivo no se encuentra en MQL5/Include/, el compilador mostrará un error aquí, por lo que este es el primer paso de la integración.
#include <TradingButtons.mqh> #include <Trade\Trade.mqh> #include <Canvas\Canvas.mqh> #include <ChartMiniTiles.mqh> // <-- CTM class include (make sure this file is in MQL5/Include/)
4.2. Declara la instancia de CChartMiniTiles: crea el gestor de minigráficos del EA
Al declarar un objeto global CChartMiniTiles, todo el EA tiene acceso a un único gestor de minigráficos. Esta instancia contiene información de estado (nombres de objetos creados, lista de símbolos, indicador de visibilidad, altura superior reservada) y ofrece métodos para la inicialización, la actualización del diseño, la gestión de eventos y la limpieza. Al declararlo junto con otras variables globales, resulta más fácil gestionar su ciclo de vida en OnInit, OnTimer, OnChartEvent y OnDeinit.
//+------------------------------------------------------------------+ //| ChartMiniTiles instance (CTM) | //+------------------------------------------------------------------+ CChartMiniTiles tiles; // class instance for mini tiles
4.3. Generar la lista de símbolos y calcular el ancho de píxeles de los minigráficos: preparar los datos de entrada para CMT
Antes de llamar a `tiles.Init`, necesitas una cadena de símbolos separados por comas y un ancho en píxeles adecuado para los minigráficos. En esta sección se crean los símbolos ctmSymbols a partir de la matriz majorPairs[] mediante la función JoinSymbolArray() y se calcula el ancho en píxeles utilizando una heurística de conversión de barras a píxeles basada en el ancho del gráfico principal y las barras visibles. Al hacer esto durante la inicialización, se garantiza que el tamaño de los minigráficos se adapte al diseño actual del gráfico y que FindBrokerSymbol, dentro de la clase, resuelva los nombres de los símbolos del bróker.
// Build a comma-separated symbol list from majorPairs[] and initialize CTM. string ctmSymbols = JoinSymbolArray(majorPairs); // Estimate pixel width from Bars heuristic (simple fallback) int mainChartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); int visibleBars = (int)ChartGetInteger(0, CHART_VISIBLE_BARS); int pixelWidth = 120; if(visibleBars > 0 && mainChartWidth > 0) pixelWidth = MathMax(80, CTM_TileWidthBars * mainChartWidth / visibleBars);
4.4. Coloca el botón de alternancia y ajusta su posición; mantén la interfaz de usuario accesible.
El botón de alternancia es el control que permite al usuario mostrar u ocultar los minigráficos. Al colocarlo deliberadamente justo debajo del panel de trading, se garantiza que no se superponga a controles importantes de la interfaz de usuario. Tras calcular tradingPanelBottomY, el EA llama a tiles.SetToggleButtonPos(toggleX, toggleY) para indicar a la clase dónde debe crear el botón. Esta colocación se realiza antes de inicializar los minigráficos, de modo que, al crearse, el botón respete la lógica del área reservada.
// Place the CTM toggle button JUST BELOW the trading panel bottom int toggleX = 8; int toggleY = tradingPanelBottomY + 6; // +6 px margin so it doesn't touch trading controls tiles.SetToggleButtonPos(toggleX, toggleY);
4.5. Reserva el espacio superior de la interfaz de usuario para los controles de trading; evita que se superpongan.
Para evitar que los minigráficos se superpongan al panel de operaciones y al botón de alternancia, el EA calcula un valor topReserve y llama a la función tiles.SetTopReservedHeight(topReserve). La clase «tiles» utiliza este valor para limitar el número de filas que se pueden apilar hacia arriba desde la parte inferior; de este modo, se reserva la zona superior para botones, lienzos u otros elementos de la interfaz de usuario. Reservar el espacio superior antes de llamar a Init garantiza que los cálculos de diseño lo respeten de inmediato.
// Reserve the area above tiles so the trading UI remains free. We reserve up to the toggle bottom. int topReserve = toggleY + CMT_TOG_H + 4; // leave a few px extra tiles.SetTopReservedHeight(topReserve);
4.6. Inicializar los minigráficos: crear objetos OBJ_CHART para cada símbolo
Esta es la llamada de integración principal. El EA pasa la lista de símbolos resueltos, el ancho de píxel calculado, la altura de los minigráficos, los desplazamientos, el espaciado, el periodo del gráfico y la escala a `tiles.Init(...)`. La clase resolverá los nombres específicos del bróker, creará objetos OBJ_CHART, configurará sus propiedades (símbolo, período, escalas, tamaños) y creará el botón de alternancia. El EA comprueba el valor booleano devuelto (ctm_ok) para gestionar adecuadamente los errores de inicialización (por ejemplo, si no se han resuelto los símbolos en este bróker).
// Initialize tiles: (symbols, widthPx, heightPx, xOffset, bottomOffset, spacing, period, dateScale, priceScale, chartScale) bool ctm_ok = tiles.Init(ctmSymbols, pixelWidth, CTM_TileHeightPx, CTM_XOffset, CTM_BottomOffset, CTM_Spacing, PERIOD_M1, false, false, CTM_ChartScale); if(!ctm_ok) { Print("CTM: initialization failed (no matching symbols?); tiles disabled."); }
4.7. Mantén el diseño adaptativo: llama a `UpdateLayout` cuando cambie el gráfico o según el temporizador
Una vez inicializado, el EA debe mantener los minigráficos en su sitio aunque cambie el tamaño o la disposición del gráfico. La integración abarca tres lugares:
- Reenvío de eventos de cambio de gráfico para reubicar los minigráficos (de modo que se gestionen los cambios de tamaño realizados por el usuario o los cambios en el espacio de trabajo).
- Llamar a tiles.UpdateLayout() periódicamente en el bucle OnTimer para gestionar los cambios dinámicos en la interfaz de usuario o para recuperarse de cambios externos.
- Llama a tiles.UpdateLayout() al final del bucle de procesamiento principal de OnTimer para que el CTM siempre se actualice después de otras actualizaciones de la interfaz de usuario (lienzos, noticias, información de la IA).
A continuación se muestran los fragmentos de código exactos que se utilizan en tu EA para gestionar estos casos.
Reenvío de eventos OnChartEvent y reacción ante cambios en el gráfico:
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Let CTM handle object clicks first (toggle button) if(tiles.HandleEvent(id, sparam)) return; // Forward to the TradingButtons header afterward buttonsEA.HandleChartEvent(id, sparam, majorPairs, pairSelected); // Also respond to chart change events for CTM layout if(id == CHARTEVENT_CHART_CHANGE) tiles.UpdateLayout(); }
Actualización al final del temporizador (mantiene CTM sincronizado en cada tick del temporizador):
// Keep CTM updated every tick (timer-driven)
tiles.UpdateLayout();
}
4.8. Limpieza al desinicializarse: eliminar minigráficos y alternar el botón
Cuando el EA se detiene o se elimina, debe eliminar todos los objetos que haya creado. Al llamar a tiles.Delete(), se eliminan todos los objetos OBJ_CHART y el botón de alternancia, se liberan las matrices y se vuelve a dibujar el gráfico. Este es el último paso de la integración y evita que queden objetos huérfanos en el gráfico.
// delete CTM tiles and toggle button
tiles.Delete();Lista de comprobación para una integración rápida (resumen)
- Incluye #include <ChartMiniTiles.mqh> al principio.
- Declara CChartMiniTiles como variable global.
- Crea ctmSymbols y calcula pixelWidth antes de Init.
- Establecer la posición del botón de alternancia mediante SetToggleButtonPos(...).
- Reserva la parte superior del área de la interfaz de usuario mediante tiles.SetTopReservedHeight(...).
- Inicializa con tiles.Init(...) y comprueba el valor devuelto.
- Reenvía OnChartEvent a tiles.HandleEvent(...) y llama a tiles.UpdateLayout() cuando cambie el gráfico y en las actualizaciones periódicas.
- Llama a tiles.Delete() en OnDeinit.
Pruebas y resultados
Esto marca la fase final de pruebas del EA integrado «News Headline». Tras compilar el programa sin errores en MetaEditor 5, lo implementamos en un gráfico del terminal de MetaTrader 5 para observar su comportamiento. Las siguientes capturas de pantalla muestran los resultados de mi prueba.

Figura 2: Implementación del EA «News Headline» en el gráfico del AUDUSD con minigráficos de gráficos para operar con múltiples símbolos

Figura 3: ChartMiniTiles en funcionamiento con News Headline EA
Tras analizar los resultados anteriores, hemos logrado integrar con éxito nuestra solución al problema identificado. Ahora los operadores pueden ver varios pares en un solo gráfico, y los botones de control funcionan correctamente. Otro logro destacable es que hemos implementado esta nueva función sin que se solape ni interfiera con las funciones existentes en el EA News Headline, gracias a una gestión adecuada del diseño y a las capacidades del lenguaje MQL5. En la siguiente sección, concluiremos destacando los principales resultados de este trabajo.
Conclusión
Hemos integrado con éxito una clase que gestiona varias vistas de minigráficos en un único gráfico principal utilizando News Headline EA. Este enfoque ofrece a los traders una potente herramienta para supervisar y operar con múltiples símbolos simultáneamente, lo que mejora la eficiencia, especialmente en períodos de alta volatilidad, como cuando se publican noticias importantes. Cuando se abren varias posiciones en distintos pares, esta herramienta permite a los traders gestionarlas y supervisarlas desde una única interfaz, lo que facilita el control y la ejecución rápidos de las operaciones.
Desde una perspectiva educativa, este debate ofrece información valiosa sobre temas como el desarrollo de clases personalizadas, las estrategias de trading con múltiples símbolos, la ejecución rápida de órdenes y la selección de pares, todo ello sin salir del gráfico actual.
Aunque esto demuestra la viabilidad del trading con múltiples pares, aún hay un margen considerable de mejora. En particular, es fundamental perfeccionar las técnicas que permitan un análisis más flexible de los pares seleccionados. Con un mayor desarrollo, el algoritmo podría incorporar métodos de análisis automático para mejorar el sistema actual. En futuras publicaciones se abordarán estas mejoras.
Os invitamos a que aportéis vuestras ideas y comentarios a este debate. A continuación se adjuntan el código fuente y una imagen en la que se muestra el gráfico principal junto con la configuración de ChartMiniTiles.
Lecciones clave
| Lección clave | Descripción: |
|---|---|
| Gestión de múltiples símbolos | Los traders pueden seleccionar y supervisar de forma eficaz varios pares de divisas sin tener que cambiar de gráfico constantemente. |
| Clase dedicada para vistas multigráfico | El uso de una clase independiente para gestionar varios minigráficos simplifica la integración y permite mantener un código modular. |
| Pruebas individuales antes de la integración | El desarrollo y la validación de una función en un entorno de pruebas independientes garantiza la estabilidad antes de integrarla en el EA principal. |
| Diseños de minigráficas personalizables | Los minigráficos se pueden redimensionar y organizar según las preferencias del usuario, lo que mejora la visibilidad y el flujo de trabajo. |
| Visualización de múltiples símbolos en tiempo real | Mostrar varios símbolos en un solo gráfico permite a los traders reaccionar con mayor rapidez en situaciones de volatilidad del mercado. |
| Programación modular | La separación de las funciones en encabezados y clases facilita el mantenimiento y la reutilización en distintos proyectos. |
| Desarrollo incremental de funcionalidades | La incorporación gradual de nuevas funciones reduce los errores y garantiza una integración fluida con los sistemas existentes. |
| Gestión de eventos en minigráficos | Cada minigráfico puede responder a las interacciones del usuario, lo que permite realizar análisis interactivos y dinámicos. |
| Integración con EA principal | Tras las pruebas, la clase de minigráficos se integra en el EA principal para ofrecer una funcionalidad fluida de trading multisímbolo. |
| Clases de utilidades reutilizables | Las clases como CChartMiniTiles sirven como herramientas modulares que pueden adaptarse a otros proyectos y EA. |
| Prácticas para un flujo de trabajo eficiente | El uso de un flujo de trabajo estructurado —prototipo, prueba, integración— mejora la velocidad de desarrollo y reduce los errores. |
| Apoyo a la toma de decisiones rápida | Los minigráficos ofrecen a los operadores una visión global de múltiples mercados, lo que les permite tomar decisiones de trading con mayor rapidez. |
| Gestión dinámica de objetos | El código muestra cómo crear, actualizar y eliminar objetos de gráfico de forma dinámica para cada minigráfico, algo esencial para el diseño de EA escalables. |
| Uso eficiente de la memoria | Al gestionar los minigráficos como objetos independientes y actualizar únicamente los elementos visibles, el EA optimiza el uso de la memoria y la CPU. |
| Propagación fluida de eventos | La clase de minigráficos muestra cómo gestionar los eventos de los gráficos de forma jerárquica, garantizando que los eventos lleguen a la instancia de gráfico correcta sin que se produzcan conflictos. |
Archivos adjuntos
| Nombre del archivo | Versión | Descripción |
|---|---|---|
| ChartMiniTiles.mqh | 1.0 | Define la clase CChartMiniTiles, encargada de gestionar y mostrar varias vistas de minigráficos dentro de un único gráfico principal. Ofrece funciones modulares de visualización e interacción con múltiples símbolos. |
| MiniChartsEA.mq5 | 1.0 | EA de prueba creado para probar la clase CChartMiniTiles de forma independiente antes de integrarla en el EA principal «News Headline». Comprueba el diseño, el cambio de tamaño y la gestión de eventos de los minigráficos. |
| NewsHeadlineEA.mq5 | 1.14 | Asesor experto principal que integra múltiples funciones: visualización de noticias, operaciones automatizadas basadas en eventos del calendario y operaciones con múltiples símbolos mediante minigráficos. |
| TradingButtons.mqh | 1.0 | Ofrece botones para ejecutar operaciones, seleccionar pares y gestionar órdenes directamente desde el gráfico. Permite realizar operaciones rápidas con múltiples símbolos en el EA. |
| terminal64_Dp0JGQhX5.png | N/A | Captura de pantalla de un gráfico de terminal ampliado que ilustra la función ChartMiniTiles del EA News Headline, en la que se muestran operaciones con múltiples símbolos, supervisión en tiempo real y análisis visual rápido. |
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/19299
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Utilizando redes neuronales en MetaTrader
De novato a experto: Dominando la generación de informes detallados de trading con Reporting EA
Particularidades del trabajo con números del tipo double en MQL4
Programación gráfica para principiantes (Parte II): Dominando la Interfaz, POO y Persistencia
- 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