English Deutsch 日本語
preview
Оптимизация торговли на снятии ликвидности: Как различать снятие ликвидности и сдвиги рыночной структуры

Оптимизация торговли на снятии ликвидности: Как различать снятие ликвидности и сдвиги рыночной структуры

MetaTrader 5Трейдинг |
44 2
Eugene Mmene
Eugene Mmene

Введение

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

Вторая группа, которой эта статья будет особенно полезна, — трейдеры со средним уровнем подготовки и некоторым опытом торговли по этим концепциям, но с нестабильными результатами: иногда они успешно выбирают торговые сетапы, а иногда терпят серьёзные неудачи. Цель статьи — укрепить их базу знаний и подробно объяснить ключевую разницу между снятиями ликвидности и сдвигами рыночной структуры, чтобы уменьшить потери, возникающие из-за смешения этих понятий. В статье будет показано, что и снятия ликвидности, и сдвиги рыночной структуры при наиболее эффективном использовании могут быть эффективными и прибыльными. Также будет приведён чек-лист проверочных признаков для определения валидного сдвига рыночной структуры или снятия ликвидности, чтобы трейдер мог быстро сверяться с ним и подтверждать своё торговое решение, что помогает сохранять спокойствие и избегать как импульсивной торговли, так и паралича при исполнении решения.

Как трейдер, я знаю, что большинство начинающих трейдеров и трейдеров среднего уровня, использующих концепции ICT, сталкиваются с этой проблемой. Фактически все трейдеры в какой-то момент своей карьеры сталкиваются с похожими, если не идентичными, трудностями. Различие состоит в том, как они справляются с этими трудностями, реагируют на них и заранее их учитывают; именно это и создаёт огромную разницу в результатах даже между трейдерами, различающимися лишь незначительно по навыкам, опыту, самообладанию, качеству решений и технике. Та же проблема может называться иначе в рамках других концепций, например пробоев, поэтому статья будет полезна не только трейдерам, работающим с ICT-концепциями.

В статье подробно рассматривается советник, специально созданный для трейдеров, которые хотят научиться наиболее эффективно определять и использовать снятия ликвидности. Такие снятия обычно дают отличные торговые возможности при работе в рамках уже определённого тренда и рыночного сценария (narrative), позволяя избегать торговли против направления тренда. Советник также предназначен для выявления сдвигов рыночной структуры, возникающих в определённых точках рынка, например в конце тренда или при крупном развороте на старшем таймфрейме. Он оптимизирован для различения снятий ликвидности и сдвигов рыночной структуры, а также для определения того, какой из этих сценариев следует использовать при его появлении, чтобы трейдеры не принимали сдвиг структуры за снятие ликвидности и наоборот.

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



Определения: дисбалансы, сдвиги рыночной структуры и снятия ликвидности

В этом разделе я приведу определения и пояснения наиболее распространённых терминов и инструментов, которые мы будем использовать в статье. Я уверен, что не все читатели знакомы с этими концепциями; для кого-то это может быть первое знакомство с ними, поэтому важно сделать материал доступным и понятным для всех.

1. Дисбалансы/неэффективности

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

Это можно наглядно объяснить на примере маляра: когда он красит стену, ему нужно наносить краску равномерными или хотя бы сопоставимыми мазками в противоположных направлениях, чтобы покрытие получилось ровным и качественным. По той же логике движется и цена. Когда бычья свеча резко проходит через ценовой диапазон, например от 1.3010 до 1.3030, для баланса требуется встречное медвежье движение через ту же область. Если такого движения нет, возникает дисбаланс. Часто, если не всегда, цена со временем возвращается в эту область. Это может происходить на любом таймфрейме.

image showing price Imbalance

2. Сдвиги рыночной структуры

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

Кроме того, чтобы сдвиги рыночной структуры имели высокую вероятность успеха, а не оказывались ложными сдвигами структуры, Judas swing (ложным выносом или манипулятивным импульсом) либо обычными снятиями ликвидности, цена должна исходить из ключевых зон интереса участников рынка, которые мы часто называем ликвидностью. Сдвиги рыночной структуры, возникающие после снятия ликвидности, имеют высокую вероятность успеха. Это явление может появляться на любом таймфрейме — от M1 до MN.

Market structure shift

3. Снятия ликвидности

Ликвидность — это ключевые зоны интереса участников рынка, которые институциональные участники часто отмечают как потенциальные области, где можно закрыть ранее открытые длинные или короткие позиции либо открыть новые сделки. Эти области важны потому, что именно там розничные трейдеры часто размещают стоп-лоссы или открывают сделки на пробой, создавая ликвидность для институциональных участников. Когда срабатывают buy stop, sell stop и стоп-лоссы, институциональные участники в этот момент также активируют свои сделки, используя появившуюся ликвидность; именно поэтому такое событие называют снятием ликвидности.

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

Image showing liquidity purge



Разбор того, как возникают снятия ликвидности и сдвиги рыночной структуры

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

Статья и советник помогают согласовывать сделки, открываемые после снятия ликвидности, с направлением тренда, избегая краткосрочных сделок против тренда. Это позволит трейдерам, которые ещё формируют навык, стать увереннее и внимательнее при открытии сделок, поскольку со временем они научатся использовать снятия ликвидности только в соответствии с текущим трендом и рыночным сценарием. Когда направление тренда и рыночный сценарий определены, остаётся найти правильный торговый сетап после снятия ликвидности или сдвига рыночной структуры.

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

Сделки, открытые с учётом силы и направления тренда, обычно лучше переносят неточности точки входа. Иногда они могут принести существенную дополнительную прибыль, если трейдер достаточно терпелив и дожидается продолжения общего тренда после разворотов или снятий ликвидности.

Кроме того, сделки, которые анализируются, открываются и сопровождаются с учётом направления тренда, как правило, оказываются точнее и имеют меньшую просадку, поскольку цена быстрее движется к целевым уровням и делает это с меньшими откатами. Свинг-движения цены в направлении тренда, как правило, более мощные, поэтому даже при временной просадке цена вскоре может вернуться к движению в соответствии с направлением и силой текущего трендового сценария.

Лучший способ определить сценарий и тренд — использовать старшие таймфреймы, главным образом W1 и D1, и внимательно их просматривать и анализировать. Первый шаг, который выполняет советник и который также можно выполнить вручную, — использовать простые и экспоненциальные скользящие средние, чтобы получить хотя бы общее представление о том, находится ли рынок в тренде или в консолидации. Трендовые рынки дают гораздо более безопасные и качественные торговые возможности. Тренд определяется, когда 9-периодная простая скользящая средняя находится ниже или выше 21-периодной скользящей средней и имеет выраженный восходящий или нисходящий наклон, а сами средние выстроены каскадом в направлении тренда. Второй важный шаг — проанализировать поведение цены на этих двух старших таймфреймах и определить, куда направляется цена. Именно так тренд достаточно просто определяется как бычий или медвежий.

После того как тренд определён и установлено, что цена не находится в консолидации, следующий шаг — определить текущий рыночный сценарий, то есть понять, к чему стремится цена. В рамках этой концепции считается, что цена всегда стремится к трём ориентирам: ликвидности, PD arrays или дисбалансам, а также чаще всего переходит от одной точки ликвидности к другой. Здесь проявляется основное назначение советника: когда ликвидность снимается в таких ключевых областях, как минимум предыдущего дня, недели или месяца либо относительно равные минимумы, можно ожидать сдвига рыночной структуры, поскольку оснований для прежнего сценария продаж больше не остаётся. Такой сдвиг может возникнуть на более низком таймфрейме, например H1, H4 или M15, и запустить новый сценарий покупок — движение к ближайшей ликвидности.

Так советник отслеживает и использует сигналы сдвига рыночной структуры. Что касается сделок после снятия ликвидности, они выполняются следующим образом: когда рыночный сценарий уже определён, внимание переносится на более низкие таймфреймы, такие как M15, M5 и M1. Эти таймфреймы подходят для внутридневной торговли и почти ежедневно дают потенциальные торговые сетапы.

Движение цены во многом зависит от времени, прежде всего от ключевых торговых часов основных сессий. Если рыночный сценарий бычий, на недавних минимумах может возникнуть так называемый Judas swing или снятие ликвидности. После снятия ликвидности и ложного пробоя цена уходит из этой области с силой и скоростью, что служит убедительным признаком того, что произошло именно снятие ликвидности. Иногда при таком движении возникает дисбаланс, который можно использовать для входа в новую позицию. Появление дисбаланса — сильный признак снятия ликвидности.

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

Image showing liquidity purge



Автоматизация торговых решений с помощью советника Liquidity Grab в MQL5

Для автоматизации, иллюстрации и реализации этой стратегии я создал:

  • советник для торговли после снятия ликвидности, который анализирует тренды и рыночный сценарий, а также открывает сделки по потенциальным точкам входа только в направлении тренда и сценария после снятия ликвидности, используя трейлинг-стоп и скользящие средние для определения тренда.

Процесс принятия решений

Решения этого советника — определение тренда, выявление ликвидности, анализ поведения цены и исполнение сделок — основаны на следующей логике:

Исходный код советника Liquidity Grab:

Этот советник выявляет потенциальные торговые сигналы, соответствующие общему направлению тренда и рыночному сценарию, и ожидает торговые сетапы только после снятия ликвидности. Он избегает позиций против тренда или сделок без предшествующего снятия ликвидности. Советник также использует экспоненциальные и простые скользящие средние для определения общего направления тренда перед входом в сделки и применяет логику трейлинг-стопа для расчёта уровней стоп-лосса и защиты капитала при благоприятном движении цены. В него включено управление риском — 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`, `ConfirmationTimeframe`, `MaxCandlesPostPurge`, `VolumeThreshold`, `UseTrendFilter` и `SMAPeriod` в описании приведены значения H1, M15, 3, 1.0, true и 50 соответственно.

//+-------------------------------------------------------------------------------+
//|                 Liquidity GrabEA.mq5                                          |
//| Expert Advisor for MetaTrader 5                                               |
//| Description:Trades based on liquidity grabs and market structure shifts, waits|
//| for trade set ups after liquidity grab, with flexible execution.              |
//+-------------------------------------------------------------------------------+
#property copyright "Eugene Mmene"
#property link "https://www.EMcapital.com"
#property version "1.10"
//--- Input parameters
input double LotSize = 0.05;                             // Lot size for trades
input int LookbackBars = 1;                              // Number of bars to check for highs/lows
input double StopLossPips = 20.0;                        // Stop loss in pips (adjusted for GOLD#)
input double TakeProfitPips = 60.0;                      // Take profit in pips (adjusted for GOLD#)
input double TrailingStopPips = 30.0;                    // Trailing stop in pips
input double BreakevenPips = 20.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), чтобы обеспечить совместимость с многотаймфреймовым подходом стратегии, и отклоняет недопустимые входные значения для предотвращения ошибок. Функция получает размер контракта символа с помощью `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` проверяет, сформировалась ли новая свеча на основном торговом таймфрейме (по умолчанию H1), сравнивая временную метку текущей свечи (`iTime`) с последним сохранённым временем (`lastCandleTime`). Если обнаружена новая свеча, `lastCandleTime` обновляется, а функция возвращает `true`, запуская основную торговую логику в `OnTick`. Благодаря этому советник оценивает торговые условия только один раз на каждой новой свече H1, снижая вычислительную нагрузку и предотвращая повторные проверки во время волатильных внутрисвечных движений GBPUSD и GBPJPY. Работа только с новыми барами соответствует логике стратегии, которая опирается на завершённые свечные данные для выявления снятий ликвидности и моделей поглощения, необходимых для определения значимых ценовых движений на трендовых рынках GBP-пар. Эта простая функция играет важную роль в поддержании эффективности и точности советника.

bool IsNewCandle()
{
   datetime currentCandleTime = iTime(_Symbol, TradeTimeframe, 0);
   if(currentCandleTime != lastCandleTime)
   {
      lastCandleTime = currentCandleTime;
      return true;
   }
   return false;
}

Функция UpdateHighsLows: отслеживание уровней снятия ликвидности

Функция `UpdateHighsLows` отслеживает самые высокие максимумы и самые низкие минимумы за последние `LookbackBars` (по умолчанию 3) на таймфреймах 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` (3) в `VolumeThreshold` (1.0) раза. Она использует `CopyRates` для получения последних свечей на торговом таймфрейме H1 и рассчитывает средний объём по корректным барам — тем, у которых объём превышает 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) на торговом таймфрейме (H1) для определения направления рыночного тренда. Она создаёт дескриптор 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 &current, 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 &current, 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), тип ордера (покупка или продажа) и цену входа. Стоп-лосс устанавливается на расстоянии 150 пипсов, а тейк-профит — 600 пипсов с учётом размера пункта EURUSD, GBPUSD и GBPJPY (`_Point * 100`) и масштаба их котировок. Режим `ORDER_FILLING_IOC` (немедленное исполнение или отмена) обеспечивает быстрое исполнение, что особенно важно на быстро движущемся рынке 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` (100 пипсов), с учётом размера пипса и особенностей котировки GBPUSD, EURUSD и GBPJPY. Новый стоп-лосс применяется только если он выше текущего стоп-лосса и выше цены открытия, обеспечивая безубыток или прибыль. Для позиций на продажу стоп-лосс устанавливается выше текущей цены 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` — основной обработчик торговой логики советника. Она выполняется на каждом тике цены, но обрабатывает данные только при появлении новых H1-свечей через `IsNewCandle`. Если открытых позиций нет, она сбрасывает `tradePlaced`, обеспечивая не более одной сделки на каждый цикл снятия ликвидности. Трейлинг-стопы для открытых позиций сопровождаются через `ManageTrailingStop`. Функция загружает данные свечей H1 и M15 с помощью `CopyRates` и сравнивает текущую H1-свечу с предыдущими максимумами/минимумами, обновлёнными через `UpdateHighsLows`, чтобы обнаружить снятия ликвидности: пробой ценой максимумов H1/H4/D1 или минимумов, что указывает на снятие ликвидности, часто встречающееся на EURUSD, GBPUSD/GBPJPY во время ключевых сессий. При обнаружении снятия ликвидности устанавливается `purgeDetected`, а `lastPurgeTime` отслеживает окно до 3 H1-свечей.

Объём подтверждается через `IsVolumeSpike`, а тренд проверяется через `IsBullishTrend` при включённом фильтре. Паттерны поглощения выявляются как на H1, так и на M15, что обеспечивает гибкое подтверждение. Сделка на покупку открывается, если снята ликвидность над максимумом и это сопровождается бычьей свечой поглощения (H1 или M15), высоким объёмом и бычьим трендом; для сделки на продажу требуется снятие ликвидности под минимумом, медвежье поглощение, высокий объём и медвежий тренд. Подробное журналирование обеспечивает прозрачность для отладки. Эта логика повышает вероятность сделок на 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 и прикрепите к графику. Бэктестирование на GBPJPY, H1 (ноябрь 2025 — февраль 2026) с риском 1%.



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

Тестирование стратегии на советнике Liquidity Grab

По замыслу автора, стратегия хорошо работает на большинстве, если не на всех, валютных парах благодаря базовой логике и способности адаптироваться к трендовой торговле и рыночному сценарию. Она использует снятие ликвидности как основу для поиска торговых сетапов в условиях повышенной волатильности, поэтому может применяться в разных торговых подходах. Стратегия тестируется на GBPJPY с 1 января 2025 года по 8 февраля 2026 года на 60-минутном таймфрейме H1. Ниже приведены выбранные для тестирования параметры.

GBPJPY

Input data

Input data


Результаты тестера стратегий

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

Результаты тестера стратегий для советника Liquidity Grab

График баланса и средств: 

GBPJPY

results graph

Результаты бэктеста:

GBPJPY

Backtest results


Резюме

Я написал эту статью, чтобы описать советник MetaTrader 5, специально адаптированный для следования тренду. Он различает снятия ликвидности и сдвиги рыночной структуры, а затем использует распознанный сценарий в торговой логике, а также включает методы управления сделками и рисками для системного снижения риска, рыночной экспозиции и количества человеческих ошибок при выявлении и исполнении высоковероятных торговых сетапов на GBPJPY, включая возможные точки выхода по тому же протоколу управления сделками и рисками.

Этот советник является простым, но функциональным торговым советником. Он использует трендовые концепции и снятия ликвидности для поиска потенциальных точек входа и сдвигов тренда. Устойчивая и адаптивная логика управления рисками и сделками помогает советнику работать более последовательно и минимизировать просадку и торговые убытки.

Я протестировал советник на GBPJPY, и он показал способность эффективно и точно выявлять потенциальные точки входа на любом таймфрейме. Однако обнаружение точки входа — лишь часть задачи, поскольку в ядро логики встроена оптимальная стратегия подтверждения входа, которая допускает исполнение только при выполнении определённых критериев. Как только сделки подтверждаются и исполняются, активируется логика управления сделкой и риском, обеспечивающая корректное сопровождение до закрытия позиции.

Чтобы применить стратегию этого советника, настройте его входные параметры, как показано ниже, для получения желаемых результатов. Советник предназначен для поиска ликвидности, снятий ликвидности и потенциальных точек входа на выбранном трейдером таймфрейме от M15 до D1. Он следит за тем, чтобы потенциальные точки входа соответствовали тренду, скользящим средним и среднему истинному диапазону, используемому для трейлинг-стопа. Заинтересованным трейдерам следует протестировать советник на демо-счетах с GBPJPY. Он оптимально работает и разработан прежде всего для GBPJPY, но также может применяться к GBPUSD, EURUSD и GOLD.

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

Я также рекомендую трейдерам регулярно просматривать журналы работы советника и торговой статистики, чтобы уточнять настройки и входные параметры в зависимости от своих целей, класса актива и склонности к риску. Отказ от ответственности: любой, кто использует этот советник, должен сначала протестировать его и начать торговлю на демо-счёте, чтобы освоить концепцию снятия ликвидности и подход к формированию торговых решений, прежде чем рисковать реальными средствами.


Заключение

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

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

В заключительном описании автор заявляет о следующих возможностях автоматизированного советника MQL5:

  • поиск высоковероятных сделок по торговым сетапам, возникающим после снятия ликвидности торгуемого актива;
  • защита от новостной волатильности за счёт ограничения торговли вокруг новостных релизов;
  • входы в сделки только по подтверждённым сигналам и заданной логике входа с динамическими SL/TP;
  • адаптивное управление риском с изменением размера лота в зависимости от серии результатов;
  • журналирование работы советника и торговой статистики для дальнейшей оптимизации стратегии;
  • предварительное определение текущего рыночного сценария и типа сетапа, например сдвига рыночной структуры или снятия ликвидности;
  • устранение эмоционального фактора при принятии торговых решений;
  • автоматизированное сопровождение сделок с использованием SL, TP и частичного закрытия позиций.

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

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

Название файлаОписание:
Liquidity Grab EA.mq5Файл, содержащий полный исходный код советника Liquidity Grab

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

Прикрепленные файлы |
Liquidity_Grab.mq5 (16.29 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (2)
Mustafa Nail Sertoglu
Mustafa Nail Sertoglu | 16 февр. 2026 в 17:42
При вставке кода используйтекнопку «CODE» (Alt-S).

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

Спасибо за новую версию; НО вы уверены, что код в файле ТОТ ЖЕ, ЧТО И В СТАТЬЕ!

(Например, я не смог найти

..

    lastHighH1 = ratesH4[0].high;

      lastLowH1  = ratesH4[0].low;

..

      lastHighH4 = ratesH4[0].high;

      lastLowH4  = ratesH4[0].low;

.. и т. д.


, но в коде указано следующее (это из вашей старой статьи «Trending King» **, но там также есть теги h1/h4/D1 по состоянию на 16 февраля 2026 года ;;; Я СОВСЕМ ЗАПУТАНСЯ В ЭТИХ КОДАХ! ! ! ):

//+------------------------------------------------------------------+

//| Обновление максимального максимума и минимального минимума для TradeTimeframe |

//+------------------------------------------------------------------+

void UpdateHighsLows()

{

   MqlRates rates[];

   ArraySetAsSeries(rates, true);

   if(CopyRates(_Symbol, TradeTimeframe, 1, LookbackBars, rates) >= LookbackBars)

   {

      lastHigh = rates[0].high;

      lastLow = rates[0].low;

      for(int i = 1; i < LookbackBars; i++)

      {

         if(rates[i].high > lastHigh) lastHigh = rates[i].high;

         if(rates[i].low < lastLow) lastLow = rates[i].low;

      }

   }

   else Print("Failed to load TradeTimeframe rates");

}
Eugene Mmene
Eugene Mmene | 16 февр. 2026 в 20:10
Mustafa Nail Sertoglu #:

Спасибо за новую версию; НО вы уверены, что коды в файле ТОЧНО ТАКИЕ ЖЕ, КАК В СТАТЬЕ?

(например, я не смог найти

..

..

.. и т. д.


но в кодах указано следующее (это из вашей старой статьи «Trending King» **, но там также указаны h1/h4/D1 по состоянию на 16 февраля 2026 года ;;; Я ТАК ЗАПУТАНА С ЭТИМИ КОДАМИ ! ! ! ):

Здравствуйте, да, показанные коды и те, что в файле, совпадают

Причина, по которой вы, похоже, запутались, заключается в том, что это не обязательно обновление советника Trending King, но он заимствовал некоторые концепции из того советника, да, но не все, а также имеет некоторые другие модификации и изменения, так что давайте просто скажем, что это усовершенствованная версия
Особенности написания Пользовательских Индикаторов Особенности написания Пользовательских Индикаторов
Написание пользовательских индикаторов в торговой системе MetaTrader 4
Встраивание торговой дисциплины в код (Часть 5): Контроль соблюдения риск-ограничений на уровне счёта в MQL5 Встраивание торговой дисциплины в код (Часть 5): Контроль соблюдения риск-ограничений на уровне счёта в MQL5
Мы представляем модуль контроля рисков на MQL5, который обеспечивает последовательное соблюдение правил риска на уровне счета. Он непрерывно сканирует позиции из любых источников, проверяет уровни стоп-лосса и тейк-профита, риск-экспозицию на основе эквити и целевое соотношение R:R, а также автоматически корректирует отклонения, устанавливая уровни или корректируя объем. В результате получается единый риск-профиль для ручных и автоматизированных сделок, с поддержкой визуальной обратной связи на графике и режимного управления.
Особенности написания экспертов Особенности написания экспертов
Написание и тестирование экспертов в торговой системе MetaTrader 4.
Создание пользовательских индикаторов в MQL5 (Часть 7): Гибридные рыночные профили Time Price Opportunity (TPO) для анализа сессий Создание пользовательских индикаторов в MQL5 (Часть 7): Гибридные рыночные профили Time Price Opportunity (TPO) для анализа сессий
В этой статье мы разрабатываем пользовательский индикатор на MQL5 для гибридных TPO-профилей с поддержкой нескольких сессионных периодов: внутридневных, дневных, недельных, месячных и фиксированных периодов с учётом часового пояса. Индикатор дискретизирует цены по сетке, отслеживает данные сессии, включая максимумы, минимумы, цены открытия и закрытия, а также рассчитывает ключевые элементы, такие как точка контроля (POC) и зона стоимости (value area) на основе количества TPO. Он визуально отображает профили на графике с настраиваемыми цветами для букв TPO, одиночных отпечатков (single prints), зон стоимости, POC и маркеров закрытия, позволяя выполнять подробный анализ сессий.