Импорт котировок криптовалют из CSV в MT5: Создание Custom Symbol

Импорт котировок криптовалют из CSV в MT5: Создание Custom Symbol КРЕДИТЫ, ИПОТЕКА и БАНКИ
Пошаговое руководство по импорту исторических котировок криптовалют из CSV-файла в MetaTrader 5. Готовый MQL5 скрипт для создания Custom Symbol.
Суть: Скрипт автоматизирует создание пользовательского инструмента (Custom Symbol) в MetaTrader 5 и наполняет его историческими минутными или дневными данными из внешнего CSV-файла с помощью функций CustomSymbolCreate и CustomRatesReplace. Это необходимо для бэктестинга криптовалютных пар, которых нет у вашего брокера.

Исходный код

В сфере количественного трейдинга (Quantitative Trading) часто возникает задача протестировать стратегию на альтернативных данных, например, на котировках криптовалют с бирж Binance, Coinbase или Kraken, которых может не быть в стандартном терминале MT5 вашего брокера. MetaTrader 5 предоставляет мощный функционал для создания пользовательских символов (Custom Symbols). Представленный ниже скрипт на MQL5 считывает исторические данные из CSV-файла, автоматически создает кастомный символ и импортирует в него историю баров.

При разработке торговых роботов на основе импортированных данных часто возникает необходимость скрыть свои намерения от брокера. В таких случаях полезно изучить, как реализовать Виртуальный Stop Loss и Take Profit в MQL4: Невидимые для брокера.

//+------------------------------------------------------------------+
//|                                         ImportCryptoToCustom.mq5 |
//|                                  Copyright 2024, Quant Developer |
//|                                             https://finfluct.com |
//+------------------------------------------------------------------+
#property copyright "Quant Developer"
#property link      "https://finfluct.com"
#property version   "1.00"
#property script_show_inputs

// Входные параметры скрипта
input string   InpCustomSymbolName = "BTCUSD_Custom"; // Имя кастомного символа
input string   InpFileName         = "crypto_data.csv"; // Имя CSV файла (в папке MQL5/Files)
input string   InpCustomGroup      = "CryptoCustom";    // Группа символов
input string   InpBaseSymbol       = "BTCUSD";          // Базовый символ для копирования свойств

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   // 1. Создаем кастомный символ
   ResetLastError();
   if(!CustomSymbolCreate(InpCustomSymbolName, InpCustomGroup, InpBaseSymbol))
   {
      int err = GetLastError();
      if(err != ERR_MARKET_SYMBOL_EXIST)
      {
         PrintFormat("Ошибка создания символа %s. Код ошибки: %d", InpCustomSymbolName, err);
         return;
      }
      else
      {
         PrintFormat("Символ %s уже существует. Продолжаем импорт.", InpCustomSymbolName);
      }
   }

   // Включаем отображение символа в Market Watch
   if(!SymbolSelect(InpCustomSymbolName, true))
   {
      PrintFormat("Не удалось выбрать символ %s в Market Watch.", InpCustomSymbolName);
      return;
   }

   // 2. Открываем CSV файл для чтения
   int file_handle = FileOpen(InpFileName, FILE_READ|FILE_CSV|FILE_ANSI, ',');
   if(file_handle == INVALID_HANDLE)
   {
      PrintFormat("Ошибка открытия файла %s. Убедитесь, что он находится в папке MQL5/Files. Код ошибки: %d", InpFileName, GetLastError());
      return;
   }

   // Динамический массив для хранения баров
   MqlRates rates[];
   ArrayResize(rates, 0);

   // Пропускаем заголовок, если он присутствует в файле
   if(!FileIsEnding(file_handle))
   {
      string header = FileReadString(file_handle);
      string header_lower = header;
      StringToLower(header_lower);
      if(StringFind(header_lower, "time") == -1 && StringFind(header_lower, "date") == -1)
      {
         // Если первая строка не заголовок, возвращаем указатель в начало
         FileSeek(file_handle, 0, SEEK_SET);
      }
   }

   Print("Начало чтения файла...");

   // Читаем данные построчно
   while(!FileIsEnding(file_handle))
   {
      string time_str = FileReadString(file_handle);
      if(time_str == "") continue;

      double open_val  = FileReadNumber(file_handle);
      double high_val  = FileReadNumber(file_handle);
      double low_val   = FileReadNumber(file_handle);
      double close_val = FileReadNumber(file_handle);
      long   volume_val = (long)FileReadNumber(file_handle);

      MqlRates rate;
      rate.time = StringToTime(time_str);
      rate.open = open_val;
      rate.high = high_val;
      rate.low = low_val;
      rate.close = close_val;
      rate.tick_volume = volume_val;
      rate.real_volume = volume_val;
      rate.spread = 0;

      if(rate.time == 0)
      { 
         PrintFormat("Предупреждение: Неверный формат даты/времени '%s'. Пропуск строки.", time_str);
         continue;
      }

      int size = ArraySize(rates);
      ArrayResize(rates, size + 1);
      rates[size] = rate;
   }

   FileClose(file_handle);

   int total_rates = ArraySize(rates);
   if(total_rates == 0)
   {
      Print("Нет данных для импорта.");
      return;
   }

   PrintFormat("Успешно прочитано %d баров. Запись в кастомный символ...", total_rates);

   // 3. Записываем котировки в кастомный символ
   ResetLastError();
   int imported = CustomRatesReplace(InpCustomSymbolName, rates[0].time, rates[total_rates - 1].time, rates);
   if(imported < 0)
   {
      PrintFormat("Ошибка импорта котировок. Код ошибки: %d", GetLastError());
   }
   else
   {
      PrintFormat("Импорт завершен! Успешно добавлено/обновлено %d баров для символа %s.", imported, InpCustomSymbolName);
   }
}

Разбор параметров

  • InpCustomSymbolName: Строковое имя создаваемого кастомного символа (например, BTCUSD_Custom).
  • InpFileName: Имя CSV-файла с котировками, который должен находиться в директории MQL5/Files терминала.
  • InpCustomGroup: Название группы в окне "Обзор рынка" (Market Watch), куда будет помещен новый символ.
  • InpBaseSymbol: Имя существующего базового символа (например, BTCUSD), свойства которого (размер контракта, маржинальные требования, шаг цены) будут скопированы для нового кастомного инструмента.

Как запустить

Для успешного запуска скрипта выполните следующие шаги:

1. Подготовьте CSV-файл с историческими данными. Файл должен иметь формат: YYYY.MM.DD HH:MM:SS,Open,High,Low,Close,Volume. Например: 2023.10.27 12:00:00,34100.5,34250.0,34050.2,34200.0,150. Обратите внимание, что разделителем должна быть запятая.

2. Поместите подготовленный файл в папку данных терминала. Для этого в MT5 выберите Файл -> Открыть каталог данных, затем перейдите по пути MQL5/Files и скопируйте файл туда.

3. Откройте MetaEditor, создайте новый скрипт, скопируйте в него представленный выше код и скомпилируйте его.

4. Перетащите скомпилированный скрипт из навигатора MT5 на любой график. В появившемся окне параметров укажите имя вашего CSV-файла и желаемое имя кастомного символа.

5. После завершения работы скрипта откройте окно Символы (Ctrl+U), найдите созданный инструмент в группе CryptoCustom и убедитесь, что бары успешно импортированы. Теперь вы можете открыть график этого символа и запускать на нем любые советники или индикаторы.

Если вы работаете с мультитаймфреймовым анализом на кастомных символах, вам также может быть интересно узнать, Как считывать данные индикатора с другого таймфрейма (iCustom MTF) без перерисовки в MQL4.

Для построения сложных сеточных стратегий на основе импортированных данных обратите внимание на Динамический Мартингейл с учетом корреляции пар в MQL4.

Оцените статью
FinFluct