Фильтр сезонности и временные периоды в моделях глубокого обучения с ONNX и Python в советнике
Введение
После прочтения статьи "Сезонность на рынке форекс и возможности ее использования" я решил написать собственную и создать в ней советник, а затем его работу с сезонностью и без нее. То есть проверить на практике, принесет ли эта сезонность пользу.
Я уже знал, что на рынки влияют сезонные факторы. Это стало очевидно, когда я узнал, что Марк Цукерберг финансировал Facebook на деньги инвестора. Этот инвестор ранее вложил деньги, полученные от бар-мицвы, в акции нефтяных компаний, предсказывая их рост из-за ожидаемых ураганов в Карибском бассейне. Он анализировал прогнозы погоды, которые указывали на предстоящую суровую погоду в этот период.
Я очень горжусь написанием этой статьи, целью которой является практическая эксплуатация идеи о том, что рынок и сезонность — хорошие спутники. Чтобы воплотить это в жизнь, мы можем объединить два советника в один. На сайте уже есть статья о том, как это сделать: "Пример ансамбля ONNX-моделей в MQL5".
Прежде всего, мы создадим советник и сравним модели с фильтрацией и без нее, чтобы увидеть, есть ли влияние фильтрации данных или нет. Затем изучим сезонность на графике и проанализируем реальные данные за февраль 2024 г. с учетом сезонность и без. В последней части статьи (которая мне кажется особенно интересной) мы обсудим другие подходы к советнику из статьи: Использование ONNX-моделей в MQL5. Посмотрим, можно ли извлечь выгоду из дополнительной настройки этих советников и моделей ONNX. Сразу скажу, что ответ – да, можно.
Для работы нам нужно скачать данные (все тики). Для этого можно использовать скрипт для загрузки всех данных по символу. Для этого нужно просто запустить скрипт на графике символа, данные которого нужны, и через некоторое время (менее часа) все исторические тики этого символа будут загружены в папку Files.
После скачивания тиков мы будем работать с этим CSV-файлом и извлекать только те данные, которые нужны (в данном случае периоды с января 2015 года по февраль 2023 года).
Сезонность
Сезонность в торговле заключается в выявлении регулярных приливов и отливов цен на активы, которые предсказуемо происходят в течение года. Это признание того, что некоторые акции в определенное время имеют тенденцию показывать лучшие результаты, чем другие. Давайте немного раскроем эту идею.
Понимание сезонности в трейдинге:
- Определение. Сезонность означает наблюдение за тем, как цены имеют тенденцию колебаться по повторяющейся схеме в зависимости от времени года. Это может быть связано с реальными сезонами (например, летом или зимой), коммерческими сезонами (например, праздники) или даже конкретными месяцами.
- Инвесторы зачастую следят за такими сезонными паттернами, считая их достаточно надежными. Вот несколько примеров:
- Сезонность, связанная с погодой — как погода влияет на сельскохозяйственные сезоны, так же она влияет на, скажем, цены на сырьевые товары и соответствующие запасы. Например, компания, продающая пляжное снаряжение, фиксирует рост продаж летом, но снижение в более холодные месяцы, что влияет на ее акции.
- Праздничная сезонность — акции компаний по розничной торговле часто растут во время ажиотажа праздничных покупок. Это относится к компаниями, которые преуспевают за счет праздничных распродаж, например магазины подарков.
- Сезонность квартальной прибыли — публично торгуемые компании сообщают о прибыли каждый квартал, и цены на их акции могут предсказуемо реагировать в эти сезоны.
- Налоговая сезонность — события, связанные с налогами, могут повлиять на рынок, особенно в секторах, связанных с финансами.
- Естественные циклы — такие отрасли, как туризм или энергетика, имеют свои собственные сезонные модели спроса, например летние каникулы или потребности в отоплении зимой.
Торговые стратегии на основе сезонности
- Есть несколько способов использовать сезонность:
- Выявление сезонных закономерностей — анализ прошлых данных для выявления тенденций, которые повторяются в определенное время года.
- Выбор времени для торговли — вход и выход из позиций на основе сезонных тенденций.
- Управление рисками — регулировка размера риска, который вы берете на себя в периоды нестабильности.
- Ротация секторов — переключение инвестиций между секторами, которые работают лучше в то или иное время года.
Фильтрация данных
Мы будем использовать фильтр нижних частот. Из Википедии:
Фильтр ни́жних часто́т (ФНЧ) — электронный или любой другой фильтр, эффективно пропускающий частотный спектр сигнала ниже некоторой частоты (частоты среза) и подавляющий частоты сигнала выше этой частоты. Степень подавления частоты в полосе подавления (полосе заграждения) зависит от вида фильтра. И наоборот, фильтр верхних частот (ФВЧ) пропускает частоты сигнала выше частоты среза, подавляя низкие частоты.
Почему в алгоритмическом трейдинге мы предпочитаем фильтры нижних частот фильтрам верхних частот? В алгоритмической торговле предпочтение фильтрам нижних частот обусловлено несколькими ключевыми преимуществами:- Фильтры нижних частот эффективно сглаживают шумные движения цен, подчеркивая долгосрочные тенденции над краткосрочными колебаниями.
- Они помогают ослабить высокочастотный шум, который может не давать значимой информации для торговых стратегий.
- Сосредоточив внимание на долгосрочных тенденциях, фильтры нижних частот могут привести к меньшему количеству стратегических сделок, потенциально снижая транзакционные расходы.
- Фильтры нижних частот способствуют более стабильной и предсказуемой торговой стратегии, уменьшая влияние краткосрочных колебаний рынка.
- Такие фильтры хорошо подходят для стратегий с долгосрочными инвестиционными горизонтами, эффективно фиксируя тенденции в течение длительных периодов.
Лично я тоже использую фильтр нижних частот. Использовать фильтр верхних частот здесь особого смысла не имеет.
В нашей статье мы мы тоже будем его использовать. (Примечание: в последней части статьи я изменил параметры 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, которые имеют разные параметры фильтра нижних частот.
Вот пример результата:
Эти же входные параметры будем использовать для советников
Период обучения будет с первого февраля по первое марта.
Для модели без фильтра:
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
С фильтром 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
Вывод по фильтрации
Поэтому да. Использование фильтрации может быть полезно.
Используемый код и модели:
- ONNX.eurusd.H1.120.Prediction_FILTERED.mq5
- ONNX.eurusd.H1.120.Prediction_FILTERED_v2.mq5 ONNX.eurusd.H1.120.Prediction_NOT_FILTERED.mq5
- onnx_LSTM_simple_EURUSD_filtered.py onnx_LSTM_simple_EURUSD_not_filtered.py
- Download all data from a symbol EURUSD_LSTM_120_1h_not_filtered.onnx EURUSD_LSTM_120_1h_filtered_v1.onnx EURUSD_LSTM_120_1h_filtered_v2.onnx
Являются ли символы сезонными?
В этой части мы сначала посмотрим это на графике, получим данные за февраль с 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
Результаты не выдающиеся, но в целом выглядят хорошо (отрицательных значений Шарп не так много).
Сравним с отфильтрованной моделью.
Мне показалось любопытным, что количество отрицательных значений Шарпа занимает половину таблицы при оптимизации для фильтрованной модели, а отрицательные значения для сезонной модели занимают только около одной пятой части таблицы. Это примечательно, поскольку даже при более низком 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 минут без фильтра
LTSM_simple_15m_filtrado_sin.py LSTM.15m.EURUSD.120.0.98.onnx ONNX.eurusd.H1.120.15m_eurusd.mq5
30 минут с фильтром (сейчас и далее я всегда использую фильтр)
LSTM.30m.EURUSD.120.0.94.onnx LTSM_simple_30m_filtrado.py ONNX.eurusd.H1.120.30m_eurusd.mq5
1 час
1 hour files.zip (815.64 KB)
2 часа
Поскольку я не могу использовать двухдневный период, я использовал однодневный период (для значения следующего дня в советнике).
Поскольку я не могу загрузить более 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 минут
12 Ч 30 минут
Период 6h 30 минут
Результаты кажутся лучше с дополнительной настройкой переменной NextDay. Давайте посмотрим, что будет происходить при более низких периодах NextDay.
30 минут с периодом NextDay = 4 часа
30 минут с периодом NextDay = 2 часа
30 минут с периодом NextDay = 1 час
Кажется, что, по крайней мере, для 30-минутных периодов от 8 до 12 баров по 30 минут дают лучшие результаты.
Поскольку цель этой «игры» — выиграть больше денег, один из способов добиться этого — иметь больше выигрышных сделок и надежную стратегию. Давайте проверим, можно ли использовать это при работе с 5-минутными периодами. Протестируем стратегию на 5 минутах, с вариантами параметра NextDay 1 час и 30 минут.
Период 5 минут, NextDay = 1h
Период 5 минут, NextDay = 30 минут
Используемые файлы: 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
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования