Использование ONNX-моделей в MQL5

Оглавление

Введение

В статье "A CNN-LSTM-Based Model to Forecast Stock Pricesarrow-up-right" (авторы Wenjie Lu, Jiazheng Li, Yifan Li, Aijun Sun, Jingyang Wang, журнал Complexity, vol. 2020, Article ID 6622927, 10 pages, 2020) сравнивались различные модели прогноза котировок фондового рынка.

Ценовые данные акций обладают характеристиками временных рядов.

В то же время, на основе машинного обучения с использованием долгосрочной краткосрочной памяти (LSTM), которая имеет преимущества в анализе взаимосвязей между временными рядами через свою функцию памяти, мы предлагаем метод прогнозирования цены акций на основе CNN-LSTM.

В течение этого времени мы используем модели MLP, CNN, RNN, LSTM, CNN-RNN и другие модели прогнозирования для поочередного прогнозирования цены акций. Кроме того, результаты прогнозирования этих моделей анализируются и сравниваются. Данные, использованные в этом исследовании, касаются дневных цен на акции с 1 июля 1991 года по 31 августа 2020 года, включая 7127 торговых дней.

В отношении исторических данных мы выбираем восемь характеристик, включая цену открытия, максимальную цену, минимальную цену, цену закрытия, объем, оборот, подъемы и падения, а также изменения. Во-первых, мы используем CNN для эффективного извлечения характеристик из данных, которые представляют собой данные предыдущих 10 дней. Затем мы применяем LSTM для прогнозирования цены акций с использованием извлеченных данных характеристик.

Согласно результатам экспериментов, CNN-LSTM может обеспечить надежный прогноз цен на акции с наивысшей точностью предсказания. Этот метод прогнозирования не только предоставляет новую исследовательскую идею для прогнозирования цен на акции, но и предоставляет практический опыт ученым для изучения временных рядов финансовых данных.

Таким образом, среди рассмотренных моделей наилучшие результаты показали модели типа CNN-LSTM. В данной статье мы рассмотрим процесс создания такой модели для прогнозирования финансовых временных рядов и использование созданной ONNX-модели в MQL5-советнике.

1. Построение модели

Благодаря наличию специализированных библиотек язык Python обладает широкими возможностями для работы с моделями машинного обучения. Библиотеки значительно облегчают подготовку и обработку данных.

Для полноценной работы с проектами машинного обучения рекомендуется использовать возможности GPU. Многие пользователи Windows при установке текущей версии TensorFlow столкнулись с проблемами (См. комментарии к видео-инструкцииarrow-up-right и текстовый вариант), поэтому мы протестировали и рекомендуем использовать TensorFlow 2.10.0. GPU-расчеты производились на видеокарте NVIDIA GeForce RTX 2080 Ti при помощи библиотек CUDA 11.2 и CUDNN 8.1.0.7.

1.1. Установка Python и библиотек

Если язык Python не установлен, его нужно установить (мы использовали версию 3.9.16).

Далее нужно установить библиотеки (если используется Conda/Anaconda, то эти команды нужно выполнить в Anaconda Prompt):

1.2. Проверка версии TensorFlow и GPU

Код для проверки установленной версии TensorFlow и возможностей использования GPU для расчета моделей:

Создание и обучение модели производится скриптом на Python, ниже кратко рассматриваются этапы этого процесса.

1.3. Создание и обучение модели

Скрипт начинается с импорта библиотек Python, которые будут использованы.

Проверка версии TensorFlow:

Доступности GPU:

Инициализация MetaTrader 5 для работы из Python:

Информация о терминале MetaTrader 5:

Выводим путь для сохранения модели (в этом примере скрипт исполняется в Jupyter Notebook):

Подготавливаем даты для запроса исторических данных. В данном случае часовые бары по EURUSD за 120 дней с текущей даты:

Запрашиваем исторические данные по инструменту EURUSD:

Отображаем загруженные данные:

Выводим начало и конец датафрейма:

Выборка только цен close:

Отображение данных:

Приводим исходные ценовые данные к диапазону [0,1] при помощи MinMaxScaler:

Для обучения будут использоваться первые 80% данных.

Функция для создания обучающих последовательностей:

Производим их построение:

Формы тензоров для обучения и тестирования:

Задаем модель:

Выводим свойства модели:

Обучение модели:

В данном случае обучение заняло около 8 минут.

Динамика оптимизации на обучаемом и тестовом наборах:

Формирование прогноза на обучающей выборке:

Отображение графиков (реального и прогноза модели) на интервале обучения:

Формирование прогноза на тестовой выборке:

Для расчета метрик требуется преобразовать данные из интервала [0,1], для этого также используем MinMaxScaler.

Экспорт модели в onnx-файл:

Полный код Python-скрипта в виде Jupyter Notebook прикреплён к статье.

В статье "A CNN-LSTM-Based Model to Forecast Stock Pricesarrow-up-right" наилучшее значение R^2=0.9646 было получено для моделей с архитектурой CNN-LSTM, в нашем примере сеть CNN-LSTM показала лучший результат R^2=0.9684. Таким образом, модели подобного типа способны эффективно решать задачи прогноза.

Представлен пример скрипта на Python для создания и обучения CNN-LSTM моделей для прогноза финансовых временных рядов.

2. Использование модели в MetaTrader 5

2.1. Перед началом использования. Что нужно знать

Существует два способа создать модель: OnnxCreatearrow-up-right для создания модели из onnx-файла и OnnxCreateFromBufferarrow-up-right для создания из массива данных.

Если ONNX-модель используется в эксперте в качестве ресурса, то после каждого её изменения эксперт необходимо перекомпилировать.

Не у всех моделей полностью определены размеры входных и/или выходных тензоров. Как правило, это первая размерность, отвечающая за размер пачки. Перед запуском модели необходимо явно указать размеры, которые будут использоваться. Для этого нужны функции OnnxSetInputShapearrow-up-right и OnnxSetOutputShape.arrow-up-right

Входные данные модели нужно готовить таким же самым способом, что был использован при обучении модели.

Для входных и выходных данных рекомендуется использовать массивы, матрицы и/или векторы того же самого типа, что и в моделиarrow-up-right. В таком случае не придётся использовать конвертацию данных при запуске модели. Если невозможно представить данные в необходимом типе, будет применяться автоматическая конвертация.arrow-up-right

Запуск модели (или инференс) производится функцией OnnxRunarrow-up-right. Запуск модели можно производить многократно.

После использования модели необходимо её освободить при помощи функции OnnxReleasearrow-up-right.

Полная документация по ONNX моделям в MQL5.arrow-up-right

2.2. Чтение onnx-файла и получение информации о входных и выходных данных

Итак, необходимо применить полученную нами модель. Для этого необходимо знать, где брать модель, тип и размерность входных данных, тип и размерность выходных данных. Мы сами писали обучающий скрипт, поэтому знаем, что модель model.eurusd.H1.120.onnx лежит рядом с питоновским скриптом, сгенерировавшем onnx-файл. Входные данные типа float32, 120 нормализованных цен Close (если будем работать с размером пачки равным 1), выходные данные типа float32, одна нормализованная цена, предсказанная моделью.

Мы специально создали onnx-файл также и в папке MQL5\Files, чтобы можно было при помощи MQL5-скрипта получить полную информацию о входе и выходе модели.

В окне выбора файлов мы взяли наш onnx-файл, сохранённый в папке MQL5\Files, создали модель из файла (OnnxCreate) и получили вот какую информацию.

Так как мы заказали отладочную информацию,

то получили ряд сообщений с префиксом ONNX.

Мы видим, что модель действительно имеет один вход и один выход. При этом первая размерность входного тензора и первая размерность выходного тензора не определены. Предполагается, что данные размерности отвечают за размер пачки (batch size). Поэтому перед запуском модели на исполнение (inference) необходимо явно указать, с какими размерами мы собираемся работать (OnnxSetInputShapearrow-up-right, OnnxSetOutputShapearrow-up-right). Как правило, мы подаём на вход только одну порцию данных. Подробный пример представлен в следующем пункте "Пример использования ONNX модели в торгующем эксперте".

Кроме этого, для подготовки входных данных совершенно необязательно использовать массив с размерностями [1, 120, 1]. На вход можно подать одномерный массив или вектор размером 120 элементов

2.3. Пример использования ONNX-модели в торгующем эксперте

Предварительные объявления и определения

Функция OnInit

Работаем только с EURUSD,H1. Просто потому, что используем данные текущего символа-периода.

Наша модель включена в эксперт в виде ресурса. Эксперт самодостаточен, и нет необходимости читать onnx-файл извне. Создаём модель сразу из ресурсного массива.

Обязательно явно определяем формы входных и выходных данных.

Функция OnTick

Определяем начало нового дня. Это нужно для того, чтобы обновить минимум и максимум 120-дневной последовательности для нормирования цен в 120-часовой последовательности. Мы обучали модель именно при этих условиях, поэтому должны соблюсти правила для подготовки входных данных.

Потом при необходимости мы в течение дня модифицируем минимум и максимум.

Функция предсказания:

Сначала проверяем, можем ли мы осуществить нормализацию. Нормализация осуществляется аналогично питоновскому MinMaxScaler.

Соответственно, код нормализации очень простой и очевидный.

Векторы для входных данных и для приёма результата специально организованы как статические. Это гарантирует неперемещаемый в памяти буфер, существующий всё время жизни программы. Таким образом, в ONNX модели входной и выходной тензоры не пересоздаются каждый раз при запуске модели.

Центральная функция OnnxRun. Флаг ONNX_NO_CONVERSION означает, что данные, входные и выходные, не должны подвергаться конверсии, так как тип float в MQL5 точно соответствует типу ONNX_DATA_TYPE_FLOAT. Флаг ONNX_DEBUG не установлен.

После этого разнормализуем полученные данные в предсказанную цену и определяем класс — цена пойдёт вверх, вниз или не поменяется.

Торговая стратегия проста. В начале каждого часа проверяем прогноз цены на конец часа. Если цена по прогнозу пойдёт вверх, покупаем. И наоборот, если цена пойдёт вниз, продаём.

Теперь необходимо проверить работоспособность эксперта. Это можно сделать в тестере. Но для того, чтобы протестировать эксперта с начала года, необходимо тренировать модель на данных до начала года. Поэтому мы немного видоизменили питоновский скрипт, убрав из него всё лишнее и заменив конечную дату.

Скрипт ONNX.eurusd.H1.120.Training.py находится в подпапке Python и запускается прямо в MetaEditor. Полученная ONNX модель будет записана рядом в этой же подпапке Python и при компиляции эксперта будет использована в качестве ресурса.

Тестирование советника на основе ONNX-модели

Настало время проверить советника на исторических данных в тестере стратегий. Выставляем в настройках параметры, на которых тренировалась модель: символ EURUSD и таймфрейм H1.

Устанавливаем интервал за пределами периодом обучения модели — с начала года, с 01.01.2023 — и запускаем тестирование.

Настройки тестирования советника

Так как согласно стратегии проверка сигналов производится один раз в начале каждого часа (в советнике стоит проверка на появление нового бара), то режим моделирования тиков не имеет значения — OnTick будет отрабатываться в тестере только один раз за бар.

При такой проверке тестирование за 3 месяца занимает несколько секунд. Мы сразу же получаем результаты.

Теперь изменим торговую стратегию, а именно — открытие позиции по сигналу, закрытие позиции по стоп-лоссу или тейк-профиту.

Укажем параметр InpUseStops = true, это означает, что при открытии позиции выставляются уровни TP и SL.

Результаты тестирования с использованием уровней SL/TP с начала года показаны ниже.

Полный исходный код эксперта и обученная модель на начало 2023 года прикреплены к статье.

Заключение

Мы показали, что нет ничего сложного в использовании ONNX моделей в MQL5-программах. Наоборот, это очень просто. Гораздо сложнее получить адекватную ONNX-модель.

Прикрепленные файлы arrow-up-right

Last updated