
Автоматическая оптимизация параметров для торговых стратегий с Python и MQL5
Смысл автоматической оптимизации
Представьте, что у вас есть торговый робот, на разработку которого ушло много сил. Вы с нетерпением ждете возможности увидеть его в работе и поэтому запускаете сразу без оптимизации. Вы получаете первые положительные результаты и думаете, что все в порядке. Однако вскоре что-то ломается, и вы начинаете нести потери.
Неоптимизированный робот работает нестабильно и может реагировать на нерелевантные данные, что приводит к непонятным прибылям и убыткам. Он может принимать решения на основе ложных сигналов, не учитывать изменения рынка и торговать с неоправданным риском, приводя к значительным убыткам. Оптимизация обеспечивает лучшую производительность и надежность.
В этой статье мы увидим, почему автоматическая оптимизация может быть полезна. Мы также познакомимся с различными используемыми алгоритмами и практическими примерами скриптов на Python и советников. Вы научитесь настраивать автоматическую оптимизацию, сравнивать результаты и правильно настраивать оптимизацию параметров, чтобы улучшить эффективность торговой стратегии.
Алгоритмы самооптимизации для торговых стратегий включают оптимизацию параметров, эволюционные алгоритмы, эвристические методы, градиентные методы, машинное обучение и оптимизацию на основе моделирования. Каждый из этих методов имеет свои уникальные плюсы и минусы и подходит под различные торговые потребности и рыночные условия.
Методы оптимизации параметров
- Оптимизация методом грубой силы — тестирует все комбинации параметров для получения точных результатов, но потребляет много ресурсов.
- Поиск по сетке — оценивает комбинации в сетке для баланса полноты и эффективности.
- Случайный поиск — проверяет случайные комбинации для более быстрого получения результатов, жертвуя при этом точностью.
Выбор конкретного метода зависит от доступных ресурсов, времени и желаемой точности.
Зачем писать на Питоне?
Программы на Python — отличный инструмент для проверки идей, быстрого создания графиков и подтверждения теоретических утверждений историческими торговыми данными. Питон позволяет разрабатывать и корректировать модели, легче проводить эксперименты с различными стратегиями и параметрами. Возможность создания подробных графиков и визуализаций помогает более интуитивно интерпретировать результаты. Кроме того, возможность интеграции исторических данных позволяет проверить, как стратегии работали бы в прошлых сценариях, обеспечивая практическое подтверждение выдвинутых теорий. Такое сочетание скорости, гибкости и аналитических возможностей делает Python незаменимы инструментом для всех трейдеров, которые хотят оптимизировать свои стратегии и лучше понимать финансовые рынки.
Стратегия и индикаторы, используемые в этой статье
Стратегия Mobile Sox Crossing (MAs Crossing) — это торговая методика, основанная сигналах, генерируемых при пересечении двух скользящих средних. Для определения изменений ценового тренда используются две скользящие средние разных периодов: короткая и длинная. Когда короткая скользящая средняя пересекает длинную снизу вверх, формируется сигнал на покупку, указывающий на возможный бычий тренд. И наоборот, когда короткая скользящая средняя пересекает длинную сверху вниз, формируется сигнал на продажу, что указывает на возможный медвежий тренд. Эта стратегия достаточно популярна — она проста и вполне эффективна на рынках с четкими тенденциями.
Индикатор SMA (Simple Moving Average, простая скользящая средняя) рассчитывает среднюю цену актива за определенный период. Для расчета SMA суммируем цены закрытия актива за выбранный период, а затем делим на количество периодов. SMA сглаживает колебания цен и помогает определить общее направление тренда. Этот индикатор фильтрует рыночный шум и дает более четкого представления о базовой тенденции. В языке Python есть готовые библиотеки для быстрого и удобно расчета SMA, например pandas.
Оптимизация параметров с помощью Python. Пример
У нас есть по Python-скрипту для каждого метода. Мы уже рассмотрели различия каждого подхода.
Стратегия во всех трех сценариях одинакова. Если вы хотите проверить собственную стратегию, поменяйте следующий код:
data = data.copy() # Create a copy of the original DataFrame data['Short_MA'] = data['Close'].rolling(window=short_window).mean() data['Long_MA'] = data['Close'].rolling(window=long_window).mean() data['Signal'] = 0 data.loc[data.index[short_window:], 'Signal'] = np.where( data['Short_MA'][short_window:] > data['Long_MA'][short_window:], 1, 0) data['Position'] = data['Signal'].diff()
Python достаточно прост, поэтому я не вижу необходимости объяснять этот код.
В приложении к статье вы найдете три скрипта: b forec.py, grid search v2.py и random search v2.py.
Перед их использованием необходимо установить библиотеки. Это можно сделать с использованием команды pip:
pip install numpy pandas matplotlib itertools MetaTrader5 random
Для работы скриптов используем одинаковые входные данные:
symbol = "EURUSD" timeframe = mt5.TIMEFRAME_D1 start = pd.Timestamp("2020-01-01") end = pd.Timestamp("2021-01-01")
Метод грубой силы Brute Force
Best parameters: Short = 14.0, Long = 43.0 Best performance: 10014.176, Risk: 3.7431030827241524e-05
Поиск по сетке
Best parameters: Short = 14.0, Long = 43.0 Best performance: 10014.176, Risk: 3.7431030827241524e-05
Случайный поиск
Best parameters: Short = 14.0, Long = 44.0 Best performance: 10013.697, Risk: 3.725494046576829e-05
Эти скрипты не оптимизируются автоматически, поэтому придется выбирать каждый период для изучения.
Результаты во всех из них хорошие и одинаковые. Но здесь мы имели дело с простой стратегией, а в более сложных может быть больше параметров и более широкие диапазоны значений.
Как часто следует оптимизировать стратегию?
Торговую стратегию обязательно нужно оптимизировать, чтобы она оставалась эффективной с течением времени. Частота и период истории для оптимизации зависят от разных факторов, но в особенности от волатильности рынка.
Представьте, что вы разрабатываете торговую стратегию, которая работает на дневном таймфрейме, то есть каждый сигнал основан на ежедневных рыночных данных. Волатильность здесь играет важную роль: когда рынок более волатилен, движения цен становятся больше и быстрее, и это несомненно отразится на результатах работы такой стратегии.
Чтобы определить, когда проводить оптимизацию и какой ретроспективный анализ использовать, необходимо отслеживать волатильность рынка. Один из вариантов — это наблюдать за дневным диапазоном цен (HIGH - LOW) или истинным средним диапазоном активов, с которыми вы работаете. Ниже приведен вариант руководства анализа на основе волатильности.
Низкая волатильность — когда рынок спокоен и дневные диапазоны небольшие, стратегии, как правило, требуют менее частых корректировок. В таких условиях достаточно может быть оптимизировать каждые 1–3 месяца на большей истории , чтобы зафиксировать более стабильные трнеды. Исторический период в 50-100 дней вполне подойдет.
Умеренная волатильность — в нормальных рыночных условиях, с более регулярными, но не слишком большими колебаниями цен, оптимизировать можно каждые 1-2 месяца. Для того чтобы заметить существенные изменения в тренде, может быть достаточно 20–50 дней истории.
Высокая волатильность — в периоды высокой волатильности, например, во время кризисов или важных экономических событий, движения цен становятся значительными и быстрыми. В такие периоды очень важно проводить оптимизацию чаще, возможно, каждые 2–4 недели, и использовать более короткий исторический период, например, 10–20 дней, чтобы быстро адаптироваться к изменениям рыночных условий.
Пример самооптимизации на MQL5
В качестве примера рассмотрим торгового советника на MQL5, работающего по стратегии пересечения скользящих средних (MA). Он работает в платформе MetaTrader 5 и предназначен для автоматического совершения операций на финансовом рынке. Советник использует две простые скользящие средние (SMA) с настраиваемыми периодами для формирования сигналов на покупку и продажу при их пересечении.
Основная цель советника — автоматическая оптимизация периодов MA для получения максимальной прибыли, минимальной просадки или максимального коэффициента Шарпа в зависимости от выбранной конфигурации. В процессе оптимизации тестируются различные комбинации периодов MA в определенном периоде исторических данных.
Советник состоит из следующих блоков:
1. Инициализация и настройка — определение начальных параметров: периоды MA, размер лота, магическое число для идентификации ордеров и т. д.
2. Оптимизация — использует алгоритм полного поиска для проверки всех возможных комбинаций периодов MA в указанных диапазонах. Оптимизация осуществляется на основе выбранных критериев: прибыль или минимальная просадка.
3. Выполнение операций — постоянно следит за рынком и открывает позиции на покупку или продажу при пересечении скользящих средних в соответствии с заданной стратегией. Он также управляет открытыми позициями, устанавливая стоп-уровни на основе ATR (среднего истинного диапазона).
4. Автоматическая переоптимизация — в определенные периоды времени (настраиваются) советник переоптимизирует параметры скользящих средних, чтобы адаптировать их к изменившимся условиям рынка.
5. Трейлинг-стоп — советник использует различные типы трейлинг-стопов, чтобы гарантировать прибыль и защититься от убытков.
6. Расписание обучения — его можно настроить так, чтобы обучение не проводилось в определенные дни недели или в определенные часы.
7. Завершение и очистка — советник выполняет нужные операции по очистке и закрытию всех открытых операций при остановке.
В целом, этот торговый робот представляет собой сложную реализацию, которая сочетает технический анализ (пересечение скользящих средних) со стратегиями управления рисками (стопы и трейлинг-стопы) и автоматической оптимизацией параметров. Он предназначен для автономной работы и оптимизирован для максимизации эффективности с учетом риска в автоматической торговой среде.
Трейлинг-стопы, используемые в статье и коде, взяты из статьи: Трейлинг-стоп в трейдинге Алексея Полякова.
Код
Чтобы использовать другой метод оптимизации, отредактируйте эту часть кода:
for(int fastPeriod = FastMAPeriodStart; fastPeriod <= FastMAPeriodStop; fastPeriod += FastMAPeriodStep) { for(int slowPeriod = SlowMAPeriodStart; slowPeriod <= SlowMAPeriodStop; slowPeriod += SlowMAPeriodStep) { double criterionValue = PerformBacktest(fastPeriod, slowPeriod, startBar); if(IsNewOptimal(criterionValue, bestCriterionValue, OptimizationCriterion)) { bestCriterionValue = criterionValue; bestFastPeriod = fastPeriod; bestSlowPeriod = slowPeriod; } } }
Чтобы использовать другую стратегию, изменить следующую часть кода (и ее входные данные):
double fastMA_curr[]; double slowMA_curr[]; double fastMA_prev[]; double slowMA_prev[]; ArraySetAsSeries(fastMA_curr, true); ArraySetAsSeries(slowMA_curr, true); ArraySetAsSeries(fastMA_prev, true); ArraySetAsSeries(slowMA_prev, true); int fastMA_current = iMA(_Symbol, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE); int fastMA_previous = iMA(_Symbol, 0, FastMAPeriod, 1, MODE_SMA, PRICE_CLOSE); int slowMA_current = iMA(_Symbol, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE); int slowMA_previous = iMA(_Symbol, 0, SlowMAPeriod, 1, MODE_SMA, PRICE_CLOSE); CopyBuffer(fastMA_current, 0, 0, 2, fastMA_curr); CopyBuffer(slowMA_current, 0, 0, 2, slowMA_curr); CopyBuffer(fastMA_previous, 0, 0, 2, fastMA_prev); CopyBuffer(slowMA_previous, 0, 0, 2, slowMA_prev); double fastMA_previousFF = fastMA_prev[0]; double slowMA_previousSS = slowMA_prev[0]; double fastMA_currentFF = fastMA_curr[0]; double slowMA_currentSS = slowMA_curr[0]; // Check for buy signal (fast MA crosses above slow MA) if(fastMA_previousFF < slowMA_previousSS && fastMA_currentFF > slowMA_currentSS) { // Close any existing sell positions if(PositionsTotal() > 0) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByTicket(i)) { if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { Print("Closing sell position: Ticket ", PositionGetInteger(POSITION_TICKET)); ClosePosition(PositionGetInteger(POSITION_TICKET)); } } } } // Open a buy position double openPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double atrMultiplier = ATRmultiplier; OpenPosition(ORDER_TYPE_BUY, openPrice, atrMultiplier); } // Check for sell signal (fast MA crosses below slow MA) else if(fastMA_previousFF > slowMA_previousSS && fastMA_currentFF < slowMA_currentSS) { // Close any existing buy positions if(PositionsTotal() > 0) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByTicket(i)) { if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { Print("Closing buy position: Ticket ", PositionGetInteger(POSITION_TICKET)); ClosePosition(PositionGetInteger(POSITION_TICKET)); } } } } // Open a sell position double openPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double atrMultiplier = ATRmultiplier; OpenPosition(ORDER_TYPE_SELL, openPrice, atrMultiplier); } IndicatorRelease(fastMA_current); IndicatorRelease(slowMA_current); IndicatorRelease(fastMA_previous); IndicatorRelease(slowMA_previous); }
Важно отметить, что если вы не освободите индикаторы, окно графика будет захламлено.
Разница с автооптимизацией и без нее
Мы будем использовать тот же период (с 20.04.2024 по 20.05.2024) для EURUSD и дневные бары.
С оптимизацией
Без автооптимизации
Очевидно, что с автоматической оптимизацией работа лучше. Ни одна сделка не была заключена без автооптимизации. Первая автоматическая оптимизация была в начале, а затем было 40 дней на повторную оптимизацию (вне периода).
Заключение
Автоматическая оптимизация позволяет обеспечить стабильную и надежную работу торговых советников на постоянно меняющихся финансовых рынках. В этой статье мы рассмотрели, почему самооптимизация полезна, увидели различные типы алгоритмов, доступных для оптимизации торговых стратегий и параметров, а также о преимуществах и недостатках различных методов оптимизации параметров. Также мы затронули тему использования языка Python как инструмента для быстрого и эффективного тестирования стратегий на основе исторических данных. Кроме того, мы рассмотрели пример оптимизации параметров с использованием стратегии пересечения скользящих средних.
Не забывайте про необходимость регулярной оптимизации с учетом волатильности рынка для поддержания эффективности стратегий. Пример самооптимизации с использованием MQL5 проиллюстрировал практическое применение этих концепций, показав существенное улучшение производительности, которого можно добиться с помощью автооптимизации. Оптимизированные советники демонстрируют лучшую адаптивность и эффективность.
В заключение следует отметить, что автоматическая оптимизация не только повышает производительность торгового советника, но и дает трейдерам большую уверенность и спокойствие, поскольку они знают, что их эксперт может эффективно ориентироваться в сложных ситуациях на финансовых рынках. Такой стратегический подход к разработке и использованию торговых роботов будет полезен всем.
Книги и ссылки
- "Advances in Financial Machine Learning" by Marcos López de Prado.
- "Algorithmic Trading and DMA" by Barry Johnson.
- "Python for Data Analysis" by Wes McKinney.
- "Machine Learning for Asset Managers" by Marcos López de Prado.
- "Quantitative Trading: How To Build Your Own Algorithmic Trading Business" by Ernest P.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/15116





- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Привет, спасибо! Вы проверяли количество дней для переоптимизации? (Настройки->Реоптимизация каждые 22 дня->использовать 16 (дней) для того же примера, извините, что плохо объяснил этот параметр)
Привет, спасибо! Вы проверяли количество дней для переоптимизации? (Настройки->Реоптимизация каждые 22 дня->использовать 16 (дней) для того же примера, извините, я не очень хорошо объяснил этот параметр)
Здравствуйте, да, я уже пробовал, но попробую еще раз.
Спасибо еще раз!