Переосмысливаем классические стратегии (Часть 18): Алгоритмический поиск свечных паттернов
Свечные паттерны давно используются профессиональными трейдерами для работы на финансовых рынках и оценки настроений инвесторов. Иногда эти паттерны действительно срабатывают и дают надежные результаты. Однако известно, что они также могут давать сбои в зависимости от преобладающего рыночного режима. В этой статье мы стремимся изучить доступные свечные паттерны и исследовать, можно ли внести какие-либо алгоритмические усовершенствования для преодоления ограничений их классической интерпретации.
В сегодняшнем обсуждении мы сосредоточимся на свечных паттернах, обычно называемых паттернами поглощения. Существует множество сложностей, из-за которых практикам трудно находить надежные свечные паттерны. Первая проблема, с которой сталкивается большинство практиков, заключается в том, что существует огромное количество различных свечных паттернов, которым может следовать любой трейдер. Что еще хуже, перебирать такие паттерны приходится вручную, а это означает, что трейдеру часто приходится вручную определять правила и условия в своем алгоритме, которые описывают конкретный свечной паттерн, который он имеет в виду.
Как мы знаем, существует множество свечных паттернов, и самостоятельный поиск в этом пространстве вручную может оказаться пугающим для новых и неопытных участников нашего сообщества. Цель этой статьи - предложить практическое руководство о том, как мы можем улучшить хорошо известный свечной паттерн. Свечной паттерн поглощения, который мы рассмотрим сегодня, обычно признается большинством трейдеров как признак потенциального пробоя на рынке. Эти свечные паттерны часто указывают на усиление интереса участников рынка и, следовательно, на возможность сильного пробоя на одной стороне рынка.
В большинстве наших статей этой серии мы в основном фокусируемся на торговых стратегиях на базе искусственного интеллекта и технических индикаторах как основных генераторах сигналов. Мы редко предоставляем возможность свечным паттернам влиять на принятие решений алгоритмом. Среди множества причин, по которым свечные паттерны сложнее интегрировать в торговые стратегии, мы назовем несколько.
Во-первых, пространство возможных свечных паттернов очень велико. Существует очень много свечных паттернов, и у каждого из них есть свои собственные вариации, в которых они могут принимать форму. Поскольку свечные паттерны не всегда имеют одну и ту же форму, пытаться исследовать весь набор возможных паттернов и придумывать новые паттерны довольно сложно, так как это приходится делать вручную. Это сложное пространство для алгоритмического поиска.
Кроме того, сами паттерны могут повторяться каждый раз с разными результатами. Следовательно, можно утверждать, что свечные паттерны недостаточно надежны, поскольку один и тот же паттерн может приводить к разным исходам. Это не обязательно является однозначным сигналом будущего направления рынка.
Визуализация классической стратегии
Покончив с этим, мы готовы приступить к визуализации классической реализации торговой стратегии. Обычно свеча поглощения определяется как цена открытия свечи, превышающая цену закрытия предшествующей ей свечи, а обратное верно для ее цены закрытия. Классически считается, что свеча поглощения в большинстве случаев представляет собой паттерн из двух свечей. Он служит сигналом для входа и обычно не используется на младших таймфреймах. В примере кода, который мы используем, мы будем реализовывать стратегию на дневном таймфрейме. На рисунке 1 мы выделили паттерн свечи поглощения на паре EURUSD для наглядности.

Рисунок 1: Идентификация классического паттерна свечи поглощения
При корректном определении свечной паттерн обычно сопровождается сильным ценовым движением в ожидаемом направлении, как мы наглядно показали читателю на рисунке 2. Это служит мотивацией того, почему данный паттерн пользуется популярностью в торговых кругах.
Однако, как мы вскоре увидим, при реализации алгоритма в коде возникают некоторые проблемы. Мы использовали эту классическую версию стратегии для определения базового уровня эффективности нашей торговой системы. После внесения некоторых усовершенствований в эту классическую версию стратегии мы смогли отфильтровать больше шума от рынка и добиться более высоких уровней прибыльности, используя меньшее количество сделок по сравнению с количеством сделок, требуемым для более шумной версии паттерна.

Рисунок 2: Этот паттерн обеспечивает обоснованный уровень уверенности, исходя из его прошлых результатов
На протяжении всей этой серии мы будем искать более 5 уникальных свечных паттернов. Но сегодня мы начнем с того, что сосредоточимся исключительно на свечном паттерне поглощения. Как и в большинстве наших торговых систем, начнем с определения системных констант, чтобы убедиться, что в обоих тестах используется одинаковый размер лотов.
//+------------------------------------------------------------------+ //| Candle Stick Patterns.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| This application attempts to reliably use different candlestick | //| patterns. The application will employ the following: | //| | //| 1) Engulfing Candle | //| 2) Momentum Candle | //| 3) Doji Candle | //| 4) Shooting Star Candle | //| 5) Hammer Candle | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| System constants | //+------------------------------------------------------------------+ #define LOT_SIZE SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN)
Импортируем торговую библиотеку.
//+------------------------------------------------------------------+ //| Trading libraries | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> CTrade Trade;
Теперь загрузим технические индикаторы, которые нам нужны. Мы будем использовать индикатор ATR для определения уровней стоп-лосса и тейк-профита для нашей торговой системы.
//+------------------------------------------------------------------+ //| Indicators | //+------------------------------------------------------------------+ int atr_handler; double atr[];
Как и в большинстве торговых систем, нам нужно несколько глобальных переменных. Они будут отвечать за отслеживание хода времени и изменений в уровнях цен.
//+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ MqlDateTime time_stamp,current_time; double bid,ask;
Когда торговая система будет инициализирована в первый раз, мы настроим параметр временной метки и ATR.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Set the time TimeLocal(time_stamp); atr_handler = iATR(Symbol(),PERIOD_CURRENT,14); //--- return(INIT_SUCCEEDED); }
Когда наша торговая система больше не будет использоваться, мы освободим память, которая ранее была связана с нужным нам индикатором.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- IndicatorRelease(atr_handler); }
Всякий раз, когда поступают новые данные о ценах, система сначала обновляет текущее время и проверяет, нет ли несоответствия между текущим днем и сохраненной временной меткой. Если это первый тик с момента инициализации, временная метка по-прежнему будет отражать это начальное значение. При обнаружении нового дня обновляется временная метка, за которой следует обновление рыночных данных, включая показания буфера ATR и текущие цены Bid и Ask.
Если открытых позиций нет, алгоритм переходит к поиску свечного паттерна поглощения. Как правило, этот паттерн охватывает две свечи — текущую (все еще формирующуюся) свечу и свечу предыдущего дня. Соответственно, iOpen и iClose индексируются как 0 и 1 для обозначения текущей и предыдущей свечей соответственно.
Бычье поглощение определяется, когда текущая свеча открывается ниже закрытия предыдущего дня, а затем закрывается выше его открытия. Тем самым, образуется свеча, которая полностью поглощает предыдущую. Обратные условия определяют медвежью настройку.
Эти правила генерируют сигналы на вход, при этом уровни тейк-профита расположены с интервалом 1,5× ATR, поддерживая соотношение риска и прибыли как 1:1.
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Update the current time TimeLocal(current_time); //--- Check if a new candle has fully formed if(time_stamp.day != current_time.day) { //--- Update the time TimeLocal(time_stamp); //--- A new candle has formed //--- Update the ATR reading CopyBuffer(atr_handler,0,0,1,atr); ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK); bid = SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- First check if we have no open positions if(PositionsTotal() == 0) { //--- Then check for a trade //--- Check for a bullish engulfing candle stick pattern if((iOpen(Symbol(),PERIOD_D1,0)<iClose(Symbol(),PERIOD_D1,1)) && (iClose(Symbol(),PERIOD_D1,0)>iOpen(Symbol(),PERIOD_D1,1))) { //--- Then, enter long positions Trade.Buy(LOT_SIZE,Symbol(),ask,(ask - (atr[0]*1.5)),(ask + (atr[0]*1.5))); } //--- Otherwise we may check for bearish engulfing candlestick pattern if((iOpen(Symbol(),PERIOD_D1,0)>iClose(Symbol(),PERIOD_D1,1)) && (iClose(Symbol(),PERIOD_D1,0)<iOpen(Symbol(),PERIOD_D1,1))) { //--- Then, enter long positions Trade.Sell(LOT_SIZE,Symbol(),ask,(ask + (atr[0]*1.5)),(ask - (atr[0]*1.5))); } } } //--- Otherwise, the current candle has not fully formed } //+------------------------------------------------------------------+
В конце работы торговой системы не забываем отменять определение всех системных переменных.
//+------------------------------------------------------------------+ //| System definitions | //+------------------------------------------------------------------+ #undef LOT_SIZE
Выберем дни бэктеста для нашей базовой версии торговой системы. Мы будем использовать данные за 2 года, охватывающие период с 2023 по 2025 годы.

Рисунок 3: Тестирование базовой версии классического свечного паттерна
Полученные первоначальные показатели эффективности обнадеживают. Похоже, что свечной паттерн поглощения обладает некоторыми уровнями надежности. За 2 года он принес общую чистую прибыль в размере 127,64 долларов в 115 сделках. Это было достигнуто с точностью 55,7% при правильном распределении длинных и коротких позиций. Постоянные читатели должны помнить, как трудно нам было получить такое симметричное распределение сделок с помощью статистической модели в нашем последнем обсуждении на прошлой неделе, ссылка на которое приведена здесь.

Рисунок 4: Статистические результаты, полученные при использовании классической установки
Первоначальная версия стратегии на основе этого свечного паттерна показала кривую эквити с устойчивой прибыльностью и долгосрочным восходящим трендом. Это дает нам дополнительную уверенность в том, что стратегия стоит тех усилий, которые могут потребоваться для ее дальнейшего совершенствования.

Рисунок 5: Кривая эквити, полученная в результате работы базовой стратегии, имеет долгосрочный восходящий тренд
Визуализация переосмысленной стратегии
После тщательного рассмотрения на ум пришло несколько потенциальных усовершенствований.
Во-первых, нужно было сравнить две свечи не только по ценам открытия и закрытия, но и по максимумам и минимумам их теней. Это помогает отфильтровать шум и выделить более заметные свечи — те, которые поддерживаются достаточным объемом для поддержания тренда или сильного направленного движения.
Второе усовершенствование носит более технический характер и связано с тем, как работает бэктестинг на платформе MetaTrader 5. При бэктестинге торгового робота в MetaTrader 5 моделирование начинается в самом начале каждой свечи — в полночь. В результате любая торговая логика, которая зависит от значений открытия, максимума, минимума и закрытия полностью сформированной дневной свечи, в этот момент становится неэффективной. Поэтому с точки зрения MQL5 более практично рассматривать паттерн как структуру из трех свечей, где каждый новый день ссылается как на предыдущий, так и на предшествующий ему день.
На практике, в начале недели, в понедельник, мы проверяем, поглотила ли пятничная свеча свечу четверга. Это понимание затем служит основой для наших торговых решений на понедельник, вместо того чтобы пытаться определить, поглотит ли свеча понедельника свечу пятницы, поскольку свеча понедельника все еще формируется на момент открытия рынка. Исходя из этих соображений, мы разработали усовершенствованную схему, показанную на рисунке 6.

Рисунок 6: Определяем улучшенную версию свечного паттерна, который мы сейчас ищем
Предварительные результаты тестирования были обнадеживающими и свидетельствовали о том, что эта стратегия многообещающая. Однако, как всегда, данные должны в конечном счете говорить сами за себя.

Рисунок 7: Предварительные результаты, которые мы получили по предложенному нами свечному паттерну, обнадеживают
Мы соответствующим образом обновили торговую систему, настроив входы таким образом, чтобы проверять тени свечей вместо того, чтобы полагаться исключительно на цены открытия и закрытия. Мы также нашли лучшее применение цене открытия: вместо того, чтобы напрямую сравнивать ее с ценой закрытия, мы оценили ее движение за предыдущие два дня. Растущая цена открытия во время движения поглощения сигнализировала о бычьих настроениях, в то время как падающая цена открытия указывала на медвежьи настроения.
//--- Then check for a trade //--- Check for a bullish engulfing candle stick pattern if((iLow(Symbol(),PERIOD_D1,1)<iLow(Symbol(),PERIOD_D1,2)) && (iHigh(Symbol(),PERIOD_D1,1)>iHigh(Symbol(),PERIOD_D1,2)) && (iOpen(Symbol(),PERIOD_D1,1)>iOpen(Symbol(),PERIOD_D1,2))) { //--- Then, enter long positions Trade.Buy(LOT_SIZE,Symbol(),ask,(ask - (atr[0]*1.5)),(ask + (atr[0]*1.5))); } //--- Otherwise we may check for bearish engulfing candlestick pattern if((iLow(Symbol(),PERIOD_D1,1)<iLow(Symbol(),PERIOD_D1,2)) && (iHigh(Symbol(),PERIOD_D1,1)>iHigh(Symbol(),PERIOD_D1,2)) && (iOpen(Symbol(),PERIOD_D1,1)<iOpen(Symbol(),PERIOD_D1,2))) { //--- Then, enter long positions Trade.Sell(LOT_SIZE,Symbol(),ask,(ask + (atr[0]*1.5)),(ask - (atr[0]*1.5))); }
Повторный прогон того же периода тестирования дал улучшенные результаты.

Рисунок 8: Улучшенная версия нашей торговой системы готова к тестированию
Общая чистая прибыль увеличилась со 126 до 160 долларов, в то время как общее количество сделок сократилось, что свидетельствует о более эффективном использовании капитала. Это указывает на то, что предыдущая версия вносила ненужный риск при выявлении свечей поглощения. Интересно, что доля прибыльных сделок осталась примерно на том же уровне - 55%, что вполне логично, учитывая, что обе стратегии являются вариациями одной и той же базовой концепции свечей.

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

Рисунок 10: Кривая эквити, полученная в результате работы пересмотренной версии торговой стратегии
Заключение
В заключение отметим, что в этой статье показано, как эффективно применять популярный свечной паттерн поглощения в форме, более подходящей для платформы MQL5. Это демонстрирует, что свечные паттерны продолжают сохранять практическую ценность, даже в своей классической форме, и что при тщательной доработке они могут стать более надежными и более эффективными с точки зрения использования капитала.
Мы также показали, как использовать эти паттерны вместе с индикатором ATR для более эффективного управления рисками, поскольку сами по себе свечные модели не содержат встроенных ориентиров для задания риск-параметров. Мы с нетерпением ждем продолжения этого исследования в нашем следующем обсуждении, где мы улучшим второй свечной паттерн из нашей серии из пяти паттернов.
| Название файла | Описание файла |
|---|---|
| Candle Stick Benchmark.mq5 | Базовая версия нашей торговой системы, разработанная для установки ключевых показателей эффективности. |
| Candle Stick Patterns.mq5 | Улучшенная торговая система, созданная, чтобы превзойти предыдущие достигнутые нами уровни эффективности. |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/20223
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Разработка инструментария для анализа Price Action (Часть 57): Создание модуля классификации состояния рынка на MQL5
Разработка динамического мультивалютного советника (Часть 7): Карта межпарных корреляций для фильтрации сделок в реальном времени
Нейросети в трейдинге: Принятие торговых решений с учётом неопределённости (Модули прогнозирования и планирования)
Разработка инструментария для анализа Price Action (Часть 56): Анализ принятия и отвержения на границах сессии с помощью CP
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования