
Operar con el Calendario Económico MQL5 (Parte 3): Añadiendo filtros de divisa, importancia y tiempo
Introducción
En este artículo, nos basamos en nuestro trabajo anterior sobre el calendario económico MetaQuotes Language 5 (MQL5), en el que desarrollamos un panel de control de noticias para mostrar eventos económicos en tiempo real. Ahora, mejoraremos este panel de control implementando filtros específicos para la divisa, la importancia y el tiempo, lo que permitirá a los operadores centrarse únicamente en las noticias más relevantes para sus estrategias. Estos filtros proporcionarán una visión específica de los acontecimientos que influyen en el mercado, lo que ayudará a agilizar la toma de decisiones y a mejorar la eficiencia de las operaciones bursátiles. Los temas que trataremos incluyen:
- Introducción
- Comprender los tipos de filtros en los calendarios económicos
- Implementación de los filtros en MQL5
- Conclusión
Con estas incorporaciones, nuestro panel de control se convertirá en una potente herramienta para supervisar y filtrar las noticias económicas dentro del entorno MQL5, adaptada a las necesidades de los operadores de obtener información oportuna y relevante.
Comprender los tipos de filtros en los calendarios económicos
Para perfeccionar la funcionalidad de nuestro panel de control, debemos comprender el propósito y las ventajas de cada tipo de filtro: moneda, importancia y tiempo. El filtro de divisas nos permite ver los acontecimientos económicos que afectan específicamente a las divisas con las que operamos, lo que facilita la identificación de acontecimientos relevantes que podrían afectar a nuestras posiciones abiertas. Este filtro ayuda a optimizar el panel de control al reducir la sobrecarga de información, centrándose únicamente en las divisas de nuestra cartera de operaciones. En la terminal de operaciones MetaTrader 5, podemos acceder y filtrar las noticias según la divisa pasando el cursor por la pestaña Calendario, haciendo clic con el botón derecho dentro de ella y seleccionando la divisa o el país que prefiera. Aquí hay una ilustración.
El filtro de importancia clasifica los eventos en función de su impacto previsto, que suele definirse como de importancia baja, media o alta. Los acontecimientos de gran repercusión, como los anuncios de los bancos centrales o las cifras de desempleo, pueden provocar volatilidad en los mercados. Al filtrar en función de la importancia, podemos evaluar rápidamente qué eventos podrían tener un impacto más significativo en nuestras decisiones comerciales, lo que mejora la capacidad de respuesta. Para filtrar las noticias según el nivel de impacto, puede volver a hacer clic con el botón derecho del ratón en la pestaña Calendario y seleccionar según la prioridad. Aquí hay una ilustración.
Por último, el filtro temporal nos permite especificar el intervalo de tiempo para los eventos económicos relevantes, lo que resulta especialmente útil para quienes operan en sesiones específicas o se preparan para noticias próximas. Con este filtro, podemos ver los eventos que ocurren dentro de un período definido, como la próxima hora, día o semana, lo que proporciona una línea de tiempo que se alinea con nuestras estrategias comerciales y preferencias de tiempo. En conjunto, estos filtros crean una experiencia personalizable que adapta los datos de noticias económicas a las necesidades comerciales individuales, formando la columna vertebral de un panel de control MQL5 receptivo y eficiente.
Implementación de los filtros en MQL5
Para implementar los filtros en MQL5, el primer paso que debemos dar es definir las variables booleanas en un ámbito global. Estas variables controlarán si los filtros de moneda, importancia y tiempo están habilitados o deshabilitados. Al definirlos globalmente, nos aseguraremos de que se pueda acceder a los filtros y modificarlos en todo el código, lo que proporcionará flexibilidad en el funcionamiento del panel de noticias. Este paso sentará las bases para implementar la lógica del filtro y nos permitirá adaptar la funcionalidad del panel de control a nuestras necesidades comerciales. Para lograrlo, esta es la lógica que utilizamos.
//--- Define flags to enable/disable filters bool enableCurrencyFilter = true; // Set to 'true' to enable currency filter, 'false' to disable bool enableImportanceFilter = true; // Set to 'true' to enable importance filter, 'false' to disable bool enableTimeFilter = true; // Set to 'true' to enable time filter, 'false' to disable
Aquí definimos tres variables booleanas, a saber, «enableCurrencyFilter», «enableImportanceFilter» y «enableTimeFilter», que utilizaremos para controlar si los filtros respectivos para la moneda, la importancia y el tiempo están habilitados o deshabilitados. Cada variable se establece en un valor predeterminado de «verdadero», lo que significa que, por defecto, todos los filtros estarán activos. Al cambiar estos valores a «false», podemos desactivar cualquiera de los filtros que no deseemos utilizar, lo que nos permite personalizar la funcionalidad del panel de noticias en función de nuestras preferencias de negociación.
A partir de aquí, en la lógica de inicialización al contar los eventos de noticias válidos, comenzaremos con el filtro de moneda. En primer lugar, debemos definir los códigos de moneda a los que deseamos aplicar el filtro. Por lo tanto, los definiremos como se indica a continuación.
string curr_filter[] = {"AUD","CAD","CHF","EUR","GBP","JPY","NZD","USD"}; int news_filter_count = 0;
Aquí definimos la matriz «string» «curr_filter», que contiene una lista de pares de divisas («AUD», «CAD», «CHF», «EUR», «GBP», «JPY», «NZD» y «USD») que queremos utilizar para filtrar las noticias en función de divisas específicas. Esta matriz nos ayudará a reducir los eventos de noticias que se muestran en el panel de control, centrándonos solo en aquellos que son relevantes para las divisas seleccionadas. También definimos la variable «news_filter_count», que utilizamos para realizar un seguimiento del número de noticias filtradas que coinciden con nuestros criterios seleccionados, lo que garantiza que solo se muestre la información más pertinente. A continuación, podemos pasar a la lógica del filtro como se muestra a continuación.
//--- Check if the event’s currency matches any in the filter array (if the filter is enabled) bool currencyMatch = false; if (enableCurrencyFilter) { for (int j = 0; j < ArraySize(curr_filter); j++) { if (country.currency == curr_filter[j]) { currencyMatch = true; break; } } //--- If no match found, skip to the next event if (!currencyMatch) { continue; } }
Aquí, comprobamos si la moneda del evento coincide con alguna moneda de la matriz «curr_filter», pero solo si el filtro de moneda está habilitado, tal y como indica el indicador «enableCurrencyFilter». Si el filtro está habilitado, recorremos el array «curr_filter» utilizando un bucle for y, en cada iteración, comparamos la moneda del evento con las monedas del filtro.
Si se encuentra una coincidencia, establecemos el indicador «currencyMatch» en verdadero y salimos del bucle. Si no se encuentra ninguna coincidencia (lo que significa que «currencyMatch» sigue siendo falso), utilizamos la instrucción continue para omitir el evento actual y pasar al siguiente, asegurándonos de que solo se procesen los eventos relevantes. A continuación, utilizamos la misma lógica para filtrar los eventos en función de su importancia.
//--- Check importance level if importance filter is enabled bool importanceMatch = false; if (enableImportanceFilter) { for (int k = 0; k < ArraySize(allowed_importance_levels); k++) { if (event.importance == allowed_importance_levels[k]) { importanceMatch = true; break; } } //--- If importance does not match the filter criteria, skip the event if (!importanceMatch) { continue; } }
Aquí, comprobamos el nivel de importancia del evento con respecto a la matriz predefinida «allowed_importance_levels», pero solo si el filtro de importancia está habilitado, tal y como indica el indicador «enableImportanceFilter». Si el filtro está habilitado, recorremos el array «allowed_importance_levels» utilizando un bucle for, comparando la importancia del evento con los niveles del array.
Si se encuentra una coincidencia, establecemos el indicador «importanceMatch» en verdadero y salimos del bucle. Si no se encuentra ninguna coincidencia (lo que significa que «importanceMatch» sigue siendo falso), utilizamos la instrucción continue para omitir el evento actual, asegurándonos de que solo se procesen los eventos con el nivel de importancia deseado. Utilizamos otra matriz para definir los niveles de importancia de la siguiente manera:
// Define the levels of importance to filter (low, moderate, high) ENUM_CALENDAR_EVENT_IMPORTANCE allowed_importance_levels[] = {CALENDAR_IMPORTANCE_LOW, CALENDAR_IMPORTANCE_MODERATE, CALENDAR_IMPORTANCE_HIGH};
Aquí hemos añadido todos los niveles de importancia, lo que significa que, técnicamente, permitimos todas las noticias en función de su prioridad, pero usted puede elegir las que mejor se adapten a sus decisiones comerciales. A continuación, debemos definir los rangos del filtro temporal.
//--- Define time range for filtering news events based on daily period datetime timeRange = PeriodSeconds(PERIOD_D1); datetime timeBefore = TimeTradeServer() - timeRange; datetime timeAfter = TimeTradeServer() + timeRange;
Definimos un intervalo de tiempo para filtrar las noticias basándonos en el periodo diario. Utilizamos la función PeriodSeconds con la constante PERIOD_D1 para determinar el número de segundos que hay en un día, que luego asignamos a la variable «timeRange» datetime. Las variables «timeBefore» y «timeAfter» se configuran para calcular el intervalo de tiempo alrededor de la hora actual del servidor, obtenida mediante la función TimeTradeServer, restando y sumando «timeRange» respectivamente. Esto garantiza que solo se tengan en cuenta para su procesamiento los eventos que se encuentren dentro del intervalo de tiempo especificado (un día antes o después de la hora actual del servidor). Asegúrese de ajustarlo según sus necesidades. Armados con esta lógica, podemos entonces aplicar el filtro temporal.
//--- Apply time filter and set timeMatch flag (if the filter is enabled) bool timeMatch = false; if (enableTimeFilter) { datetime eventTime = values[i].time; if (eventTime <= TimeTradeServer() && eventTime >= timeBefore) { timeMatch = true; //--- Event is already released } else if (eventTime >= TimeTradeServer() && eventTime <= timeAfter) { timeMatch = true; //--- Event is yet to be released } //--- Skip if the event doesn't match the time filter if (!timeMatch) { continue; } }
Aquí, aplicamos el filtro de tiempo comprobando si la hora del evento se encuentra dentro del intervalo de tiempo especificado, y utilizamos el indicador «timeMatch» para rastrear si el evento cumple los criterios. Si «enableTimeFilter» es verdadero, primero recuperamos la hora del evento de la variable «values[i].time». A continuación, comprobamos si la hora del evento es pasada (entre la hora actual del servidor y «timeBefore») o futura (entre la hora actual del servidor y «timeAfter»). Si la hora del evento se encuentra dentro de cualquiera de los dos rangos, el indicador «timeMatch» se establece en verdadero, lo que indica que el evento coincide con el filtro de tiempo. Si no se encuentra ninguna coincidencia, omitimos el evento utilizando la instrucción continue.
Eso es todo en cuanto a los filtros. Si llegamos hasta aquí, significa que hemos superado todas las pruebas y tenemos algunas noticias. Por lo tanto, actualizamos el recuento del filtro de noticias en uno.
//--- If we reach here, the currency matches the filter news_filter_count++; //--- Increment the count of filtered events
Ahora utilizamos los datos del recuento del filtro de noticias para crear las secciones del contenedor de datos, ya que en esta ocasión no estamos teniendo en cuenta todos los eventos seleccionados. Esto garantiza que creamos solo los soportes de datos que nos resultan relevantes en el panel de control.
//--- Set alternating colors for each data row holder color holder_color = (news_filter_count % 2 == 0) ? C'213,227,207' : clrWhite; //--- Create rectangle label for each data row holder createRecLabel(DATA_HOLDERS+string(news_filter_count),62,startY-1,716,26+1,holder_color,1,clrNONE);
Aquí, establecemos colores alternos para cada fila de datos con el fin de mejorar la distinción visual entre las filas. El «holder_color» se determina utilizando un operador ternario, donde si el «news_filter_count» es par (es decir, «news_filter_count % 2 == 0»), el color se establece en un tono verde claro (C'213,227,207'), y si es impar, el color se establece en blanco. Esto garantiza que cada fila alterne de color, lo que facilita la lectura de los datos.
A continuación, creamos una etiqueta rectangular para cada contenedor de filas de datos utilizando la función «createRecLabel», que coloca un rectángulo de color en las coordenadas especificadas. La etiqueta se identifica de forma única combinando «DATA_HOLDERS» con la representación de cadena de «news_filter_count» para garantizar que cada fila tenga un nombre único, y las dimensiones del rectángulo se ajustan para adaptarse al contenido. El borde del rectángulo se establece con un grosor de 1, mientras que el color de relleno se establece en «holder_color» alternativo y el color del borde se establece en «clrNONE» para que no haya color de borde.
Sin embargo, observe que hemos añadido 1 píxel al desplazamiento y de los soportes, como se destaca en color amarillo, para eliminar los bordes. Aquí está el resultado de la comparación.
Antes de añadir 1 píxel:
Después de añadir 1 píxel:
Fue todo un éxito. Lo siguiente que debemos hacer es actualizar el total de noticias que se muestra en el panel de control cuando se aplican los filtros.
updateLabel(TIME_LABEL,"Server Time: "+TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS)+" ||| Total News: "+ IntegerToString(news_filter_count)+"/"+IntegerToString(allValues));
Aquí utilizamos la función «updateLabel» para actualizar la etiqueta que muestra la hora actual del servidor y el número total de noticias filtradas. Actualizamos la etiqueta identificada como «TIME_LABEL» con una nueva cadena que combina la hora actual del servidor y el recuento de noticias. Para obtener la hora actual del servidor, utilizamos la función TimeCurrent y la formateamos con la función TimeToString con los indicadores «TIME_DATE | TIME_SECONDS».
A continuación, mostramos el número total de noticias filtradas, almacenadas en «news_filter_count», junto con el número total de noticias disponibles, representadas por «allValues». Al actualizar esta etiqueta, proporcionamos información en tiempo real tanto sobre la hora del servidor como sobre el estado del filtro de noticias, lo que nos ayuda a estar al tanto de las noticias actuales del mercado que son importantes para nosotros.
El fragmento de código de la función personalizada que utilizamos para actualizar la etiqueta es el siguiente.
//+------------------------------------------------------------------+ //| Function to create text label | //+------------------------------------------------------------------+ bool updateLabel(string objName,string txt) { // Reset any previous errors ResetLastError(); if (!ObjectSetString(0,objName,OBJPROP_TEXT,txt)) { Print(__FUNCTION__, ": failed to update the label! Error code = ", _LastError); return (false); } ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the label // Redraw the chart to display the label ChartRedraw(0); return (true); // Label creation successful }
Aquí definimos la función «updateLabel», que utilizamos para actualizar una etiqueta existente en el gráfico. La función toma dos parámetros: «objName» (el nombre del objeto etiqueta) y «txt» (el texto que se mostrará en la etiqueta). Comenzamos restableciendo cualquier error anterior utilizando la función ResetLastError para garantizar un reinicio completo. A continuación, intentamos actualizar el texto de la etiqueta con la cadena proporcionada «txt» utilizando la función ObjectSetString. Si la actualización falla, imprimimos un mensaje de error utilizando la función Print junto con el código de error recuperado de _LastError y devolvemos «false».
Si la actualización de la etiqueta se realiza correctamente, llamamos a la función ChartRedraw para actualizar el gráfico y mostrar la etiqueta actualizada y, por último, devolvemos «true» para indicar que la operación se ha realizado correctamente. Esta es la función que nos permite actualizar dinámicamente el contenido de las etiquetas del gráfico, proporcionando un método flexible para mostrar información como la hora del servidor o el recuento de noticias. Al ejecutar el programa, esto es lo que obtenemos.
Con la implementación, ahora estamos seguros de que solo tenemos en cuenta las noticias que nos interesan e ignoramos las demás. También mostramos el total de noticias aprobadas de entre todas las noticias seleccionadas, mostrando tanto los eventos de noticias disponibles como los considerados. El fragmento de código de inicialización completo responsable de la aplicación de los filtros es el siguiente.
string curr_filter[] = {"AUD","CAD","CHF","EUR","GBP","JPY","NZD","USD"}; int news_filter_count = 0; // Define the levels of importance to filter (low, moderate, high) ENUM_CALENDAR_EVENT_IMPORTANCE allowed_importance_levels[] = {CALENDAR_IMPORTANCE_LOW, CALENDAR_IMPORTANCE_MODERATE, CALENDAR_IMPORTANCE_HIGH}; //--- Loop through each calendar value up to the maximum defined total for (int i = 0; i < valuesTotal; i++){ MqlCalendarEvent event; //--- Declare event structure CalendarEventById(values[i].event_id,event); //--- Retrieve event details by ID MqlCalendarCountry country; //--- Declare country structure CalendarCountryById(event.country_id,country); //--- Retrieve country details by event's country ID MqlCalendarValue value; //--- Declare calendar value structure CalendarValueById(values[i].id,value); //--- Retrieve actual, forecast, and previous values //--- Check if the event’s currency matches any in the filter array (if the filter is enabled) bool currencyMatch = false; if (enableCurrencyFilter) { for (int j = 0; j < ArraySize(curr_filter); j++) { if (country.currency == curr_filter[j]) { currencyMatch = true; break; } } //--- If no match found, skip to the next event if (!currencyMatch) { continue; } } //--- Check importance level if importance filter is enabled bool importanceMatch = false; if (enableImportanceFilter) { for (int k = 0; k < ArraySize(allowed_importance_levels); k++) { if (event.importance == allowed_importance_levels[k]) { importanceMatch = true; break; } } //--- If importance does not match the filter criteria, skip the event if (!importanceMatch) { continue; } } //--- Apply time filter and set timeMatch flag (if the filter is enabled) bool timeMatch = false; if (enableTimeFilter) { datetime eventTime = values[i].time; if (eventTime <= TimeTradeServer() && eventTime >= timeBefore) { timeMatch = true; //--- Event is already released } else if (eventTime >= TimeTradeServer() && eventTime <= timeAfter) { timeMatch = true; //--- Event is yet to be released } //--- Skip if the event doesn't match the time filter if (!timeMatch) { continue; } } //--- If we reach here, the currency matches the filter news_filter_count++; //--- Increment the count of filtered events //--- Set alternating colors for each data row holder color holder_color = (news_filter_count % 2 == 0) ? C'213,227,207' : clrWhite; //--- Create rectangle label for each data row holder createRecLabel(DATA_HOLDERS+string(news_filter_count),62,startY-1,716,26+1,holder_color,1,clrNONE); //--- Initialize starting x-coordinate for each data entry int startX = 65; //--- Loop through calendar data columns for (int k=0; k<ArraySize(array_calendar); k++){ //--- Print event details for debugging //Print("Name = ",event.name,", IMP = ",EnumToString(event.importance),", COUNTRY = ",country.name,", TIME = ",values[i].time); //--- Skip event if currency does not match the selected country code // if (StringFind(_Symbol,country.currency) < 0) continue; //--- Prepare news data array with time, country, and other event details string news_data[ArraySize(array_calendar)]; news_data[0] = TimeToString(values[i].time,TIME_DATE); //--- Event date news_data[1] = TimeToString(values[i].time,TIME_MINUTES); //--- Event time news_data[2] = country.currency; //--- Event country currency //--- Determine importance color based on event impact color importance_color = clrBlack; if (event.importance == CALENDAR_IMPORTANCE_LOW){importance_color=clrYellow;} else if (event.importance == CALENDAR_IMPORTANCE_MODERATE){importance_color=clrOrange;} else if (event.importance == CALENDAR_IMPORTANCE_HIGH){importance_color=clrRed;} //--- Set importance symbol for the event news_data[3] = ShortToString(0x25CF); //--- Set event name in the data array news_data[4] = event.name; //--- Populate actual, forecast, and previous values in the news data array news_data[5] = DoubleToString(value.GetActualValue(),3); news_data[6] = DoubleToString(value.GetForecastValue(),3); news_data[7] = DoubleToString(value.GetPreviousValue(),3); //--- Create label for each news data item if (k == 3){ createLabel(ARRAY_NEWS+IntegerToString(i)+" "+array_calendar[k],startX,startY-(22-12),news_data[k],importance_color,22,"Calibri"); } else { createLabel(ARRAY_NEWS+IntegerToString(i)+" "+array_calendar[k],startX,startY,news_data[k],clrBlack,12,"Calibri"); } //--- Increment x-coordinate for the next column startX += buttons[k]+3; } //--- Increment y-coordinate for the next row of data startY += 25; //Print(startY); //--- Print current y-coordinate for debugging } //Print("Final News = ",news_filter_count); updateLabel(TIME_LABEL,"Server Time: "+TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS)+" ||| Total News: "+ IntegerToString(news_filter_count)+"/"+IntegerToString(allValues));
Fue todo un éxito. Al final, queremos eliminar el panel de control cuando se elimine el programa del gráfico para dejar un entorno limpio. Para lograrlo de forma más profesional y sencilla, podemos definir una función en la que añadamos toda la lógica de control.
//+------------------------------------------------------------------+ //| Function to destroy the Dashboard panel | //+------------------------------------------------------------------+ void destroy_Dashboard(){ //--- Delete main rectangle panel ObjectDelete(0, MAIN_REC); //--- Delete first sub-rectangle in the dashboard ObjectDelete(0, SUB_REC1); //--- Delete second sub-rectangle in the dashboard ObjectDelete(0, SUB_REC2); //--- Delete header label text ObjectDelete(0, HEADER_LABEL); //--- Delete server time label text ObjectDelete(0, TIME_LABEL); //--- Delete label for impact/importance ObjectDelete(0, IMPACT_LABEL); //--- Delete all objects related to the calendar array ObjectsDeleteAll(0, ARRAY_CALENDAR); //--- Delete all objects related to the news array ObjectsDeleteAll(0, ARRAY_NEWS); //--- Delete all data holder objects created in the dashboard ObjectsDeleteAll(0, DATA_HOLDERS); //--- Delete all impact label objects ObjectsDeleteAll(0, IMPACT_LABEL); //--- Redraw the chart to update any visual changes ChartRedraw(0); }
Aquí definimos la función personalizada «destroy_Dashboard», que utilizaremos para gestionar la eliminación completa de todos los elementos creados para nuestro panel de control en el gráfico, devolviendo el gráfico a su estado inicial. Esto implica eliminar cada objeto, etiqueta y soporte utilizado en el panel de control. En primer lugar, eliminamos el rectángulo del panel principal llamando a la función ObjectDelete en «MAIN_REC», que representa el contenedor principal de nuestro panel de control. A continuación, procedemos a eliminar cualquier subrectángulo, como «SUB_REC1» y «SUB_REC2», que hemos utilizado para organizar varias secciones del panel de control.
A continuación, eliminamos las etiquetas que muestran información como el encabezado del panel de control («HEADER_LABEL»), la hora del servidor («TIME_LABEL») y el nivel de impacto («IMPACT_LABEL»). Cada una de estas etiquetas se elimina para garantizar que se borre cualquier información textual que aparezca en el gráfico. A continuación, eliminamos todos los objetos de «ARRAY_CALENDAR» y «ARRAY_NEWS», que almacenan información sobre el calendario y las noticias, respectivamente. Realizamos esta acción utilizando la función ObjectsDeleteAll, que nos permite borrar cualquier objeto creado dinámicamente asociado a estas matrices.
A continuación, eliminamos todos los objetos relacionados con «DATA_HOLDERS», que representan filas individuales o contenedores que muestran puntos de datos en el panel, seguido de otra llamada para eliminar las instancias «IMPACT_LABEL» y garantizar que no quede ningún elemento visual.
Por último, llamamos a la función ChartRedraw, que actualiza el gráfico y borra cualquier resto del panel de control, proporcionando un lienzo en blanco para cualquier dibujo adicional o restablecimiento del panel de control. Esta función básicamente desmantela toda la pantalla del panel de control, preparando el gráfico para nuevas actualizaciones u otros elementos visuales según sea necesario después de eliminar el programa. Por último, solo tenemos que llamar a la función en el controlador de eventos OnDeinit para efectuar la eliminación del panel de control.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason){ //--- destroy_Dashboard(); }
Después de llamar a la función personalizada en el controlador de eventos OnDeinit, nos aseguramos de eliminar el panel del gráfico. Eso es todo lo que se necesita para añadir los filtros a nuestro panel de control.
Conclusión
En conclusión, hemos mejorado con éxito nuestro panel del Calendario Económico de MQL5 integrando funciones esenciales de filtrado, que utilizamos para ver únicamente las noticias más relevantes según la divisa, la importancia y el momento. Estos filtros proporcionan una interfaz más optimizada y centrada, lo que nos permite concentrarnos en los acontecimientos económicos que se ajustan a nuestra estrategia y objetivos comerciales específicos.
Al perfeccionar el panel de control con estos filtros, lo convertimos en una herramienta más potente y eficaz para la toma de decisiones informadas. En la siguiente parte, ampliaremos esta base añadiendo actualizaciones en tiempo real a la lógica del panel de control del calendario, lo que permitirá que se actualice constantemente con las últimas noticias económicas directamente en nuestro panel de control MQL5.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/16380
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.





- 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