Оптимизация трендовой торговли: Торговля по направлению тренда и с учётом его силы
Введение
Эта статья предназначена как для трейдеров, которым сложно выбрать правильную сделку и направление тренда, так и для тех, кто хочет выработать торговую дисциплину и избежать или сократить убытки, открывая сделки только по направлению тренда и не торгуя против него или на краткосрочных колебаниях. Она также будет полезна трейдерам, которые сталкиваются с параличом при входе в сделку или чрезмерно анализируют ситуацию после появления точки входа и в итоге упускают сделку, потому что не решаются вовремя исполнить торговую идею из-за неуверенности в правильном направлении тренда и рыночном смещении. Ещё одна группа, которой может помочь эта статья, — новые и развивающиеся трейдеры, которые всё ещё пытаются разобраться, как выбирать правильное направление тренда, будь то долгосрочное, внутридневное или общее направление и сила тренда, для принятия торговых решений.
Я считаю, что в большинстве случаев, если не всегда, торговля с учётом силы и направления тренда может стать переломным фактором и тем самым отличием между трейдером A и трейдером B при одинаковых навыках и опыте. Способность трейдера принимать прибыльные и качественные решения, особенно во внутридневной и долгосрочной торговле, во многом зависит от того, как он открывает и удерживает позиции относительно направления и силы тренда. Статистика снова и снова показывает, что торговля против тренда часто даёт лишь краткосрочные движения цены, которые в основном являются откатами перед сильным движением по тренду, и если не быть осторожным, можно столкнуться с очень серьёзными убытками. В то же время сделки, открытые с учётом силы и направления тренда, чаще прощают неидеальную точку входа и иногда могут принести дополнительные сотни, а то и тысячи долларов прибыли, если трейдер достаточно терпелив и ждёт продолжения тренда.
Как трейдер, я знаю, что участники рынка сталкиваются с множеством трудностей. На самом деле большинство трейдеров в какой-то момент своей торговой карьеры сталкиваются с очень похожими, если не одинаковыми, проблемами. Отличает их то, что разные трейдеры по-разному справляются с этими трудностями, реагируют на них и заранее их учитывают. Именно поэтому результаты торговли могут различаться очень сильно даже у трейдеров, которые почти равны по навыкам, опыту, выдержке, качеству принятия решений и технике.
Одна из главных, если не самая распространённая, трудность — определение направления и силы тренда. Именно эту задачу и призвана решить данная статья. Это серьёзная проблема для начинающих и развивающихся трейдеров, а иногда и для гораздо более опытных участников рынка; когда-то она была серьёзной проблемой и для меня. Эта статья и советник помогут согласовывать открываемые сделки с трендом и тем самым избегать краткосрочных сделок против него. Развивающимся трейдерам это поможет действовать увереннее и более избирательно при исполнении сделок, поскольку со временем они научатся определять тренды и направления торговых движений. А когда задача определения направления сделки решена, остаётся найти правильный сетап, момент и точку входа.
Кроме того, сделки, которые анализируются, открываются, сопровождаются и отслеживаются с учётом направления тренда, как правило, оказываются и более точными, и более быстрыми, при этом сопровождаются небольшой просадкой, поскольку цена быстрее движется к целям сделки. Более того, ценовые колебания в направлении тренда обычно сильнее: даже если позиция временно находится в просадке, цена вскоре вновь начнёт двигаться в соответствии с текущим трендовым сценарием и выведет позицию из просадки.
В статье подробно рассматривается советник, специально разработанный для трейдеров, которым хватает терпения открывать, выдерживать и удерживать позиции только при торговле с учётом направления и силы тренда, избегая сделок против тренда. Они воздерживаются от контртрендовых сделок и удерживают позиции, не меняя часто направленного взгляда на рынок, пока не будут достигнуты цели по тейк-профиту или пока не изменится общий тренд. Этот советник также важен для внутридневных и краткосрочных трейдеров, поскольку помогает торговать в направлении наиболее вероятного движения цены с учётом тренда и тем самым повышает вероятность успеха.

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

Определение тренда, недельный, месячный и дневной тренд, а также прогнозирование направления и силы тренда
Первое, что нужно сделать после перехода на график MN, — отметить ключевые точки, то есть области реакции, о которых говорилось выше. Обычно они находятся в районе минимумов и максимумов предыдущих недель. Такую ключевую область реакции всегда следует держать в уме, поскольку цена почти всегда реагирует на неё, и она может определить, как цена будет двигаться в течение месяца или его оставшейся части. Следовательно, когда мы подтверждаем, что цена движется от одной ключевой области к другой на таймфрейме MN, это означает, что мы определили направление месячного тренда, а сделки в этом месяце будут тяготеть к ключевым областям на месячном графике.
Это можно считать наиболее доступной ближайшей целью, поскольку речь идёт о ближайшей области реакции на месячном таймфрейме (MN). Ещё одной точкой интереса являются скользящие средние: их можно использовать для оценки текущей силы и скорости движения цены к цели. Последний важный элемент — ценовая динамика (price action), поскольку он во многом определяет дальнейшее движение цены и может предупредить о внезапном изменении или пробое тренда. Скользящим средним может потребоваться время, чтобы дать чёткие сигналы, тогда как ценовая динамика гораздо информативнее, особенно если вы достаточно внимательны и умеете его читать.
Внимательные трейдеры по ценовой динамике заметят, что для начала некоторых долгосрочных трендов цена может прийти в ключевую область, снять минимум или максимум, а затем сформировать свечу поглощения или сдвиг рыночной структуры. Это может произойти даже на более младшем таймфрейме, и для эффективности не обязательно, чтобы всё произошло на одном и том же таймфрейме. Например, если цена снимает минимум предыдущей недели, после чего появляется бычья свеча поглощения или сдвиг рыночной структуры, и затем цена быстро развивает движение в противоположном направлении, мы можем наблюдать начало нового тренда.
Цель состоит в том, чтобы терпеливо дождаться завершения и закрытия свечи поглощения или сдвига рыночной структуры. Когда мы убеждаемся, что модель сформировалась корректно, можно считать, что новый тренд определён, и входить в покупки по его направлению. Все сделки следует открывать в соответствии с текущим трендом, поскольку сделки по тренду обычно развиваются быстрее, дают более чистую картину ценовой динамики и сопровождаются минимальной просадкой. Также желательно не торговать против тренда, пока он снова не изменится.
Колебания и краткосрочные развороты будут возникать, особенно на младших таймфреймах, но они не должны существенно влиять на долгосрочную картину тренда. Завершение тренда или разворот может произойти на противоположной стороне месячного диапазона или в ключевых областях, описанных ранее. Та же формула или теория применима и к недельному графику, где она используется для определения недельного тренда, ожиданий и рыночного сценария.
Последний таймфрейм, на котором проявляется эта важная и характерная особенность, — D1. Я считаю его критически важным и фундаментальным, потому что он выступает промежуточным звеном между двумя крайностями: младшими и старшими таймфреймами. Вероятно, это даже лучший таймфрейм для построения контекста внутридневных и краткосрочных сделок, которые рассчитаны на несколько часов или дней, используя только дневной график.
На этом таймфрейме относительно проще заметить как краткосрочные, так и долгосрочные колебания, а также определить рыночный сценарий и тренд. Поскольку D1 является ключевым таймфреймом, трейдерам следует уделять внимание ценовой динамике, тренду и скользящим средним: именно на этом таймфрейме сосредоточены ключевые сигналы, на основе которых оценивают и отрабатывают направление тренда.
Важно отметить, что области сопротивления и поддержки также являются ключевыми зонами, за которыми нужно следить, как и зоны спроса и предложения, а также ордер-блоки, поскольку они, по сути, описывают схожее рыночное явление, хотя называются по-разному. При этом общий тренд иногда может меняться в зависимости от геополитической обстановки или факторов, поддерживающих торгуемый актив.
Последняя важная мысль, которую я оставил напоследок: для достижения оптимальных результатов трейдеру следует отдавать приоритет сделкам тогда, когда два или все три таймфрейма совпадают и имеют одно и то же рыночное смещение, рыночный сценарий и тренд. Когда W1, D1 и MN «говорят на одном языке», такие торговые дни часто оказываются одними из самых простых: движение развивается быстро, с минимальными просадками или откатами.
Ниже, в следующих разделах, я подробнее объясню, как разработать и настроить советник, основанный на анализе тренда и использующий его для формирования торгового решения.

Автоматизация торговых решений с помощью советника Trend King в MQL5
Чтобы автоматизировать, проиллюстрировать и реализовать эту стратегию, я создал:
- трендовый советник, который анализирует тренды и открывает позиции только по направлению тренда, используя трейлинг-стоп и скользящие средние для помощи в определении тренда.
Процесс принятия решений
Решения этого советника — определение тренда, анализ ценовой динамики и исполнение сделок — основаны на следующей логике:
Исходный код советника Trend King (в тексте местами также: Trending King EA):
Этот советник выявляет потенциальные торговые сигналы, соответствующие общему направлению и силе тренда, и ожидает торговые сетапы только по направлению тренда, избегая позиций против него. Он также использует экспоненциальные и простые скользящие средние для определения общего направления тренда при входе в сделки и применяет логику трейлинг-стопа для определения уровней стоп-лосса и защиты капитала, когда цена движется в пользу позиции. В советник включено управление риском — 1% риска на сделку.
Входные параметры: настраиваемые торговые настройки
Входные параметры позволяют пользователям адаптировать поведение советника для торговли GBPJPY, GBPUSD и EURUSD без изменения основного кода. `LotSize` установлен равным 0.1 — это консервативный размер, подходящий для пар с GBP и позволяющий ограничивать риск при их умеренной волатильности (100–300 пунктов в день). `LookbackBars` (3) определяет окно для выявления недавних максимумов/минимумов на H1/H4/D1, сочетая отзывчивость и надёжность. `StopLossPips` (150) и `TakeProfitPips` (600) адаптированы к типичным диапазонам GBPJPY, GBPUSD/EURUSD и нацелены на соотношение риск/прибыль 1:4, чтобы использовать сильные тренды после снятия ликвидности. `TrailingStopPips` (100) позволяет фиксировать прибыль во время более резких движений GBPJPY. `EngulfingMinBodyRatio` (0.3) гарантирует, что тело свечи поглощения существенно по отношению к телу предыдущей свечи, отфильтровывая слабые сигналы.
`TradeTimeframe` (H1) и `ConfirmationTimeframe` (M15) обеспечивают гибкое обнаружение снятия ликвидности и более быстрое подтверждение входа соответственно. `MaxCandlesPostPurge` (3) ограничивает окно для сигналов поглощения после снятия ликвидности, помогая избегать поздних входов. `VolumeThreshold` (1.0) требует всплеска объёма для подтверждения ликвидности, что особенно важно для движений GBPUSD, часто связанных с новостями. `UseTrendFilter` (true) и `SMAPeriod` (50) включают 50-периодную SMA, чтобы сделки соответствовали более широкому тренду и снижалось количество ложных пробоев на волатильных рынках GBP.
Примечание редактора: в пояснительном описании указаны одни параметры, однако в приведённом ниже коде заданы другие значения по умолчанию: `LookbackBars` — 5, `StopLossPips` — 30, `TakeProfitPips` — 90, `TrailingStopPips` — 40, `EngulfingMinBodyRatio` — 0.5, `TradeTimeframe` — M15, `ConfirmationTimeframe` — M5, `MaxCandlesPostPurge` — 5, `VolumeThreshold` — 1.2.
//+------------------------------------------------------------------+ //| TrendKingEA.mq5 | //| Expert Advisor for MetaTrader 5 | //| Description:Trades based on Trend strenght and direction, waits | //| for trade set ups on trend direction, with flexible execution. | //+------------------------------------------------------------------+ #property copyright "Eugene Mmene" #property link "https://www.EMcapital.com" #property version "1.06" //--- Input parameters input double LotSize = 0.1; // Lot size for trades input int LookbackBars = 5; // Number of bars to check for highs/lows input double StopLossPips = 30.0; // Stop loss in pips (adjusted for GOLD#) input double TakeProfitPips = 90.0; // Take profit in pips (adjusted for GOLD#) input double TrailingStopPips = 40.0; // Trailing stop in pips input double BreakevenPips = 30.0; // Move to BE after 30 pips profit input double EngulfingMinBodyRatio = 0.5; // Min body ratio for engulfing candle input ENUM_TIMEFRAMES TradeTimeframe = PERIOD_M15; // Primary timeframe for trading input ENUM_TIMEFRAMES ConfirmationTimeframe = PERIOD_M5; // Lower timeframe for engulfing input ENUM_TIMEFRAMES TrendTimeframe = PERIOD_H1; // Trend from H1 SMA input int MaxCandlesPostPurge = 5; // Max H1 candles to wait for engulfing input double VolumeThreshold = 1.2; // Volume multiplier for liquidity confirmation input bool UseTrendFilter = true; // Use SMA trend filter input int SMAPeriod = 50; // SMA period for trend filter
Функция OnInit: настройка и проверка для надёжной торговли
Функция `OnInit` выполняется один раз при загрузке советника на график и обеспечивает корректную настройку для торговли GBPUSD, GBPJPY и EURUSD. В авторском описании указано, что она проверяет `TradeTimeframe` (H1, H4 или D1) и `ConfirmationTimeframe` (M15 или M30), однако в приведённом коде фактически проверяются `TradeTimeframe` M15/M30 и `ConfirmationTimeframe` M5/M15; некорректные входные данные отклоняются для предотвращения ошибок. Функция получает размер контракта символа с помощью `SymbolInfoDouble`, что критически важно для точного расчёта размера позиции по парам с GBP, где стоимость пункта отличается, например у GBPJPY из-за масштаба JPY.
Глобальные переменные, отслеживающие максимумы и минимумы (`lastHighH1`, `lastLowH1` и т. д.), время свечей и статус торговли, инициализируются нулём или значением false, сбрасывая состояние советника. Проверка размера контракта позволяет советнику корректно рассчитывать размеры лотов, что особенно важно для GBPJPY с её высокой чувствительностью к стоимости пункта. При успешной инициализации в журнал выводятся таймфрейм и размер контракта, подтверждая готовность к торговле. Такая настройка делает советник более надёжным и адаптированным к специфической рыночной динамике EURUSD/GBPUSD/GBPJPY, в отличие от более широких ценовых колебаний золота.
int OnInit() { if(TradeTimeframe != PERIOD_M15 && TradeTimeframe != PERIOD_M30) { Print("Invalid trade timeframe. Use M15 or M30."); return(INIT_PARAMETERS_INCORRECT); } if(ConfirmationTimeframe != PERIOD_M5 && ConfirmationTimeframe != PERIOD_M15) { Print("Invalid confirmation timeframe. Use M5 or M15."); return(INIT_PARAMETERS_INCORRECT); } contractSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE); if(contractSize == 0) { Print("Failed to get contract size for ", _Symbol); return(INIT_PARAMETERS_INCORRECT); } lastHigh = 0; lastLow = 0; lastCandleTime = 0; purgeDetected = false; lastPurgeTime = 0; Print("EA Initialized on ", EnumToString(TradeTimeframe), ", Confirmation TF: ", EnumToString(ConfirmationTimeframe), ", Contract Size: ", contractSize); return(INIT_SUCCEEDED); }
Функция IsNewCandle: логика срабатывания на новом баре
Функция `IsNewCandle` проверяет, сформировалась ли новая свеча на основном торговом таймфрейме, сравнивая временную метку текущей свечи (`iTime`) с последним сохранённым временем свечи (`lastCandleTime`). В авторском пояснении говорится о H1, но в опубликованном коде по умолчанию задан `TradeTimeframe = PERIOD_M15`. Если обнаружена новая свеча, `lastCandleTime` обновляется, а функция возвращает `true`, запуская основную торговую логику в `OnTick`. Это гарантирует, что советник оценивает торговые условия только один раз на каждую новую свечу выбранного торгового таймфрейма, снижая нагрузку на обработку и предотвращая лишние проверки во время волатильных внутрисвечных движений GBPUSD/GBPJPY. Работа по новым барам соответствует стратегии, которая опирается на завершённые свечные данные для определения снятия ликвидности и паттернов поглощения, что критически важно для захвата значимых движений цены на трендовых рынках пар с GBP. Функция лёгкая, но важная для поддержания эффективности и точности советника.
bool IsNewCandle() { datetime currentCandleTime = iTime(_Symbol, TradeTimeframe, 0); if(currentCandleTime != lastCandleTime) { lastCandleTime = currentCandleTime; return true; } return false; }
Функция UpdateHighsLows: отслеживание уровней снятия ликвидности
Функция `UpdateHighsLows` отслеживает наивысшие максимумы и наименьшие минимумы за последние `LookbackBars` (по умолчанию 5) на таймфреймах H1, H4 и D1, сохраняя их в глобальных переменных (`lastHighH1`, `lastLowH1` и т. д.). Она использует `CopyRates` для получения исторических ценовых данных, а `ArraySetAsSeries` гарантирует, что самая свежая свеча находится в индексе 0. Для каждого таймфрейма функция инициализирует максимум и минимум значениями первой свечи, а затем проходит по периоду просмотра и фиксирует экстремальные цены.
Эта функция критически важна для обнаружения снятия ликвидности — ситуации, когда текущая свеча H1 пробивает предыдущий максимум или минимум на любом таймфрейме, сигнализируя о потенциальном развороте или продолжении тренда на EURUSD, GBPUSD или GBPJPY. Мультитаймфреймовый подход позволяет советнику фиксировать значимые случаи снятия ликвидности, например вызванные охотой за стопами во время волатильных движений GBPJPY. Обработка ошибок записывает в журнал сбои загрузки котировок, обеспечивая устойчивость. Эта функция закладывает основу логики входа после снятия ликвидности, адаптированной к чувствительности пар с GBP к ключевым уровням поддержки и сопротивления.
void UpdateHighsLows() { // H1 MqlRates ratesH1[]; ArraySetAsSeries(ratesH1, true); if(CopyRates(_Symbol, PERIOD_H1, 1, LookbackBars, ratesH1) >= LookbackBars) { lastHighH1 = ratesH1[0].high; lastLowH1 = ratesH1[0].low; for(int i = 1; i < LookbackBars; i++) { if(ratesH1[i].high > lastHighH1) lastHighH1 = ratesH1[i].high; if(ratesH1[i].low < lastLowH1) lastLowH1 = ratesH1[i].low; } } else Print("Failed to load H1 rates"); // H4 MqlRates ratesH4[]; ArraySetAsSeries(ratesH4, true); if(CopyRates(_Symbol, PERIOD_H4, 1, LookbackBars, ratesH4) >= LookbackBars) { lastHighH4 = ratesH4[0].high; lastLowH4 = ratesH4[0].low; for(int i = 1; i < LookbackBars; i++) { if(ratesH4[i].high > lastHighH4) lastHighH4 = ratesH4[i].high; if(ratesH4[i].low < lastLowH4) lastLowH4 = ratesH4[i].low; } } else Print("Failed to load H4 rates"); // D1 MqlRates ratesD1[]; ArraySetAsSeries(ratesD1, true); if(CopyRates(_Symbol, PERIOD_D1, 1, LookbackBars, ratesD1) >= LookbackBars) { lastHighD1 = ratesD1[0].high; lastLowD1 = ratesD1[0].low; for(int i = 1; i < LookbackBars; i++) { if(ratesD1[i].high > lastHighD1) lastHighD1 = ratesD1[i].high; if(ratesD1[i].low < lastLowD1) lastLowD1 = ratesD1[i].low; } } else Print("Failed to load D1 rates"); }
Функция IsVolumeSpike: подтверждение торговой ликвидности
Функция `IsVolumeSpike` подтверждает торговые сетапы, проверяя, превышает ли тиковый объём текущей свечи средний объём за `LookbackBars` (5) с коэффициентом `VolumeThreshold` (1.2). Она использует `CopyRates` для получения последних свечей на торговом таймфрейме и рассчитывает средний объём валидных баров, то есть баров с объёмом > 1, чтобы избежать проблем с данными. Если валидных баров нет, проверка пропускается, чтобы не останавливать работу, а в журнал выводится предупреждение для отладки. Для EURUSD, GBPUSD и GBPJPY высокий объём часто сопровождает значимые движения цены, например пробои после новостей или снятие ликвидности, поэтому этот фильтр важен для подтверждения снятия ликвидности. Функция выводит текущий и средний объём для прозрачности. Подтверждение объёма помогает советнику избегать низколиквидных сетапов, которые приводят к ложным сигналам по парам с GBP, повышая качество сделок и прибыльность на трендовых рынках вроде GBPJPY.
bool IsVolumeSpike(long currentVolume) { double avgVolume = 0; MqlRates rates[]; ArraySetAsSeries(rates, true); if(CopyRates(_Symbol, TradeTimeframe, 1, LookbackBars, rates) < LookbackBars) { Print("Failed to load rates for volume check"); return true; } int validBars = 0; for(int i = 0; i < LookbackBars; i++) { if(rates[i].tick_volume > 1) { avgVolume += rates[i].tick_volume; validBars++; } } if(validBars == 0) { Print("Warning: No valid volume data. Average volume is 0. Bypassing volume check."); return true; } avgVolume /= validBars; Print("Current volume: ", currentVolume, ", Average volume: ", avgVolume, ", Valid bars: ", validBars); return currentVolume >= VolumeThreshold * avgVolume; }
Функция IsBullishTrend: проверка соответствия тренду
Функция `IsBullishTrend` использует 50-периодную простую скользящую среднюю (SMA) на торговом таймфрейме, чтобы определить направление рыночного тренда. Она создаёт хендл SMA с помощью `iMA`, получает последнее значение SMA через `CopyBuffer` и сравнивает его с текущей ценой закрытия (`iClose`). Если цена находится выше SMA, функция возвращает `true`, указывая на бычий тренд; в противном случае подразумевается медвежий или нейтральный тренд.
Когда `UseTrendFilter` включён (по умолчанию true), эта функция гарантирует, что покупки открываются только в бычьих условиях, а продажи — в медвежьих, что соответствует склонности EURUSD/GBPUSD/GBPJPY следовать устойчивым трендам во время лондонской и нью-йоркской сессий. Обработка ошибок фиксирует сбои получения данных SMA, обеспечивая надёжность. Фильтр снижает количество ложных пробоев в условиях неровного, разнонаправленного рынка, что часто встречается на парах с GBP, подтверждая более широкий рыночный контекст перед входом после снятия ликвидности.
bool IsBullishTrend() { double sma[]; ArraySetAsSeries(sma, true); int smaHandle = iMA(_Symbol, TradeTimeframe, SMAPeriod, 0, MODE_SMA, PRICE_CLOSE); if(CopyBuffer(smaHandle, 0, 0, 1, sma) < 1) { Print("Failed to load SMA data"); return false; } double currentPrice = iClose(_Symbol, TradeTimeframe, 0); Print("Current price: ", currentPrice, ", SMA: ", sma[0]); return currentPrice > sma[0]; }
IsBullishEngulfing и IsBearishEngulfing: подтверждение разворотных сигналов
Эти функции определяют бычьи и медвежьи свечи поглощения — ключевые разворотные паттерны, используемые для подтверждения входов после снятия ликвидности. `IsBullishEngulfing` проверяет, является ли текущая свеча бычьей (close > open), предыдущая — медвежьей (close < open), поглощает ли текущая свеча предыдущую (open ≤ previous close, close ≥ previous open), а также составляет ли тело текущей свечи не менее `EngulfingMinBodyRatio` (0.3) тела предыдущей свечи. `IsBearishEngulfing` применяет обратную логику для медвежьих сетапов. Для EURUSD, GBPUSD и GBPJPY свечи поглощения на M15 или H1 после снятия ликвидности часто сигнализируют о сильных разворотах или продолжениях, особенно после снятия ликвидности на ключевых уровнях.
Проверка соотношения тел свечей гарантирует, что свеча поглощения достаточно значима, и отфильтровывает слабые паттерны во время волатильных сессий по парам с GBP. Эти функции применяются к трём последним свечам как на H1, так и на M15, что позволяет гибко ловить сигналы на любом из этих таймфреймов и повышает отзывчивость советника к динамике рынков GBP.
bool IsBullishEngulfing(MqlRates ¤t, MqlRates &previous) { double currentBody = MathAbs(current.close - current.open); double prevBody = MathAbs(previous.close - previous.open); if(current.close > current.open && previous.close < previous.open && current.open <= previous.close && current.close >= previous.open && currentBody >= EngulfingMinBodyRatio * prevBody) { return true; } return false; } bool IsBearishEngulfing(MqlRates ¤t, MqlRates &previous) { double currentBody = MathAbs(current.close - current.open); double prevBody = MathAbs(previous.close - previous.open); if(current.close < current.open && previous.close > previous.open && current.open >= previous.close && current.close <= previous.open && currentBody >= EngulfingMinBodyRatio * prevBody) { return true; } return false; }
Функция PlaceTrade: исполнение рыночных сделок со SL/TP
Функция `PlaceTrade` исполняет сделки на покупку или продажу, когда подтверждён корректный сигнал: снятие ликвидности + поглощение + объём + тренд. Она формирует `MqlTradeRequest` с символом, фиксированным `LotSize` (0.1), типом ордера (buy/sell) и ценой входа. В коде стоп-лосс задаётся через `StopLossPips`, а тейк-профит — через `TakeProfitPips`; в приведённой версии кода это 30 и 90 пипсов соответственно, с поправкой на стоимость пункта EURUSD, GBPUSD и GBPJPY (`_Point * 100`) для учёта масштаба пунктов. Тип исполнения `ORDER_FILLING_IOC` (Immediate or Cancel) обеспечивает быстрое исполнение, что критически важно на быстро движущемся рынке GBPJPY.
При успешном исполнении функция записывает детали сделки в журнал, устанавливает `tradePlaced` в true для предотвращения множественных сделок и сбрасывает `purgeDetected`, чтобы избежать повторного входа по тому же сигналу. При ошибке она записывает код ошибки для отладки. Эта функция обеспечивает точное исполнение сделок с заранее заданными параметрами риска, оптимизируя прибыльность за счёт работы с высоковероятными сетапами в трендовом поведении пар с GBP.
void PlaceTrade(ENUM_ORDER_TYPE orderType, double price) { MqlTradeRequest request = {}; MqlTradeResult result = {}; request.action = TRADE_ACTION_DEAL; request.symbol = _Symbol; request.volume = LotSize; request.type = orderType; request.price = price; request.sl = (orderType == ORDER_TYPE_BUY) ? price - StopLossPips * _Point * 100 : price + StopLossPips * _Point * 100; request.tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfitPips * _Point * 100 : price - TakeProfitPips * _Point * 100; request.type_filling = ORDER_FILLING_IOC; if(OrderSend(request, result)) { Print("Trade placed successfully: ", orderType == ORDER_TYPE_BUY ? "BUY" : "SELL", " at ", price, " SL: ", request.sl, " TP: ", request.tp); tradePlaced = true; purgeDetected = false; // Reset purge after trade } else { Print("Trade failed: ", result.retcode); } }
Функция ManageTrailingStop: защита прибыли с помощью трейлинг-стопов
Функция `ManageTrailingStop` динамически корректирует стоп-лосс открытых позиций, фиксируя прибыль по мере благоприятного движения цены. Она проверяет наличие позиции по символу с помощью `PositionSelect`. Для позиций на покупку рассчитывается новый стоп-лосс на уровне текущей цены Bid минус `TrailingStopPips` с учётом стоимости пункта GBPUSD, EURUSD и GBPJPY. В пояснении автор указывает 100 пипсов, но в опубликованном коде параметр по умолчанию равен 40. Новый стоп-лосс применяется только если он выше текущего стоп-лосса и выше цены открытия, что обеспечивает безубыток или прибыль. Для позиций на продажу стоп-лосс устанавливается выше текущей цены Ask и применяется, если он ниже текущего стоп-лосса (или если стоп-лосс отсутствует) и ниже цены открытия.
Функция использует `MqlTradeRequest` с `TRADE_ACTION_SLTP` для обновления стоп-лосса при сохранении тейк-профита. Этот механизм трейлинга особенно важен для волатильных колебаний GBPJPY, поскольку позволяет советнику захватывать крупные движения и одновременно защищать прибыль. Обработка ошибок записывает неудачные обновления в журнал, обеспечивая прозрачность. Функция повышает прибыльность, снижая риск возврата уже полученной прибыли на трендовых рынках пар с GBP.
void ManageTrailingStop() { if(!PositionSelect(_Symbol)) return; double currentPrice = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double currentSL = PositionGetDouble(POSITION_SL); double newSL = 0; if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { newSL = currentPrice - TrailingStopPips * _Point * 100; if(newSL > currentSL && newSL > openPrice) { MqlTradeRequest request = {}; MqlTradeResult result = {}; request.action = TRADE_ACTION_SLTP; request.position = PositionGetInteger(POSITION_TICKET); request.symbol = _Symbol; request.sl = newSL; request.tp = PositionGetDouble(POSITION_TP); if(OrderSend(request, result)) Print("Trailing stop updated for BUY: ", newSL); else Print("Failed to update trailing stop: ", result.retcode); } } else // POSITION_TYPE_SELL { newSL = currentPrice + TrailingStopPips * _Point * 100; if((newSL < currentSL || currentSL == 0) && newSL < openPrice) { MqlTradeRequest request = {}; MqlTradeResult result = {}; request.action = TRADE_ACTION_SLTP; request.position = PositionGetInteger(POSITION_TICKET); request.symbol = _Symbol; request.sl = newSL; request.tp = PositionGetDouble(POSITION_TP); if(OrderSend(request, result)) Print("Trailing stop updated for SELL: ", newSL); else Print("Failed to update trailing stop: ", result.retcode); } } }
Функция OnTick: основная торговая логика снятия ликвидности и поглощения
Функция `OnTick` является главным центром принятия решений советника. Она выполняется на каждом ценовом тике, но обрабатывает данные только на новых свечах выбранного торгового таймфрейма через `IsNewCandle`. Если открытых позиций нет, она сбрасывает `tradePlaced`, обеспечивая одну сделку на цикл снятия ликвидности. Открытые позиции сопровождаются трейлинг-стопами с помощью `ManageTrailingStop`. Функция загружает свечные данные H1 и M15 через `CopyRates`, сравнивает текущую свечу H1 с предыдущими максимумами и минимумами, обновлёнными через `UpdateHighsLows`, чтобы обнаружить снятие ликвидности — пробой ценой максимумов H1/H4/D1 или минимумов, что часто встречается на EURUSD, GBPUSD/GBPJPY во время ключевых сессий. Если снятие ликвидности обнаружено, устанавливается `purgeDetected`, а `lastPurgeTime` отслеживает окно после снятия ликвидности. В авторском описании говорится об окне до 3 свечей H1, тогда как в коде параметр `MaxCandlesPostPurge` по умолчанию равен 5.
Объём подтверждается функцией `IsVolumeSpike`, а тренд проверяется через `IsBullishTrend`, если фильтр включён. Паттерны поглощения определяются на торговом и подтверждающем таймфреймах, что обеспечивает гибкое подтверждение. Сделка на покупку открывается, если после снятия верхней ликвидности появляется бычья свеча поглощения на торговом или подтверждающем таймфрейме, присутствует высокий объём и бычий тренд. Сделка на продажу требует снятия нижней ликвидности, медвежьего поглощения, высокого объёма и медвежьего тренда. Подробное журналирование обеспечивает прозрачность при отладке. Такая логика повышает вероятность качественных сделок по парам с GBP, объединяя мультитаймфреймовое снятие ликвидности с надёжными подтверждающими сигналами и учитывая их склонность к трендовому движению.
void OnTick() { // Check if a new candle has formed on the trade timeframe if(!IsNewCandle()) return; // Reset tradePlaced if no open positions if(!PositionSelect(_Symbol)) tradePlaced = false; // Manage trailing stop for open positions ManageTrailingStop(); // Get current and previous candle data for trade timeframe MqlRates ratesH1[]; ArraySetAsSeries(ratesH1, true); if(CopyRates(_Symbol, TradeTimeframe, 0, 4, ratesH1) < 4) { Print("Failed to load H1 rates data"); return; } // Get candle data for confirmation timeframe (M15) MqlRates ratesM15[]; ArraySetAsSeries(ratesM15, true); if(CopyRates(_Symbol, ConfirmationTimeframe, 0, 4, ratesM15) < 4) { Print("Failed to load M15 rates data"); return; } // Current H1 candle (index 0) double currentOpenH1 = ratesH1[0].open; double currentCloseH1 = ratesH1[0].close; double currentHighH1 = ratesH1[0].high; double currentLowH1 = ratesH1[0].low; long currentVolumeH1 = ratesH1[0].tick_volume; datetime currentTimeH1 = ratesH1[0].time; // Update highs and lows for all timeframes UpdateHighsLows(); // Check for purge (liquidity sweep) on any timeframe bool highPurgedH1 = (currentHighH1 > lastHighH1 && lastHighH1 > 0); bool highPurgedH4 = (currentHighH1 > lastHighH4 && lastHighH4 > 0); bool highPurgedD1 = (currentHighH1 > lastHighD1 && lastHighD1 > 0); bool lowPurgedH1 = (currentLowH1 < lastLowH1 && lastLowH1 > 0); bool lowPurgedH4 = (currentLowH1 < lastLowH4 && lastLowH4 > 0); bool lowPurgedD1 = (currentLowH1 < lastLowD1 && lastLowD1 > 0); bool highPurged = highPurgedH1 || highPurgedH4 || highPurgedD1; bool lowPurged = lowPurgedH1 || lowPurgedH4 || lowPurgedD1; // Update purge status if(highPurged || lowPurged) { purgeDetected = true; lastPurgeTime = currentTimeH1; highPurge = highPurged; } // Check if within the post-purge window bool withinPurgeWindow = false; if(purgeDetected) { int candlesSincePurge = iBarShift(_Symbol, TradeTimeframe, lastPurgeTime, true); withinPurgeWindow = candlesSincePurge <= MaxCandlesPostPurge; if(!withinPurgeWindow) { purgeDetected = false; // Reset if window expires Print("Purge window expired: ", candlesSincePurge, " candles since last purge"); } } // Check volume for liquidity confirmation bool volumeConfirmed = IsVolumeSpike(currentVolumeH1); if(currentVolumeH1 <= 1) { Print("Warning: Tick volume is ", currentVolumeH1, ". Possible data issue. Bypassing volume check."); volumeConfirmed = true; } // Check trend with SMA bool isBullishTrend = UseTrendFilter ? IsBullishTrend() : true; // Check for engulfing candles on H1 (current + previous 2 candles) bool bullishEngulfingH1 = false, bearishEngulfingH1 = false; for(int i = 0; i < 3; i++) { if(IsBullishEngulfing(ratesH1[i], ratesH1[i+1])) bullishEngulfingH1 = true; if(IsBearishEngulfing(ratesH1[i], ratesH1[i+1])) bearishEngulfingH1 = true; } // Check for engulfing candles on M15 (current + previous 2 candles) bool bullishEngulfingM15 = false, bearishEngulfingM15 = false; for(int i = 0; i < 3; i++) { if(IsBullishEngulfing(ratesM15[i], ratesM15[i+1])) bullishEngulfingM15 = true; if(IsBearishEngulfing(ratesM15[i], ratesM15[i+1])) bearishEngulfingM15 = true; } // Trade logic if(purgeDetected && withinPurgeWindow && !tradePlaced) { if(highPurge && (bullishEngulfingH1 || bullishEngulfingM15) && volumeConfirmed && isBullishTrend) { Print("Buy signal: High purged, bullish engulfing on ", bullishEngulfingH1 ? "H1" : "M15", ", volume confirmed, bullish trend"); PlaceTrade(ORDER_TYPE_BUY, currentCloseH1); } else if(!highPurge && (bearishEngulfingH1 || bearishEngulfingM15) && volumeConfirmed && !isBullishTrend) { Print("Sell signal: Low purged, bearish engulfing on ", bearishEngulfingH1 ? "H1" : "M15", ", volume confirmed, bearish trend"); PlaceTrade(ORDER_TYPE_SELL, currentCloseH1); } } }
Установка и бэктестинг: скомпилируйте советник в MetaEditor и прикрепите его к графику. Бэктестинг на GBPUSD, H1 (2025–2026) с риском 1%.
Тестирование стратегии
Тестирование стратегии на советнике Trending King EA
Стратегия хорошо работает на большинстве, если не на всех, валютных парах благодаря своей базовой логике и быстрой адаптации к трендовой торговле. Она использует концепцию снятия ликвидности для торговых сетапов и высокой волатильности, что полезно и важно для большинства торговых стратегий. Мы протестируем эту стратегию на GBPUSD за период с 1 января 2025 года по 8 января 2026 года на 60-минутном таймфрейме (H1). Ниже приведены параметры, которые я выбрал для этой стратегии.
GBPUSD


Результаты тестера стратегий
Ниже приведены результаты тестирования в тестере стратегий.
Результаты тестера стратегий для Trending King EA
График баланса/средств:
GBPUSD

Результаты бэктеста:
GBPUSD 
Резюме
Я написал эту статью, чтобы объяснить советник MetaTrader 5, специально адаптированный под следование за трендом. Он использует скорость и силу тренда, а также объединяет методы управления сделками и рисками, чтобы системно снижать риск, рыночную экспозицию и влияние человеческого фактора при выявлении и исполнении высоковероятных торговых сетапов на GBPUSD, а также возможных точек выхода с использованием того же протокола управления сделками и риском.
Этот советник является одним из самых простых, но при этом мощных торговых советников и трендовых подходов, используемых для поиска возможных точек входа и смены тренда. Надёжная и хорошо адаптируемая логика управления рисками и сделками помогает советнику работать на оптимальном уровне и минимизировать просадку и торговые убытки.
Я протестировал советник на GBPUSD, и он показал способность эффективно и достаточно точно определять возможные точки входа на любом таймфрейме. Однако определение точки входа — лишь часть общей задачи, поскольку в его ядро встроен механизм проверки входов, который разрешает исполнение только при выполнении заданных критериев. Как только сделки подтверждаются и исполняются, быстро включается логика управления сделкой и риском, обеспечивая корректное сопровождение до закрытия позиции.
Чтобы реализовать стратегию этого советника, настройте его входные параметры, как показано ниже, для получения желаемых результатов. Советник предназначен для поиска возможных входов на выбранном трейдером таймфрейме от M15 до D1, при этом потенциальные точки входа должны согласовываться с трендом, скользящими средними и Average True Range (ATR), используемым для трейлинг-стопа. Заинтересованным трейдерам следует протестировать этот советник на демо-счетах с GBPUSD. Он оптимизирован под GBPUSD и показывает на этой паре наилучшие результаты, но также может применяться к GBPJPY, EURUSD и GOLD. Главная задача этого советника — оптимизация строго трендовой торговли с продвинутой торговой логикой, высоковероятными сетапами на любом таймфрейме в зависимости от выбора трейдера, а также управление рисками с использованием реализованных трейлинг-стопов.
Я также советую трейдерам регулярно просматривать журналы эффективности, чтобы уточнять настройки и входные параметры в зависимости от своих целей, класса актива и склонности к риску. Отказ от ответственности: любой, кто использует этот советник, должен сначала протестировать его и начать торговлю на демо-счёте, чтобы освоить этот подход к следованию за трендом и торговую идею для стабильной прибыли, прежде чем рисковать реальными средствами.
Заключение
В статье выделены основные трудности, с которыми сталкиваются трейдеры: определение рыночного сценария, рыночного смещения, направления и силы тренда, управление рисками и сделками, а также избегание просадок. Также объясняется, как разработать советник, который упрощает этот процесс и повышает шансы на прибыльную торговлю и совершение только высоковероятных сделок. Далее в статье подробно показано, как этому способствует торговля только по направлению тренда и игнорирование контртрендовых идей и сетапов.
Многие трейдеры не до конца понимают, насколько сильно трендовая торговля может положительно повлиять на их результаты, особенно в сочетании с грамотным управлением риском и сделками. В таком случае она становится важным фактором, который отделяет средний уровень от лучших результатов. Предложенный советник помогает поддерживать дисциплину и позволяет трейдерам проверять свои торговые идеи, размер позиции и сетапы, даже если они не используют его входы напрямую.
В заключении автор перечисляет заявленные возможности советника. При этом фильтр новостей, адаптивное изменение размера лота и частичные закрытия в представленном фрагменте кода не показаны. Автоматизированный советник MQL5 обеспечивает:
- высоковероятные сделки в направлении тренда торгуемого актива;
- защиту от новостной волатильности за счёт блокировки сделок вблизи выхода новостей;
- входы в сделки только по подтверждённым сигналам с динамическими SL/TP;
- адаптивное управление риском: уменьшение размера лота во время серий убытков и увеличение во время прибыльных серий;
- журналирование результатов для постоянной оптимизации стратегии;
- строгое соблюдение принципа следования за трендом и торговли только по его направлению;
- исключение эмоционального принятия решений;
- автоматизированное управление сделками: SL, TP и частичные закрытия.
В совокупности описанные возможности должны обеспечивать последовательное совершение высоковероятных сделок и оптимальное управление рисками, повышая вероятность прибыльной торговли и улучшая результаты.
Весь код, упомянутый в статье, прикреплён ниже. В следующей таблице описаны все файлы исходного кода, сопровождающие статью.
| Название файла | Описание: |
|---|---|
| Trending King EA.mq5 | Файл, содержащий полный исходный код советника Trend King EA |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/19755
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Моделирование рынка: Position View (VIII)
Создание пользовательских индикаторов в MQL5 (Часть 3): Улучшение многошкальной визуализации с секторным и круговым стилями
Создание пользовательских индикаторов в MQL5 (Часть 4): Smart WaveTrend Crossover на основе двух осцилляторов
От начального до среднего уровня: Словно мыльные пузыри
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Спасибо всем; будьте здоровы и берегите себя
Тем, кто хочет попробовать / использовать Attention: там очень много PRINT() и очень много логов
Спасибо за всё; будьте здоровы и берегите себя
Тем, кто хочет попробовать / использовать Attention: так много PRINT() и так много логов