English 中文 Español Deutsch 日本語 Português
preview
Фильтр сезонности и временные периоды в моделях глубокого обучения с ONNX и Python в советнике

Фильтр сезонности и временные периоды в моделях глубокого обучения с ONNX и Python в советнике

MetaTrader 5Эксперты | 25 июля 2024, 17:15
787 2
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

Введение

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

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

Я очень горжусь написанием этой статьи, целью которой является практическая эксплуатация идеи о том, что рынок и сезонность — хорошие спутники. Чтобы воплотить это в жизнь, мы можем объединить два советника в один. На сайте уже есть статья о том, как это сделать: "Пример ансамбля ONNX-моделей в MQL5".

Прежде всего, мы создадим советник и сравним модели с фильтрацией и без нее, чтобы увидеть, есть ли влияние фильтрации данных или нет. Затем изучим сезонность на графике и проанализируем реальные данные за февраль 2024 г. с учетом сезонность и без. В последней части статьи (которая мне кажется особенно интересной) мы обсудим другие подходы к советнику из статьи: Использование ONNX-моделей в MQL5. Посмотрим, можно ли извлечь выгоду из дополнительной настройки этих советников и моделей ONNX. Сразу скажу, что ответ – да, можно.

Для работы нам нужно скачать данные (все тики). Для этого можно использовать скрипт для загрузки всех данных по символу. Для этого нужно просто запустить скрипт на графике символа, данные которого нужны, и через некоторое время (менее часа) все исторические тики этого символа будут загружены в папку Files.

После скачивания тиков мы будем работать с этим CSV-файлом и извлекать только те данные, которые нужны (в данном случае периоды с января 2015 года по февраль 2023 года).


Сезонность

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

Понимание сезонности в трейдинге:

  • Определение. Сезонность означает наблюдение за тем, как цены имеют тенденцию колебаться по повторяющейся схеме в зависимости от времени года. Это может быть связано с реальными сезонами (например, летом или зимой), коммерческими сезонами (например, праздники) или даже конкретными месяцами.
  • Инвесторы зачастую следят за такими сезонными паттернами, считая их достаточно надежными. Вот несколько примеров:
    • Сезонность, связанная с погодой — как погода влияет на сельскохозяйственные сезоны, так же она влияет на, скажем, цены на сырьевые товары и соответствующие запасы. Например, компания, продающая пляжное снаряжение, фиксирует рост продаж летом, но снижение в более холодные месяцы, что влияет на ее акции.
    • Праздничная сезонность — акции компаний по розничной торговле часто растут во время ажиотажа праздничных покупок. Это относится к компаниями, которые преуспевают за счет праздничных распродаж, например магазины подарков.
    • Сезонность квартальной прибыли — публично торгуемые компании сообщают о прибыли каждый квартал, и цены на их акции могут предсказуемо реагировать в эти сезоны.
    • Налоговая сезонность — события, связанные с налогами, могут повлиять на рынок, особенно в секторах, связанных с финансами.
    • Естественные циклы — такие отрасли, как туризм или энергетика, имеют свои собственные сезонные модели спроса, например летние каникулы или потребности в отоплении зимой.

Торговые стратегии на основе сезонности

  • Есть несколько способов использовать сезонность:
    • Выявление сезонных закономерностей — анализ прошлых данных для выявления тенденций, которые повторяются в определенное время года.
    • Выбор времени для торговли — вход и выход из позиций на основе сезонных тенденций.
    • Управление рисками — регулировка размера риска, который вы берете на себя в периоды нестабильности.
    • Ротация секторов — переключение инвестиций между секторами, которые работают лучше в то или иное время года.


Фильтрация данных

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

Фильтр ни́жних часто́т (ФНЧ) — электронный или любой другой фильтр, эффективно пропускающий частотный спектр сигнала ниже некоторой частоты (частоты среза) и подавляющий частоты сигнала выше этой частоты. Степень подавления частоты в полосе подавления (полосе заграждения) зависит от вида фильтра. И наоборот, фильтр верхних частот (ФВЧ) пропускает частоты сигнала выше частоты среза, подавляя низкие частоты.

Почему в алгоритмическом трейдинге мы предпочитаем фильтры нижних частот фильтрам верхних частот? В алгоритмической торговле предпочтение фильтрам нижних частот обусловлено несколькими ключевыми преимуществами:
  1. Фильтры нижних частот эффективно сглаживают шумные движения цен, подчеркивая долгосрочные тенденции над краткосрочными колебаниями.
  2. Они помогают ослабить высокочастотный шум, который может не давать значимой информации для торговых стратегий.
  3. Сосредоточив внимание на долгосрочных тенденциях, фильтры нижних частот могут привести к меньшему количеству стратегических сделок, потенциально снижая транзакционные расходы.
  4. Фильтры нижних частот способствуют более стабильной и предсказуемой торговой стратегии, уменьшая влияние краткосрочных колебаний рынка.
  5. Такие фильтры хорошо подходят для стратегий с долгосрочными инвестиционными горизонтами, эффективно фиксируя тенденции в течение длительных периодов.

Лично я тоже использую фильтр нижних частот. Использовать фильтр верхних частот здесь особого смысла не имеет.

В нашей статье мы мы тоже будем его использовать. (Примечание: в последней части статьи я изменил параметры order и Cutoff_ Frequency на Cutoff=0,1 и Order=1, потому что в итоге они дали лучшие результаты. Кроме того, правильные файлы .py для фильтрации — это файлы из последней части статьи (там я использовал не только лучшие параметры, но и minmaxscaler для обучения и инверсии).

# Low-pass filter parameters
cutoff_frequency = 0.01  # Cutoff frequency as a proportion of the Nyquist frequency
order = 4

# Apply the low-pass filter
def butter_lowpass_filter(data, cutoff, fs, order):
    nyquist = 0.5 * fs
    normal_cutoff = cutoff / nyquist
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    print("Filter coefficients - b:", b)
    print("Filter coefficients - a:", a)
    y = lfilter(b, a, data)
    return y

filtered_data_low = butter_lowpass_filter(df2['close'], cutoff_frequency, fs=1, order=order)

Для создания и сравнения моделей ONNX мы будем использовать файлы onnx_LSTM_simple_filtered.pyи onnx_LSTM_simple_not_filtered.py.

Примечание: я использовал модель v1 и модель v2, которые имеют разные параметры фильтра нижних частот.

Вот пример результата:

Эти же входные параметры будем использовать для советников

inputs

inputs2

Период обучения будет с первого февраля по первое марта.

Для модели без фильтра:

RMSE         : 0.0010798043714784716
MSE          : 1.165977480664017e-06
R2 score     : 0.8799146678247277

Без фильтра


С фильтром v1

# Low pass filter parameters

cutoff_frequency = 0.01  # Cutoff frequency in porportion to Nyquist frequency

order = 4


RMSE         : 0.0010228999869332884
MSE          : 1.0463243832681218e-06
R2 score     : 0.8922378749062259


С фильтром v1


С фильтром v2

cutoff_frequency = 0.1  # Cutoff frequency in porportion to Nyquist frequency

order = 2

RMSE         : 0.0010899163515744447
MSE          : 1.1879176534293484e-06
R2 score     : 0.8775550550819025

С фильтром v2


Вывод по фильтрации

Лучшие результаты можно получить только при использовании правильных параметров.

Поэтому да. Использование фильтрации может быть полезно.

Используемый код и модели:


Являются ли символы сезонными?

В этой части мы сначала посмотрим это на графике, получим данные за февраль с 2015 по 2023 год и добавим данные, чтобы увидеть, как они меняются в течение этих недель.

Вот что мы видим из того периода:

Итого за февраль

Вывод:

Мы видим, что у него есть некоторые тенденции, или, по крайней мере, мы не видим черной горизонтальной линии (линия суммы). Между линиями есть промежутки, поскольку символ торгуется в течение года и цены на него колеблются. Поэтому в следующей части статьи мы объединим все символы по годам за февраль. Будем использовать фильтр, чтобы он не пропускал высокую частоту, например, от последней даты с 2022 года по первое февраля 2023 года, и когда ИИ обучается, например, закрытию пятницы и открытию понедельника, он не изучает эти изменения и ищет более сглаженные данные.

Используемые скрипты и данные:


Коррелируют ли эти данные символа?

Автокорреляция — это характеристика данных, которая показывает степень сходства между значениями в последовательных интервалах времени.

Значение около 1 указывает на наличие большой положительной корреляции.

Ниже приведены результаты, которые мы получили с помощью файла autocorrelation.py

[1.         0.99736147 0.99472432 0.99206626 0.98937664 0.98671649
 0.98405706 0.98144222 0.9787753  0.97615525 0.97356318 0.97099777
 0.96848029 0.96602671 0.96360361 0.96113539 0.95865344 0.95615626
 0.95362417 0.95108177 0.94854957 0.94599045 0.94346076 0.94091564
 0.93837742 0.93583734 0.9332909  0.93074655 0.92826504 0.92579028
 0.92330505 0.92084645 0.91834403 0.91581296 0.91328091 0.91076099
 0.90826447]


Создание модели ONNX для оценки февральских сезонов

Для этой задачи нам просто нужно объединить все данные в один CSV и создать на его основе модель.

На основе ранее созданного файла Season.py создадим CSV-файл и добавим его zip-архив Season_feb_contac. Создадим и обучим модель с помощью onnx_LSTM_..._seasonals.py.

Используемые скрипты и данные:


Результаты тестирования сезонной модели и сравнение ее с моделью, отфильтрованной по 120 дням (1 час).

Сезонная модель

RMSE         : 0.013137568368684325
MSE          : 0.00017259570264185493
R2 score     : 0.7166764010650979

Результаты не выдающиеся, но в целом выглядят хорошо (отрицательных значений Шарп не так много).

Коэффициент Шарпа

sharpe2

сезонная оптимизация


Сравним с отфильтрованной моделью.

Коэффициент Шарпа отфильтрованной модели

Коэффициент Шарпа отфильтрованной модели 2d

Отфильтрованная оптимизация


Мне показалось любопытным, что количество отрицательных значений Шарпа занимает половину таблицы при оптимизации для фильтрованной модели, а отрицательные значения для сезонной модели занимают только около одной пятой части таблицы. Это примечательно, поскольку даже при более низком r2 эта модель кажется надежной, дающей прибыльную прибыль.

Я мог бы также протестировать советник без SL и TP, но я считаю, что лучше всегда использовать их в советниках.


Используемый код и модель ONNX:

ONNX.eurusd.H1.120.Prediction_seasonal.mq5 EURUSD_LSTM_270_1h_filtered_seasonal0.72.onnx onnx_LSTM_simple_EURUSD_concat_seasonals.py



Какой период времени использовать?

В этой части статьи я настроил фильтр, чтобы получить лучшие результаты для EURUSD.

cutoff_frequency = 0.1  # Cutoff frequency in proportion to Nyquist frequency
order = 1

Я также изменил фильтр:

from sklearn.preprocessing import MinMaxScaler
from scipy.signal import butter, lfilter

# Parámetros del filtro pasa bajo
cutoff_frequency = 0.1  # Frecuencia de corte en proporción a la frecuencia de Nyquist
order = 1

# Aplicar filtro pasa bajo
def butter_lowpass_filter(data, cutoff, fs, order):
    nyquist = 0.5 * fs
    normal_cutoff = cutoff / nyquist
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    print("Coeficientes del filtro - b:", b)
    print("Coeficientes del filtro - a:", a)
    y = lfilter(b, a, data)
    return y

scaled = MinMaxScaler(feature_range=(0,1))

valores_df1 = df.filter(['close']).values
valores_df1 = pd.DataFrame(valores_df1)
x_features1 = valores_df1[[0]]
valores_df2 = x_features1.values


data_escalada = scaled.fit_transform(valores_df2)

print(data_escalada)

filtered_data_low = butter_lowpass_filter(data_escalada, cutoff_frequency, fs=1, order=order)
print("filtered_data_low",filtered_data_low)

filtered_data_low_unscaled = scaled.inverse_transform(filtered_data_low)

Ордер необходимо округлить до целочисленной цены.

Тестируем стратегию в течение месяца на часовом интервале, в феврале 2024 года. Для 30-минутного интервала тестирование проводится с 1 по 15 февраля и так далее.

Для 15-минутный интервал я проводил тесты с фильтрами и без них. Результаты показывают, что использование фильтра с тонкой настройкой дает лучшие результаты (по крайней мере, в целом).

15 мин с фильтром (Шарп)

Тестирование 15-минутный интервал с фильтром


Тестер 2d 15 min

Тестирование 15-минутный интервал с фильтром


LTSM_simple_15m_filtrado.py LSTM.15m.EURUSD.120.0.98.onnx ONNX.eurusd.H1.120.15m_eurusd.mq5


15 минут без фильтра

Тестирование 15 мин без фильтров

2d 15 мин без фильтра

Тестирование 15-минутный интервал с фильтром

LTSM_simple_15m_filtrado_sin.py LSTM.15m.EURUSD.120.0.98.onnx ONNX.eurusd.H1.120.15m_eurusd.mq5


30 минут с фильтром (сейчас и далее я всегда использую фильтр)

Тестер 30 мин

Тестер 30 мин 2d

тестирование 30 мин


LSTM.30m.EURUSD.120.0.94.onnx
LTSM_simple_30m_filtrado.py ONNX.eurusd.H1.120.30m_eurusd.mq5


1 час

Тесты за 1 час

Тепловая карта тестов на 1 час

Тесты за 1 час


1 hour files.zip (815.64 KB)


2 часа

Поскольку я не могу использовать двухдневный период, я использовал однодневный период (для значения следующего дня в советнике).

Тестирование 2 ч

Тепловая карта 2 ч

Тестирование 2 ч

График 2 ч

Тестирование на истории 2ч


2h.zip

Поскольку я не могу загрузить более 32 файлов, некоторые файлы добавлены в папку.


Заключение

Кажется, что при использовании этой стратегии по мере увеличения периода результаты выглядят более устойчивыми для всех TP и SL.


NextDay var

Я использовал стратегию из статьи "Использование ONNX-моделей в MQL5, но поскольку у меня были хорошие результаты по 2-часовой стратегии, я использовал 1-дневный период. Посмотрим на другие значения переменной NextDays.

   if(TimeCurrent()>=ExtNextDay)
     {
      GetMinMax();
      //--- set next day time
      ExtNextDay=TimeCurrent();
      ExtNextDay-=ExtNextDay%PeriodSeconds(PERIOD_D1);
      ExtNextDay+=PeriodSeconds(PERIOD_D1);
     }
void GetMinMax(void)
  {
   vectorf close;
   close.CopyRates(_Symbol,PERIOD_D1,COPY_RATES_CLOSE,0,SAMPLE_SIZE);
   ExtMin=close.Min();
   ExtMax=close.Max();
  }

Теперь посмотрим, Как ведет себя EURUSD с периодом 30 минут с отфильтрованными данными и различными периодами NextDay (мы будем использовать 1D, 12h и 6h) и обсудим результаты.

1D с периодом 30 минут

1D 30 минут

1D тепловая карта 30 минут

Тестирование 1D


12 Ч 30 минут

Тестирование 12 часов 30 минут

Тепловая карта для периода 12h

Тестирование на периоде 12h 30 минут


Период 6h 30 минут

Период 6h 30 минут

Тепловая карта для периода 6h 30 минут

Тестированик h6 30 min


Результаты кажутся лучше с дополнительной настройкой переменной NextDay. Давайте посмотрим, что будет происходить при более низких периодах NextDay.

30 минут с периодом NextDay = 4 часа

Периоды 4h

Тепловая карта для 4h

Тестирование для периода 4h


30 минут с периодом NextDay = 2 часа

30 min и период 2 h

Тепловая карта для 30 минут и NextDay = 4 часа

Тестирование для периода 2h


30 минут с периодом NextDay = 1 час

Период h1 30 мин

Тепловая карта для периода h1 30 min

Тестирование для периода 1h 30 min


Кажется, что, по крайней мере, для 30-минутных периодов от 8 до 12 баров по 30 минут дают лучшие результаты.


Поскольку цель этой «игры» — выиграть больше денег, один из способов добиться этого — иметь больше выигрышных сделок и надежную стратегию. Давайте проверим, можно ли использовать это при работе с 5-минутными периодами. Протестируем стратегию на 5 минутах, с вариантами параметра NextDay 1 час и 30 минут.

Входные параметры

Период 5 минут, NextDay = 1h

Тестирование 1 h (период 5 мин)

Тепловая карта 1 h (период 5 мин)

Результаты тестирования 1h (5 мин)



Период 5 минут, NextDay = 30 минут

Тестирование 30 мин (5 мин)

Тепловая карта 30 мин (5 мин)

Тестирование 30 мин (5 мин)

Используемые файлы: Last files.zip

Другие периоды времени кажутся более надежными.


Наконец, мы можем внести коррективы в стратегию, которые в конечном итоге могут дать лучшие или более надежные результаты, например, установить лимит времени или баров, например, равным 1-часовому периоду, и использовать 12-часовой период для параметра NextDay, чтобы после создания ордера он был открытым не более 12 часов.

   if(ExtPredictedClass>=0)
     {
      if(PositionSelect(_Symbol))
         CheckForClose();
      else
        {
         CheckForOpen();
         started_time1 = rates[0].time;
         string started_time1_str = TimeToString(started_time1);
int total = PositionsTotal();
   if(total>0)
     {
      datetime started_time2 = rates[0].time;
      string started_time2_str = TimeToString(started_time2);
      int segundos = started_time2 - started_time1;
      Print("Tiempo 1: ", started_time1_str);
      Print("Tiempo 2: ", started_time2_str);
      Print("Diferencia en segundos: ", segundos);
      if((segundos >= days*PeriodSeconds(PERIOD_H12)) && segundos != 0)
        {
         Print("closing position----------------");
         ExtTrade.PositionClose(_Symbol,3);

        }
     }

Тестер

Тепловая карта

Тесты

График


ONNX.eurusd.120.1h_H12_eurusd.v3.mq5
 (9.23 KB)


Заключение

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


Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/14424

Последние комментарии | Перейти к обсуждению на форуме трейдеров (2)
Roman Shiredchenko
Roman Shiredchenko | 25 июл. 2024 в 19:34
Спасибо за статью по сезонности и ее автоматизации. Посмотрел быстро. Буду у компьютера на выходных вчитаюсь по-внимательнее и элементы автомотизации предложенные Вами буду использовать в своих торговых системах по фактору сезонности.
Roman Shiredchenko
Roman Shiredchenko | 25 июл. 2024 в 23:02
Хотелось бы видеть более расширенное заключение в виде удалось ли добиться более интересных (положительных) результатов при использовании фактора сезонности...
Нейросети в трейдинге: Использование языковых моделей для прогнозирования временных рядов Нейросети в трейдинге: Использование языковых моделей для прогнозирования временных рядов
Мы продолжаем рассмотрения моделей прогнозирования временных рядов. И в данной статье я предлагаю познакомиться с комплексным алгоритмом, построенным на использовании предварительно обученной языковой модели.
Нейросети в трейдинге: "Легкие" модели прогнозирования временных рядов Нейросети в трейдинге: "Легкие" модели прогнозирования временных рядов
Легковесные модели прогнозирования временных рядов обеспечивают высокую производительность, используя минимальное количество параметров. Что, в свою очередь, снижает расход вычислительных ресурсов и ускоряет принятие решений. При этом они достигают качества прогнозов, сопоставимого с более сложными моделями.
Возможности Мастера MQL5, которые вам нужно знать (Часть 13): DBSCAN для класса сигналов советника Возможности Мастера MQL5, которые вам нужно знать (Часть 13): DBSCAN для класса сигналов советника
Основанная на плотности пространственная кластеризация для приложений с шумами (Density Based Spatial Clustering for Applications with Noise, DBSCAN) - это неконтролируемая форма группировки данных, которая практически не требует каких-либо входных параметров, за исключением всего двух, что по сравнению с другими подходами, такими как k-средние, является преимуществом. Разберемся в том, как это может быть полезно в тестировании и торговле с применением советников, собранных в Мастере.
Создаем простой мультивалютный советник с использованием MQL5 (Часть 7): Сигналы индикаторов ZigZag и Awesome Oscillator Создаем простой мультивалютный советник с использованием MQL5 (Часть 7): Сигналы индикаторов ZigZag и Awesome Oscillator
Под мультивалютным советником в этой статье понимается советник, или торговый робот, который использует индикаторы ZigZag и Awesome Oscillator, фильтрующие сигналы друг друга.