Obtener registros de eventos de un tipo específico

Si es necesario, un programa MQL tiene la capacidad de solicitar eventos de un tipo específico: para ello, basta con conocer de antemano el identificador del evento, por ejemplo, utilizando las funciones CalendarEventByCountry o CalendarEventByCurrency que se presentaron en la sección Consultar tipos de eventos por país y divisa.

int CalendarValueHistoryByEvent(ulong id, MqlCalendarValue &values[], datetime from, datetime to = 0)

La función CalendarValueHistoryByEvent rellena el array pasado por referencia con registros de eventos de un tipo específico indicado por el identificador id. Los parámetros from y to permiten limitar el intervalo de fechas en el que se buscan los eventos.

Si no se especifica el parámetro opcional to, todas las entradas del calendario se colocarán en el array, empezando por la hora de from y avanzando hacia el futuro. Para consultar todos los eventos pasados, establezca from en 0. Si ambos parámetros from y to son 0, se devolverán todos los eventos históricos y programados. En todos los demás casos, cuando to no es igual a 0, debe ser mayor que from.

El array values puede ser dinámico (entonces la función lo ampliará o reducirá automáticamente según la cantidad de datos) o de tamaño fijo (entonces sólo se copiará en el array la parte que quepa).

La función devuelve el número de caracteres copiados.

Como ejemplo, considere el script CalendarStatsByEvent.mq5, que calcula las estadísticas (frecuencia de aparición) de eventos de diferentes tipos para un país o moneda determinados en un intervalo de tiempo dado.

Las condiciones de análisis se especifican en las variables de entrada.

input string CountryOrCurrency = "EU";
input ENUM_CALENDAR_SCOPE Scope = SCOPE_YEAR;

En función de la longitud de la cadena CountryOrCurrency, se interpreta como un código de país (2 caracteres) o de divisa (3 caracteres).

Para recopilar estadísticas, declararemos una estructura; sus campos almacenarán el identificador y el nombre del tipo de evento, su importancia y el contador de dichos eventos.

struct CalendarEventStats
{
   static const string importances[];
   ulong id;
   string name;
   string importance;
   int count;
};
   
static const string CalendarEventStats::importances[] = {"None""Low""Medium""High"};

En la función OnStart, primero solicitamos todo tipo de eventos utilizando la función CalendarEventByCountry o CalendarEventByCurrency hasta la profundidad especificada de la historia y hacia el futuro, y luego, en un bucle a través de las descripciones de eventos recibidas en el array events, llamamos a CalendarValueHistoryByEvent para cada ID de evento. En esta aplicación no nos interesa el contenido del array values, ya que sólo necesitamos conocer su recuento.

void OnStart()
{
   MqlCalendarEvent events[];
   MqlCalendarValue values[];
   CalendarEventStats stats[];
   
   const datetime from = TimeCurrent() - Scope;
   const datetime to = TimeCurrent() + Scope;
   
   if(StringLen(CountryOrCurrency) == 2)
   {
      PRTF(CalendarEventByCountry(CountryOrCurrencyevents));
   }
   else
   {
      PRTF(CalendarEventByCurrency(CountryOrCurrencyevents));
   }
   
   for(int i = 0i < ArraySize(events); ++i)
   {
      if(CalendarValueHistoryByEvent(events[i].idvaluesfromto))
      {
         CalendarEventStats event = {events[i].idevents[i].name,
            CalendarEventStats::importances[events[i].importance], ArraySize(values)};
         PUSH(statsevent);
      }
   }
   
   SORT_STRUCT(CalendarEventStatsstatscount);
   ArrayReverse(stats);
   ArrayPrint(stats);
}

Si la llamada a la función tiene éxito, rellenamos la estructura CalendarEventStats y la añadimos al array de estructuras stats. A continuación, ordenamos la estructura de la forma que ya conocemos (la macro SORT_STRUCT se describe en la sección Comparar, ordenar y buscar en arrays).

La ejecución del script con la configuración por defecto genera algo como esto en el registro (abreviado):

CalendarEventByCountry(CountryOrCurrency,events)=82 / ok
          [id]                                                [name] [importance] [count]
[ 0] 999520001 "CFTC EUR Non-Commercial Net Positions"               "Low"             79
[ 1] 999010029 "ECB President Lagarde Speech"                        "High"            69
[ 2] 999010035 "ECB Executive Board Member Elderson Speech"          "Medium"          37
[ 3] 999030027 "Core CPI"                                            "Low"             36
[ 4] 999030026 "CPI"                                                 "Low"             36
[ 5] 999030025 "CPI excl. Energy and Unprocessed Food y/y"           "Low"             36
[ 6] 999030024 "CPI excl. Energy and Unprocessed Food m/m"           "Low"             36
[ 7] 999030010 "Core CPI m/m"                                        "Medium"          36
[ 8] 999030013 "CPI y/y"                                             "Low"             36
[ 9] 999030012 "Core CPI y/y"                                        "Low"             36
[10] 999040006 "Consumer Confidence Index"                           "Low"             36
[11] 999030011 "CPI m/m"                                             "Medium"          36
...
[65] 999010008 "ECB Economic Bulletin"                               "Medium"           8
[66] 999030023 "Wage Costs y/y"                                      "Medium"           6
[67] 999030009 "Labour Cost Index"                                   "Low"              6
[68] 999010025 "ECB Bank Lending Survey"                             "Low"              6
[69] 999010030 "ECB Supervisory Board Member af Jochnick Speech"     "Medium"           4
[70] 999010022 "ECB Supervisory Board Member Hakkarainen Speech"     "Medium"           3
[71] 999010028 "ECB Financial Stability Review"                      "Medium"           3
[72] 999010009 "ECB Targeted LTRO"                                   "Medium"           2
[73] 999010036 "ECB Supervisory Board Member Tuominen Speech"        "Medium"           1
 

Tenga en cuenta que se recibió un total de 82 tipos de eventos, pero en el array de estadísticas sólo teníamos 74. Esto se debe a que la función CalendarValueHistoryByEvent devuelve false (fallo) y código de error cero en _LastError si no hubo eventos de ningún tipo en el rango de fechas especificado. En la prueba anterior hay 8 entradas de este tipo que teóricamente existen pero que nunca se encontraron en el año.