Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 8): Panel de métricas
Contenido
- Introducción
- Descripción general del sistema
- Código MQL5
- Desglose e implementación del código
- Incluyendo librerías
- Resultados
- Conclusión
Introducción
En las primeras etapas de nuestra serie, publicamos un artículo titulado «Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 3): Asesor Experto Analytics Master», en el que se exploraban métodos para recuperar y visualizar las métricas del mercado del día anterior. Este trabajo fundamental sentó las bases para el desarrollo de herramientas más sofisticadas. Nos complace presentar Metrics Board EA, una solución innovadora y de alta calidad que revoluciona el análisis de mercado dentro de MetaTrader 5. Esta herramienta funciona como una aplicación perfectamente integrada, que ofrece una interfaz optimizada y sencilla equipada con botones específicos para análisis avanzados, entre los que se incluyen:
- Análisis alto/bajo: Detecte sin esfuerzo los niveles de precios críticos para evaluar las tendencias del mercado e identificar posibles reversiones.
- Análisis de volumen: Analizar los volúmenes de negociación para evaluar el compromiso del mercado y las condiciones de liquidez.
- Análisis de tendencias: Evalúe la fuerza direccional y la sostenibilidad mediante métricas precisas.
- Análisis de volatilidad: Cuantificar las fluctuaciones del mercado para formular estrategias adaptadas a los distintos entornos comerciales.
- Análisis de medias móviles: Supervise las tendencias dinámicas de los precios para comprender mejor el comportamiento del mercado.
- Análisis de soporte/resistencia: Identifique los niveles de precios fundamentales para optimizar las entradas, salidas y estrategias de gestión de riesgos.
Cada botón ofrece datos en tiempo real con un simple clic, transformando datos complejos del mercado en información útil al instante. El Metrics Board EA funciona con algoritmos avanzados, lo que garantiza cálculos precisos y de alta velocidad que satisfacen las necesidades de los operadores profesionales. Al utilizar esta herramienta, los operadores pueden transformar datos de mercado complejos en información clara y útil. Este EA es un recurso clave para quienes desean perfeccionar sus estrategias de trading.
Descripción general del sistema
En esta sección, ofreceré una breve descripción general de la lógica del sistema. En la sección Desglose e implementación del código se ofrece una explicación detallada de los pasos. Sigamos los pasos que se indican a continuación:
- Configuración de la clase: La clase crea un cuadro de diálogo con botones para diferentes análisis.
- Gestión de eventos: Los clics en los botones activan los métodos de análisis correspondientes.
- Análisis y visualización: Los datos del mercado se procesan y se muestran en el panel.
- Cerrar: El botón «Cerrar» permite al usuario cerrar el panel de métricas.

Figura 1. Resumen de la lógica del EA
Código MQL5
//+------------------------------------------------------------------+ //| Metrics Board.mql5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com| //+------------------------------------------------------------------+ #property copyright "2025, MetaQuotes Software Corp." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict #include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Label.mqh> #include <Controls\Panel.mqh> // Metrics Board Class class CMetricsBoard : public CAppDialog { private: CButton m_btnClose; // Close Button CButton m_btnHighLowAnalysis; CButton m_btnVolumeAnalysis; CButton m_btnTrendAnalysis; CButton m_btnVolatilityAnalysis; CButton m_btnMovingAverage; CButton m_btnSupportResistance; CPanel m_panelResults; CLabel m_lblResults; public: CMetricsBoard(void); ~CMetricsBoard(void); virtual bool Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2); virtual void Minimize(); virtual bool Run(); // Declaration of Run method virtual bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam); virtual bool ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam); virtual void Destroy(const int reason = REASON_PROGRAM); // Override Destroy method private: bool CreateButtons(void); bool CreateResultsPanel(void); void OnClickButtonClose(); // New close button handler void PerformHighLowAnalysis(void); void PerformVolumeAnalysis(void); void PerformTrendAnalysis(void); void PerformVolatilityAnalysis(void); void PerformMovingAverageAnalysis(void); void PerformSupportResistanceAnalysis(void); double CalculateMovingAverage(int period); }; CMetricsBoard::CMetricsBoard(void) {} CMetricsBoard::~CMetricsBoard(void) {} // Override Destroy method void CMetricsBoard::Destroy(const int reason) { // Call base class Destroy method to release resources CAppDialog::Destroy(reason); } //+------------------------------------------------------------------+ //| Create a control dialog | //+------------------------------------------------------------------+ bool CMetricsBoard::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) { if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) { Print("Failed to create CAppDialog instance."); return false; // Failed to create the dialog } if(!CreateResultsPanel()) { Print("Failed to create results panel."); return false; // Failed to create the results panel } if(!CreateButtons()) { Print("Failed to create buttons."); return false; // Failed to create buttons } Show(); // Show the dialog after creation return true; // Successfully created the dialog } //+------------------------------------------------------------------+ //| Minimize the control window | //+------------------------------------------------------------------+ void CMetricsBoard::Minimize() { CAppDialog::Minimize(); } //+------------------------------------------------------------------+ //| Run the control. | //+------------------------------------------------------------------+ bool CMetricsBoard::Run() { // Assuming Run makes the dialog functional if(!Show()) { Print("Failed to show the control."); return false; // Could not show the control } // Additional initialization or starting logic can be added here return true; // Successfully run the control } //+------------------------------------------------------------------+ //| Create the results panel | //+------------------------------------------------------------------+ bool CMetricsBoard::CreateResultsPanel(void) { if(!m_panelResults.Create(0, "ResultsPanel", 0, 10, 10, 330, 60)) return false; m_panelResults.Color(clrLightGray); Add(m_panelResults); if(!m_lblResults.Create(0, "ResultsLabel", 0, 15, 15, 315, 30)) return false; m_lblResults.Text("Results will be displayed here."); m_lblResults.Color(clrBlack); m_lblResults.FontSize(12); Add(m_lblResults); return true; } //+------------------------------------------------------------------+ //| Create buttons for the panel | //+------------------------------------------------------------------+ bool CMetricsBoard::CreateButtons(void) { int x = 20; int y = 80; int buttonWidth = 300; int buttonHeight = 30; int spacing = 15; // Create Close Button if(!m_btnClose.Create(0, "CloseButton", 0, x, y, x + buttonWidth, y + buttonHeight)) return false; m_btnClose.Text("Close Panel"); Add(m_btnClose); y += buttonHeight + spacing; struct ButtonData { CButton *button; string name; string text; }; ButtonData buttons[] = { {&m_btnHighLowAnalysis, "HighLowButton", "High/Low Analysis"}, {&m_btnVolumeAnalysis, "VolumeButton", "Volume Analysis"}, {&m_btnTrendAnalysis, "TrendButton", "Trend Analysis"}, {&m_btnVolatilityAnalysis, "VolatilityButton", "Volatility Analysis"}, {&m_btnMovingAverage, "MovingAverageButton", "Moving Average"}, {&m_btnSupportResistance, "SupportResistanceButton", "Support/Resistance"} }; for(int i = 0; i < ArraySize(buttons); i++) { if(!buttons[i].button.Create(0, buttons[i].name, 0, x, y, x + buttonWidth, y + buttonHeight)) return false; buttons[i].button.Text(buttons[i].text); Add(buttons[i].button); y += buttonHeight + spacing; } return true; } //+------------------------------------------------------------------+ //| Handle events for button clicks | //+------------------------------------------------------------------+ bool CMetricsBoard::OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { Print("Event ID: ", id, ", Event parameter (sparam): ", sparam); if(sparam == "CloseButton") // Handle close button click { OnClickButtonClose(); // Call to new close button handler return true; // Event processed } else if(sparam == "HighLowButton") { Print("High/Low Analysis Button Clicked"); m_lblResults.Text("Performing High/Low Analysis..."); PerformHighLowAnalysis(); return true; // Event processed } else if(sparam == "VolumeButton") { Print("Volume Analysis Button Clicked"); m_lblResults.Text("Performing Volume Analysis..."); PerformVolumeAnalysis(); return true; // Event processed } else if(sparam == "TrendButton") { Print("Trend Analysis Button Clicked"); m_lblResults.Text("Performing Trend Analysis..."); PerformTrendAnalysis(); return true; // Event processed } else if(sparam == "VolatilityButton") { Print("Volatility Analysis Button Clicked"); m_lblResults.Text("Performing Volatility Analysis..."); PerformVolatilityAnalysis(); return true; // Event processed } else if(sparam == "MovingAverageButton") { Print("Moving Average Analysis Button Clicked"); m_lblResults.Text("Calculating Moving Average..."); PerformMovingAverageAnalysis(); return true; // Event processed } else if(sparam == "SupportResistanceButton") { Print("Support/Resistance Analysis Button Clicked"); m_lblResults.Text("Calculating Support/Resistance..."); PerformSupportResistanceAnalysis(); return true; // Event processed } } return false; // If we reach here, the event was not processed } //+------------------------------------------------------------------+ //| Handle chart events | //+------------------------------------------------------------------+ bool CMetricsBoard::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { Print("ChartEvent ID: ", id, ", lparam: ", lparam, ", dparam: ", dparam, ", sparam: ", sparam); if(id == CHARTEVENT_OBJECT_CLICK) { return OnEvent(id, lparam, dparam, sparam); } return false; } //+------------------------------------------------------------------+ //| Analysis operations | //+------------------------------------------------------------------+ void CMetricsBoard::PerformHighLowAnalysis(void) { double high = iHigh(Symbol(), PERIOD_H1, 0); double low = iLow(Symbol(), PERIOD_H1, 0); Print("Retrieved High: ", high, ", Low: ", low); if(high == 0 || low == 0) { m_lblResults.Text("Failed to retrieve high/low values."); return; } string result = StringFormat("High: %.5f, Low: %.5f", high, low); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformVolumeAnalysis(void) { double volume = iVolume(Symbol(), PERIOD_H1, 0); Print("Retrieved Volume: ", volume); if(volume < 0) { m_lblResults.Text("Failed to retrieve volume."); return; } string result = StringFormat("Volume (Last Hour): %.1f", volume); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformTrendAnalysis(void) { double ma = CalculateMovingAverage(14); Print("Calculated 14-period MA: ", ma); if(ma <= 0) { m_lblResults.Text("Not enough data for moving average calculation."); return; } string result = StringFormat("14-period MA: %.5f", ma); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformVolatilityAnalysis(void) { int atr_period = 14; int atr_handle = iATR(Symbol(), PERIOD_H1, atr_period); if(atr_handle == INVALID_HANDLE) { m_lblResults.Text("Failed to get ATR handle."); return; } double atr_value[]; if(CopyBuffer(atr_handle, 0, 0, 1, atr_value) < 0) { m_lblResults.Text("Failed to copy ATR value."); IndicatorRelease(atr_handle); return; } string result = StringFormat("ATR (14): %.5f", atr_value[0]); m_lblResults.Text(result); IndicatorRelease(atr_handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformMovingAverageAnalysis(void) { double ma = CalculateMovingAverage(50); Print("Calculated 50-period MA: ", ma); if(ma <= 0) { m_lblResults.Text("Not enough data for moving average calculation."); return; } string result = StringFormat("50-period MA: %.5f", ma); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMetricsBoard::PerformSupportResistanceAnalysis(void) { double support = iLow(Symbol(), PERIOD_H1, 1); double resistance = iHigh(Symbol(), PERIOD_H1, 1); Print("Retrieved Support: ", support, ", Resistance: ", resistance); if(support == 0 || resistance == 0) { m_lblResults.Text("Failed to retrieve support/resistance levels."); return; } string result = StringFormat("Support: %.5f, Resistance: %.5f", support, resistance); m_lblResults.Text(result); } //+------------------------------------------------------------------+ //| Calculate moving average | //+------------------------------------------------------------------+ double CMetricsBoard::CalculateMovingAverage(int period) { if(period <= 0) return 0; double sum = 0.0; int bars = Bars(Symbol(), PERIOD_H1); if(bars < period) { return 0; } for(int i = 0; i < period; i++) { sum += iClose(Symbol(), PERIOD_H1, i); } return sum / period; } // Implementation of OnClickButtonClose void CMetricsBoard::OnClickButtonClose() { Print("Close button clicked. Closing the Metrics Board..."); Destroy(); // This method destroys the panel } CMetricsBoard ExtDialog; //+------------------------------------------------------------------+ //| Initialize the application | //+------------------------------------------------------------------+ int OnInit() { if(!ExtDialog.Create(0, "Metrics Board", 0, 10, 10, 350, 500)) { Print("Failed to create Metrics Board."); return INIT_FAILED; } if(!ExtDialog.Run()) // Call Run to make the dialog functional { Print("Failed to run Metrics Board."); return INIT_FAILED; // Call to Run failed } return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Deinitialize the application | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ExtDialog.Destroy(reason); // Properly call Destroy method } //+------------------------------------------------------------------+ //| Handle chart events | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { ExtDialog.ChartEvent(id, lparam, dparam, sparam); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+
Desglose e implementación del código
- Encabezado y metadatos
//+------------------------------------------------------------------+ //| Metrics Board.mql5| //| Copyright 2025, Christian Benjamin| //| https://www.mql5.com| //+------------------------------------------------------------------+ #property copyright "2025, MetaQuotes Software Corp." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strictEl bloque de comentarios describe el propósito del script y proporciona los créditos, lo cual es esencial para identificar la autoría y garantizar la atribución adecuada para los futuros usuarios. Las directivas #property sirven para definir diversas características del script, como la información sobre derechos de autor, un enlace al autor o a la documentación, el número de versión y la configuración del modo estricto, que ayuda a detectar posibles problemas durante la compilación.
- Incluir las librerías necesarias
A continuación, incluimos las bibliotecas necesarias para nuestra aplicación. Estas librerías proporcionan funcionalidades predefinidas que simplifican la codificación.
#include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Label.mqh> #include <Controls\Panel.mqh>
Aquí incorporamos las librerías relacionadas con las operaciones comerciales y los controles de la interfaz de usuario. Por ejemplo, Trade.mqh es fundamental para ejecutar funciones comerciales, mientras que Dialog.mqh, Button.mqh, Label.mqh, y Panel.mqh se utilizan para crear y gestionar los componentes de la interfaz de usuario del panel de métricas.
- Definición de clase
class CMetricsBoard : public CAppDialog { private: CButton m_btnClose; CButton m_btnHighLowAnalysis; CButton m_btnVolumeAnalysis; CButton m_btnTrendAnalysis; CButton m_btnVolatilityAnalysis; CButton m_btnMovingAverage; CButton m_btnSupportResistance; CPanel m_panelResults; CLabel m_lblResults;
La clase también incluye un constructor y un destructor.
public: CMetricsBoard(void); ~CMetricsBoard(void); CMetricsBoard::CMetricsBoard(void) {} CMetricsBoard::~CMetricsBoard(void) {}
El constructor inicializa la clase y el destructor se define (aunque en este caso está vacío) para garantizar que se realice cualquier limpieza necesaria cuando se destruya una instancia de CMetricsBoard . Esto es esencial para gestionar los recursos de manera eficiente.
- Creación del cuadro de diálogo
El método Create se encarga de construir todo el cuadro de diálogo de control. En este método, primero intentamos crear el cuadro de diálogo a través de la clase base (CAppDialog::Create). Si falla, registramos un error y devolvemos falso. A continuación, creamos un panel de resultados y botones, comprobando de nuevo si hay posibles fallos. Por último, si todos los pasos se han realizado correctamente, mostramos el cuadro de diálogo y devolvemos verdadero.
bool CMetricsBoard::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) { if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) { Print("Failed to create CAppDialog instance."); return false; } if(!CreateResultsPanel()) { Print("Failed to create results panel."); return false; } if(!CreateButtons()) { Print("Failed to create buttons."); return false; } Show(); return true; }
Ahora aparece el cuadro de diálogo Run. El método Run es esencial para que el cuadro de diálogo funcione.
bool CMetricsBoard::Run() { if(!Show()) { Print("Failed to show the control."); return false; } return true; }
Aquí, mostramos el cuadro de diálogo utilizando el método Show. Si falla la visualización del cuadro de diálogo, se muestra un mensaje de error y se devuelve false.
- Creación del panel de resultados
El método CreateResultsPanel construye el panel donde se mostrarán los resultados del análisis. Inicialmente, creamos el panel de resultados y establecemos sus propiedades, como el color y las dimensiones. A continuación, añadimos este panel al cuadro de diálogo. También creamos una etiqueta dentro del panel para mostrar los resultados y personalizamos su apariencia antes de añadirla al panel. Este método devuelve verdadero si la creación se ha realizado correctamente.
bool CMetricsBoard::CreateResultsPanel(void) { if(!m_panelResults.Create(0, "ResultsPanel", 0, 10, 10, 330, 60)) return false; m_panelResults.Color(clrLightGray); Add(m_panelResults); if(!m_lblResults.Create(0, "ResultsLabel", 0, 15, 15, 315, 30)) return false; m_lblResults.Text("Results will be displayed here."); m_lblResults.Color(clrBlack); m_lblResults.FontSize(12); Add(m_lblResults); return true; }
- Creación de botones
El método CreateButtons se encarga de inicializar los botones interactivos del cuadro de diálogo.
bool CMetricsBoard::CreateButtons(void) { int x = 20; int y = 80; int buttonWidth = 300; int buttonHeight = 30; int spacing = 15; if(!m_btnClose.Create(0, "CloseButton", 0, x, y, x + buttonWidth, y + buttonHeight)) return false; m_btnClose.Text("Close Panel"); Add(m_btnClose); y += buttonHeight + spacing; struct ButtonData { CButton *button; string name; string text; }; ButtonData buttons[] = { {&m_btnHighLowAnalysis, "HighLowButton", "High/Low Analysis"}, {&m_btnVolumeAnalysis, "VolumeButton", "Volume Analysis"}, {&m_btnTrendAnalysis, "TrendButton", "Trend Analysis"}, {&m_btnVolatilityAnalysis, "VolatilityButton", "Volatility Analysis"}, {&m_btnMovingAverage, "MovingAverageButton", "Moving Average"}, {&m_btnSupportResistance, "SupportResistanceButton", "Support/Resistance"} }; for(int i = 0; i < ArraySize(buttons); i++) { if(!buttons[i].button.Create(0, buttons[i].name, 0, x, y, x + buttonWidth, y + buttonHeight)) return false; buttons[i].button.Text(buttons[i].text); Add(buttons[i].button); y += buttonHeight + spacing; } return true; }
En esta implementación, definimos las coordenadas iniciales, las dimensiones y el espaciado de nuestros botones. Creamos cada botón, primero para cerrar el panel, añadiéndolo al cuadro de diálogo. A continuación, utilizamos una matriz de estructuras ButtonData, lo que nos permite recorrer eficazmente las definiciones de los botones. Cada botón se configura con el texto correspondiente y se añade al cuadro de diálogo. El método concluye devolviendo verdadero si todos los botones se han creado correctamente.
- Gestión de eventos
1. Clics en botones
El método OnEvent procesa los eventos generados por la interacción del usuario, como los clics en botones.
bool CMetricsBoard::OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) { Print("Event ID: ", id, ", Event parameter (sparam): ", sparam); if(sparam == "CloseButton") { OnClickButtonClose(); return true; } // ... Handling for other button clicks } return false; }
Cuando se produce un evento, primero comprobamos si se trata de un evento de clic en un botón. Imprimimos los detalles del evento con fines de depuración y reaccionamos a clics específicos en botones llamando a las funciones de manejo correspondientes. Imprimimos los detalles del evento con fines de depuración y reaccionamos a clics específicos en botones llamando a las funciones de manejo correspondientes.
2. Eventos gráficos
El método ChartEvent tiene una finalidad similar, pero se centra específicamente en los eventos relacionados con los gráficos.
bool CMetricsBoard::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { Print("ChartEvent ID: ", id, ", lparam: ", lparam, ", dparam: ", dparam, ", sparam: ", sparam); if(id == CHARTEVENT_OBJECT_CLICK) { return OnEvent(id, lparam, dparam, sparam); } return false; }
Este método captura cualquier clic en los objetos del gráfico y pasa el evento al método OnEvent para su posterior procesamiento.
- Operaciones de análisis
Los siguientes métodos implementan los distintos tipos de análisis de mercado que puede realizar nuestro Panel de métricas. Por ejemplo, PerformHighLowAnalysis recupera los precios máximos y mínimos para un período definido:
void CMetricsBoard::PerformHighLowAnalysis(void) { double high = iHigh(Symbol(), PERIOD_H1, 0); double low = iLow(Symbol(), PERIOD_H1, 0); Print("Retrieved High: ", high, ", Low: ", low); if(high == 0 || low == 0) { m_lblResults.Text("Failed to retrieve high/low values."); return; } string result = StringFormat("High: %.5f, Low: %.5f", high, low); m_lblResults.Text(result); }
En este método, utilizamos funciones integradas para recuperar los precios más altos y más bajos de la última hora. Si se realiza correctamente, los resultados se muestran en la etiqueta. Si no es así, se muestra un mensaje de error.
Se aplica una lógica similar a otras funciones de análisis, como PerformVolumeAnalysis, PerformTrendAnalysis, PerformVolatilityAnalysis, PerformMovingAverageAnalysis y PerformSupportResistanceAnalysis. Cada método recupera datos específicos para su tipo de análisis y actualiza la interfaz de usuario en consecuencia.
- Calcular la media móvil
Uno de los métodos de utilidad incluidos es CalculateMovingAverage, que calcula la media móvil durante un período determinado. Este método suma los precios de cierre durante el período especificado y los divide entre ese número para determinar la media. Comprueba que la entrada sea válida y que haya datos suficientes antes de realizar el cálculo.
double CMetricsBoard::CalculateMovingAverage(int period) { if(period <= 0) return 0; double sum = 0.0; int bars = Bars(Symbol(), PERIOD_H1); if(bars < period) { return 0; } for(int i = 0; i < period; i++) { sum += iClose(Symbol(), PERIOD_H1, i); } return sum / period; }
- Comprueba que la entrada sea válida y que haya datos suficientes antes de realizar el cálculo.
Comprueba que la entrada sea válida y que haya datos suficientes antes de realizar el cálculo.
CMetricsBoard ExtDialog; int OnInit() { if(!ExtDialog.Create(0, "Metrics Board", 0, 10, 10, 350, 500)) { Print("Failed to create Metrics Board."); return INIT_FAILED; } if(!ExtDialog.Run()) { Print("Failed to run Metrics Board."); return INIT_FAILED; } return INIT_SUCCEEDED; }
En la función OnInit, inicializamos el panel de métricas llamando al método Create. Si tiene éxito, procedemos a ejecutarlo. Los errores se registran según corresponda, con la función indicando el éxito o el fracaso.
El proceso de desinicialización garantiza que los recursos se liberen correctamente cuando se elimina el EA.
void OnDeinit(const int reason) { ExtDialog.Destroy(reason); // Properly call Destroy method }
- Gestión de eventos de gráficos
Por último, definimos la función OnChartEvent para gestionar los eventos relacionados con los gráficos. Esto integra las interacciones del usuario directamente en la funcionalidad de la aplicación. Este método captura los eventos del gráfico y los pasa al método ChartEvent de nuestra instancia CMetricsBoard .
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { ExtDialog.ChartEvent(id, lparam, dparam, sparam); }
Incluyendo librerías
Si compila su código sin incluir las librerías mencionadas en la sección anterior, es posible que encuentre errores. Para resolver esto, abra MetaEditor y vaya al panel Navegador. Desplácese hacia abajo hasta la sección «Include», donde podrá acceder a las librerías necesarias. Abra las subcarpetas necesarias, seleccione los archivos pertinentes y compílelos individualmente. Asegúrate de que las librerías estén correctamente referenciadas en tu código utilizando la directiva #include al principio de tu script. Este paso garantiza que todas las dependencias se carguen correctamente, evitando posibles errores de compilación. El siguiente GIF ilustra cómo acceder e incluir librerías en MetaEditor.

Figura 2. Incluyendo librerías
En MQL5, una librería de inclusión le permite integrar código externo, funciones o clases en su programa, mejorando su funcionalidad y permitiendo la reutilización de código de diversas fuentes. Al incluir una librería, obtienes acceso a las funciones, clases o variables definidas en ella, lo que las hace disponibles para su uso en tu script, asesor experto o indicador. La mayoría de las librerías de MQL5 están integradas y proporcionan soluciones listas para usar para tareas comunes, como funciones de trading, indicadores técnicos y mucho más.
Resultados
Después de compilar correctamente el EA, ahora puede ir a MetaTrader 5 y adjuntar el EA a un gráfico. Repasemos los resultados que obtuvimos durante las pruebas.

Figura 3. Resultados
De acuerdo con el diagrama anterior, es evidente que el EA del panel de métricas ofrece una funcionalidad óptima, respondiendo eficazmente a cada pulsación de botón. Esta capacidad garantiza que el EA proporcione las métricas necesarias en tiempo real, mejorando la interacción del usuario y el rendimiento.
- Registro del EA
También podemos revisar el registro de Expertos en MetaTrader 5 para observar la interacción entre los botones pulsados y los eventos en el gráfico. Dado que nuestro EA incluye una función de registro integrada, capturará estas interacciones. Echemos un vistazo a la información registrada y analicemos lo que se ha registrado.

Figura 4. Registro de expertos
Conclusión
El Metrics Board EA cuenta con una interfaz de panel dinámica y fácil de usar integrada directamente en MetaTrader 5, que incorpora la función de dibujo de objetos. Su integración fluida da la impresión de trabajar con controles nativos de MetaTrader 5, ofreciendo una experiencia comparable a usar una aplicación incorporada. En mi opinión, marca un avance significativo en las herramientas comerciales, ofreciendo funcionalidad y facilidad de uso que superan las capacidades de algunos scripts de análisis que desarrollé anteriormente. Al permitir a los usuarios centrarse en información específica con un solo clic, se garantiza que solo se muestren los datos necesarios, agilizando el proceso de análisis. Si bien esos scripts anteriores cumplieron eficazmente sus propósitos, Metrics Board EA lleva el análisis de mercado a un nivel superior de eficiencia y accesibilidad.
Las características principales de Metrics Board EA incluyen:
| Característica | Ventaja |
|---|---|
| Análisis alto/bajo | Identifica rápidamente niveles de mercado significativos para ayudar a los comerciantes. |
| Seguimiento del volumen | Proporciona actualizaciones actualizadas sobre el volumen comercial para un mejor contexto del mercado. |
| Identificación de tendencias | Simplifica el proceso de reconocimiento de las tendencias actuales del mercado. |
| Niveles de soporte/resistencia | Identifica con precisión zonas de precios cruciales para el trading estratégico. |
Esta herramienta permite a los operadores analizar los mercados de forma eficaz y tomar mejores decisiones. Su diseño sencillo simplifica los análisis complejos, lo que permite a los usuarios centrarse en perfeccionar sus estrategias. De cara al futuro, existe la posibilidad de ampliar sus capacidades añadiendo nuevas funciones y mejorando aún más la interfaz.
| Fecha | Nombre de la herramienta | Descripción | Versión | Actualizaciones | Notas |
|---|---|---|---|---|---|
| 01/10/24 | Chart Projector | Script para superponer la acción del precio del día anterior con efecto fantasma. | 1.0 | Lanzamiento inicial | Primera herramienta en Lynnchris Tool Chest |
| 18/11/24 | Analytical Comment | Proporciona información del día anterior en formato tabular y anticipa la dirección futura del mercado. | 1.0 | Lanzamiento inicial | Segunda herramienta en Lynnchris Tool Chest |
| 27/11/24 | Analytics Master | Actualización periódica de los indicadores del mercado cada dos horas. | 1.01 | Segundo lanzamiento | Tercera herramienta en Lynnchris Tool Chest |
| 02/12/24 | Analytics Forecaster | Actualización periódica de los indicadores del mercado cada dos horas con integración de Telegram. | 1.1 | Tercera edición | Herramienta número 4 |
| 09/12/24 | Volatility Navigator | EA que analiza las condiciones del mercado utilizando los indicadores Bandas de Bollinger, RSI y ATR. | 1.0 | Lanzamiento inicial | Herramienta número 5 |
| 19/12/24 | Mean Reversion Signal Reaper | Analiza el mercado utilizando la estrategia de reversión a la media y proporciona señales. | 1.0 | Lanzamiento inicial | Herramienta número 6 |
| 09/01/25 | Signal Pulse | Analizador de múltiples marcos temporales. | 1.0 | Lanzamiento inicial | Herramienta número 7 |
| 17/01/25 | Metrics Board | Panel con botón para análisis. | 1.0 | Lanzamiento inicial | Herramienta número 8 |
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/16584
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.
Simulación de mercado (Parte 05): Creación de la clase C_Orders (II)
Algoritmo de búsqueda circular — Circle Search Algorithm (CSA)
Simulación de mercado (Parte 06): Transfiriendo información desde MetaTrader 5 hacia Excel
Cómo publicar código en CodeBase: Guía práctica
- 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