//+------------------------------------------------------------------+
//|                                           GetTodayEvents-S.mq5   |
//|                               Получение событий на текущий день  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Получение событий на текущий день"

#property strict

//+------------------------------------------------------------------+
//| Обработчик события запуска скрипта                               |
//+------------------------------------------------------------------+
void OnStart()
 {
  GetTodayUSD_Events();
 }

//+------------------------------------------------------------------+
//| Получение значений календаря на текущие сутки                    |
//+------------------------------------------------------------------+
void GetTodayUSD_Events()
 {
//--- определяем границы периода в серверном времени
  datetime server_now = TimeTradeServer();
  datetime day_start  = server_now - (server_now % 86400);
  datetime day_end    = day_start + 86400;

//datetime day_start  = D'01.04.2026';
//datetime day_end    = 0;

  MqlCalendarValue    values[];
  MqlCalendarEvent    event;
  MqlCalendarCountry  country;

//--- запрашиваем значения только для USD
  if(LoadCalendar(values, day_start, day_end, NULL, "USD"))
   {
    Print("  Получено событий для USD: ", ArraySize(values));

    //--- проходимся по массиву событий
    for(int i = 0; i < ArraySize(values); i++)
     {
      //--- получим описание события
      if(CalendarEventById(values[i].event_id, event))
       {
        //--- получим описание страны
        if(CalendarCountryById(event.country_id, country))
         {
          Print("✅ Событие #", i);
          Print("ID события:      ", values[i].event_id);

          Print("Название события: ", event.name);
          Print("Сектор:           ", EnumToString(event.sector));
          Print("Источник:         ", event.source_url);

          Print("Название страны:  ", country.name);
          Print("URL страны:       ", country.url_name);

          Print("Время:            ", TimeToString(values[i].time, TIME_DATE | TIME_SECONDS));
          Print("Влияние:          ", EnumToString(values[i].impact_type));

          // ПРОВЕРКА И ВЫВОД ЗНАЧЕНИЙ
          if(values[i].HasActualValue())
            Print("Факт:             ", values[i].GetActualValue());

          if(values[i].HasRevisedValue())
            Print("Пересмотрено:     ", values[i].GetRevisedValue());

          if(values[i].HasForecastValue())
            Print("Прогноз:          ", values[i].GetForecastValue());

          if(values[i].HasPreviousValue())
            Print("Предыдущее:       ", values[i].GetPreviousValue());
         }
       }
     }
   }
  else
   {
    int error = GetLastError();
    if(error == 0)
     {
      Print("❌ CalendarValueHistory: No Events");
     }
    else
     {
      Print("❌ Ошибка CalendarValueHistory: ", error);
     }
   }
 }
//+------------------------------------------------------------------+
//| Функция загрузки календаря                                       |
//+------------------------------------------------------------------+
bool LoadCalendar(MqlCalendarValue& values[], const datetime from, const datetime to, const string country_code = NULL, const string currency = NULL, const int max_retries = 5)
 {
  int retry_count = 0;

  while(retry_count < max_retries)
   {
    ResetLastError();
    //--- пытаемся загрузить
    if(CalendarValueHistory(values, from, to, country_code, currency))
      return true;

    int error = GetLastError();

    //--- если ошибка "Нет данных" (5201) или "Таймаут" (5200) — ждем и повторяем
    if(error == 5201 || error == 5200)
     {
      retry_count++;
      Sleep(1000);
      continue;
     }

    //--- если ошибка критическая (например, неверная дата) — прерываем сразу
    Print("❌ Critical Calendar Error: ", error);
    return false;
   }

  Print("❌ Failed to load calendar after ", max_retries, " attempts.");
  return false;
 }
//+------------------------------------------------------------------+
//| Функция обработки события от таймера                             |
//+------------------------------------------------------------------+
ulong last_change_id = 0;
MqlCalendarValue updates[];
//+------------------------------------------------------------------+
void OnTimer()
 {
//--- запрашиваем только изменения для валюты USD
  if(CalendarValueLast(last_change_id, updates, "USD") > 0)
   {
    if(ArraySize(updates) > 0)
     {
      //--- обработка новых событий
      // ...
     }
   }
 }
//+------------------------------------------------------------------+
