English
preview
Рыночные секреты Ларри Уильямса (Часть 14): Обнаружение разворотов Hidden Smash Day с помощью пользовательского индикатора

Рыночные секреты Ларри Уильямса (Часть 14): Обнаружение разворотов Hidden Smash Day с помощью пользовательского индикатора

MetaTrader 5Индикаторы |
88 2
Chacha Ian Maroa
Chacha Ian Maroa

Введение

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

Для алгоритмических трейдеров и разработчиков MQL5 такая неоднозначность становится практической проблемой. Торговым системам нужны детерминированные правила, которые одинаково работают на исторических данных и при исполнении в реальном времени. Поэтому такие понятия, как «нижняя часть бара» или «подтверждение уровня, заданного Smash-баром», необходимо переводить в точные числовые условия, чтобы обнаружение сигналов оставалось стабильным при каждом запуске.

Практическое решение — формализовать правила Hidden Smash Day и реализовать их в инструменте, который автоматически обнаруживает такие сетапы. В этой статье разрабатывается пользовательский индикатор MQL5, который формализует паттерн Hidden Smash Day с помощью объективных условий: положение закрытия внутри диапазона бара, его соотношение с предыдущим закрытием и логику подтверждения на следующей сессии.

Когда обнаруживается сетап, соответствующий условиям, индикатор визуально отмечает его на графике. Под барами Hidden Smash Day Buy, соответствующими условиям, появляется стрелка цвета морской волны, а над барами Hidden Smash Day Sell, соответствующими условиям, — черная стрелка. Эти сигналы дают объективный ориентир, который помогает трейдерам быстро заметить паттерн и при необходимости применить дополнительные контекстные фильтры.

Индикатор разработан прежде всего для алгоритмических трейдеров, которые хотят объективно описать сетап Hidden Smash Day Ларри Уильямса и автоматизировать его обнаружение, сохранив при этом возможность использовать сигнал в дискреционном анализе. Далее в статье объясняется структура индикатора, логика обнаружения, с помощью которой паттерн формализуется, а также работа инструмента на исторических данных и при обновлении графика в реальном времени.


Понимание разворотных паттернов Hidden Smash Day

Паттерны Hidden Smash Day — это особая разновидность разворотов Smash Day Ларри Уильямса. На первый взгляд такие бары поддерживают текущее направление рынка. Однако более внимательный анализ их внутренней структуры показывает скорее слабость, чем силу. Именно это противоречие между внешним видом и реальностью и дает паттерну его название.

Ключевая идея Hidden Smash Day — неудача попытки движения. В течение сессии рынок пытается сильно продвинуться в одном направлении, но к закрытию эта попытка отвергается. Хотя цена может завершить сессию немного выше или ниже, положение закрытия внутри бара рассказывает совсем другую историю.

Сетап Hidden Smash Day Buy

Сетап Hidden Smash Day Buy начинается с бара, который закрывается выше предыдущего бара. Внешне это выглядит бычьим признаком. Однако важная деталь заключается в том, где именно это закрытие находится внутри собственного диапазона бара.

Hidden Smash Day Buy Bar

Для валидного бара Hidden Smash Day Buy закрытие должно находиться в нижней части диапазона бара. В самых сильных версиях паттерна закрытие также расположено ниже цены открытия. Это означает, что, хотя сессия завершилась повышением, покупатели не смогли удержать большую часть прироста, полученного ранее внутри бара. Рост встретил давление продавцов, и покупательская инициатива фактически была нейтрализована.

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

Бычий сигнал подтверждается только в том случае, если следующий бар закрывается выше максимума бара Hidden Smash Day. Когда это происходит, это показывает, что неудавшееся движение было развернуто, а спрос вернулся с достаточной силой, чтобы преодолеть предыдущее отвержение. Эта последовательность неудачной попытки движения и немедленного восстановления образует основу разворота Hidden Smash Day Buy.

Сетап Hidden Smash Day Sell

Сетап Hidden Smash Day Sell является зеркальным отражением паттерна на покупку. В этом случае бар закрывается ниже предыдущего бара, что сначала выглядит медвежьим признаком. Но и здесь реальную картину показывает внутренняя структура.

Hidden Smash Day Sell Bar

Для валидного бара Hidden Smash Day Sell закрытие должно находиться в верхней части диапазона бара. В самых сильных вариантах паттерна закрытие также расположено выше цены открытия. Это показывает, что продавцы в течение сессии продавили цену вниз, но не смогли сохранить контроль. Перед закрытием цена восстановилась к максимумам, указывая на слабость давления продавцов.

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

Медвежий сигнал подтверждается только в том случае, если следующий бар закрывается ниже минимума бара Hidden Smash. Такой пробой вниз подтверждает, что попытка восстановления не удалась, а давление продавцов вернулось с достаточной силой. Паттерн снова следует той же логике: неудачная попытка движения и немедленный разворот.

Паттерны Hidden Smash Day не пытаются предсказывать развороты; они ждут, пока рынок сам проявит слабость, а затем подтверждают смещение через анализ движения цены (price action). Это делает их особенно полезными в рамках торговой системы с формализованными правилами и сильным кандидатом для системной автоматизации.


Как устроен индикатор Hidden Smash Day

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

Визуальный язык индикатора намеренно прост. Стрелка вверх цвета морской волны строится непосредственно под баром Hidden Smash Day Buy. Она выделяет моменты, когда бычье давление в течение сессии не смогло удержаться, создавая условия для потенциального разворота вверх. В противоположном случае черная стрелка вниз строится над баром Hidden Smash Day Sell. Она отмечает ситуации, в которых давление продавцов сначала выглядело доминирующим, но в итоге сорвалось, нередко предшествуя развороту вниз. Размещая стрелки прямо у бара, на котором формируется паттерн, индикатор позволяет легко находить такие сетапы без перегрузки графика.

Помимо визуальной части, ключевой элемент дизайна — гибкость. Паттерны Hidden Smash Day можно трактовать по-разному в зависимости от торгового стиля и предпочтений по подтверждению. Поэтому индикатор поддерживает два режима обнаружения, выбираемые через входные параметры.

В первом режиме бар Hidden Smash Day отмечается сразу после формирования, если он соответствует критериям Ларри Уильямса. Этот режим полезен трейдерам, которые хотят заранее видеть потенциальные развороты и предпочитают внимательно отслеживать поведение цены после появления сетапа.

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

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

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

Indicator Demo

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


Реализация индикатора Hidden Smash Day в MQL5

Когда основная идея разворотов Hidden Smash Day определена, следующий шаг — превратить эту концепцию в рабочий пользовательский индикатор. В этом разделе мы начинаем практическую реализацию с использованием MQL5. Цель здесь не в том, чтобы как можно быстрее перейти к сигналам, а в том, чтобы заложить чистую и надежную основу для точного обнаружения паттернов Hidden Smash Day и их отметки на графике.

Перед написанием логики важно правильно подготовить среду разработки. Для этого нужно базовое понимание синтаксиса MQL5, знакомство с терминалом MetaTrader 5 и уверенная работа в MetaEditor. При наличии этих базовых навыков можно двигаться дальше и пошагово строить индикатор.

Полная реализация индикатора приложена к этой статье под именем lwHiddenSmashDayIndicator.mq5. Настоятельно рекомендуется писать код параллельно с руководством. Ручной набор кода и сравнение результата с приложенной версией помогают закрепить понимание и упрощают диагностику проблем, если они возникнут.

Создание каркаса индикатора

Мы начинаем с создания нового пустого файла Custom Indicator в MetaEditor. Имя файла можно выбрать свободно, хотя использование того же имени, что и у приложенного исходника, помогает сохранить единообразие. После создания файла в него вставляется начальный шаблонный код.

//+------------------------------------------------------------------+
//|                                    lwHiddenSmashDayIndicator.mq5 |
//|          Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian |
//|                          https://www.mql5.com/en/users/chachaian |
//+------------------------------------------------------------------+

#property copyright "Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian"
#property link      "https://www.mql5.com/en/users/chachaian"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Custom Indicator specific directives                             |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_plots 2
#property indicator_buffers 2

//+------------------------------------------------------------------+
//| Defines how Hidden Smash Day patterns are validated              |
//+------------------------------------------------------------------+
enum ENUM_HIDDEN_SMASH_VALIDATION_MODE
{
   HIDDEN_SMASH_BAR_ONLY,
   HIDDEN_SMASH_CONFIRMED
};

//+------------------------------------------------------------------+
//| Hidden Smash Detection Settings                                  |
//+------------------------------------------------------------------+
input ENUM_HIDDEN_SMASH_VALIDATION_MODE hiddenSmashValidationMode = HIDDEN_SMASH_CONFIRMED;

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT;

//+------------------------------------------------------------------+
//| Indicator buffers                                                |
//+------------------------------------------------------------------+
double buySmashArrowBuffer [];
double sellSmashArrowBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){

   //--- To configure the chart's appearance
   if(!ConfigureChartAppearance()){
      Print("Error while configuring chart appearance ", GetLastError());
      return INIT_FAILED;
   }

   return(INIT_SUCCEEDED);
} 
 
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t  rates_total,
                const int32_t  prev_calculated,
                const datetime &time[],
                const double   &open[],
                const double   &high[],
                const double   &low[],
                const double   &close[],
                const long     &tick_volume[],
                const long     &volume[],
                const int32_t  &spread[])
{  

   ArraySetAsSeries(open,  false);
   ArraySetAsSeries(high,  false);
   ArraySetAsSeries(low,   false);
   ArraySetAsSeries(close, false);

   //--- Temporary buffers used to store price data for rendering custom colored candles
   double lwOpen [];
   double lwHigh [];
   double lwLow  [];
   double lwClose[];
   
   //--- Copy price data into local working buffers to safely manipulate candle values without altering the original price arrays
   ArrayCopy(lwOpen, open);
   ArrayCopy(lwHigh, high);
   ArrayCopy(lwLow, low);
   ArrayCopy(lwClose, close); 

   //--- This block will be executed whenever the indicator is initially attached to a chart
   if(prev_calculated == 0){
      
      //--- Start with clean arrays
      
   }
   
   //--- This block is executed on new bar open
   if(prev_calculated != rates_total && prev_calculated != 0){
      
      //--- Update buffers on new bar open
   
   }
   
   //--- This block is executed on arrival of new price (tick) data
   if(prev_calculated == rates_total){
      
      //--- Update buffers on new tick
      
   }
   
   return(rates_total);
}

//+------------------------------------------------------------------+
//| This function configures the chart's appearance.                 |
//+------------------------------------------------------------------+
bool ConfigureChartAppearance()
{
   if(!ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite)){
      Print("Error while setting chart background, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_SHOW_GRID, false)){
      Print("Error while setting chart grid, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_MODE, CHART_CANDLES)){
      Print("Error while setting chart mode, ", GetLastError());
      return false;
   }

   if(!ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack)){
      Print("Error while setting chart foreground, ", GetLastError());
      return false;
   }

   if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrSeaGreen)){
      Print("Error while setting bullish candles color, ", GetLastError());
      return false;
   }
      
   if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrBlack)){
      Print("Error while setting bearish candles color, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_COLOR_CHART_UP, clrSeaGreen)){
      Print("Error while setting bullish candles color, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrBlack)){
      Print("Error while setting bearish candles color, ", GetLastError());
      return false;
   }
   
   return true;
}

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

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

Свойства индикатора и метаданные

//+------------------------------------------------------------------+
//|                                    lwHiddenSmashDayIndicator.mq5 |
//|          Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian |
//|                          https://www.mql5.com/en/users/chachaian |
//+------------------------------------------------------------------+

#property copyright "Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian"
#property link      "https://www.mql5.com/en/users/chachaian"
#property version   "1.00"

Первый раздел исходного файла задает общие метаданные: сведения об авторских правах, номер версии и ссылку. Эти объявления не являются простой формальностью. Они проясняют авторство и помогают отслеживать версии по мере развития индикатора.

Сразу после этого объявляются директивы, специфичные для индикатора. Они сообщают терминалу, что индикатор будет отрисовываться непосредственно в окне графика и будет использовать две серии отрисовки и два буфера. Это решение соответствует проектной цели: визуально отмечать как бычьи, так и медвежьи бары Hidden Smash с помощью стрелок.

Настройка режима валидации

Паттерны Hidden Smash Day можно трактовать несколькими способами. Одни трейдеры предпочитают видеть паттерн сразу после формирования бара, другие требуют подтверждения следующим баром. Для поддержки обоих подходов определяется пользовательское перечисление.

//+------------------------------------------------------------------+
//| Defines how Hidden Smash Day patterns are validated              |
//+------------------------------------------------------------------+
enum ENUM_HIDDEN_SMASH_VALIDATION_MODE
{
   HIDDEN_SMASH_BAR_ONLY,
   HIDDEN_SMASH_CONFIRMED
};

Перечисление режима валидации вводит два четких варианта. Один вариант отмечает бар Hidden Smash Day сразу на основе его внутренней структуры. Другой отмечает бар только после подтверждения на следующей сессии. Этот выбор вынесен во входной параметр, поэтому индикатор может адаптироваться к разным стилям анализа без изменения кода.

//+------------------------------------------------------------------+
//| Hidden Smash Detection Settings                                  |
//+------------------------------------------------------------------+
input ENUM_HIDDEN_SMASH_VALIDATION_MODE hiddenSmashValidationMode = HIDDEN_SMASH_CONFIRMED;

Благодаря раннему введению этой настройки логика индикатора остается гибкой и не опирается на жестко зашитые предположения.

Глобальная область и работа с таймфреймом

Объявляется глобальная переменная таймфрейма, которой задается текущий таймфрейм графика.

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT;

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

Такой подход сохраняет соответствие индикатора принципам Ларри Уильямса и при этом позволяет ему работать на разных таймфреймах.

Буферы индикатора и визуальный вывод

Объявляются два буфера индикатора.

//+------------------------------------------------------------------+
//| Indicator buffers                                                |
//+------------------------------------------------------------------+
double buySmashArrowBuffer [];
double sellSmashArrowBuffer[];

Один буфер зарезервирован для бычьих баров Hidden Smash Day, второй — для медвежьих баров Hidden Smash Day. Позднее эти буферы будут хранить ценовые значения, в которых должны отрисовываться стрелки.

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

Визуальная идея проста и намеренна. Под бычьим баром Hidden Smash будет отрисовываться стрелка цвета морской волны, а над медвежьим баром Hidden Smash — черная стрелка. Такой выбор цвета и расположения создает мгновенный визуальный контраст и помогает трейдерам быстро находить потенциальные зоны разворота.

Логика инициализации

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){

   //--- To configure the chart's appearance
   if(!ConfigureChartAppearance()){
      Print("Error while configuring chart appearance", GetLastError());
      return INIT_FAILED;
   }

   return(INIT_SUCCEEDED);
}

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

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

Расчетный каркас

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t  rates_total,
                const int32_t  prev_calculated,
                const datetime &time[],
                const double   &open[],
                const double   &high[],
                const double   &low[],
                const double   &close[],
                const long     &tick_volume[],
                const long     &volume[],
                const int32_t  &spread[])
{  

   ArraySetAsSeries(open,  false);
   ArraySetAsSeries(high,  false);
   ArraySetAsSeries(low,   false);
   ArraySetAsSeries(close, false);

   //--- Temporary buffers used to store price data for rendering custom colored candles
   double lwOpen [];
   double lwHigh [];
   double lwLow  [];
   double lwClose[];
   
   //--- Copy price data into local working buffers to safely manipulate candle values without altering the original price arrays
   ArrayCopy(lwOpen, open);
   ArrayCopy(lwHigh, high);
   ArrayCopy(lwLow, low);
   ArrayCopy(lwClose, close); 

   //--- This block will be executed whenever the indicator is initially attached on a chart
   if(prev_calculated == 0){
      
      //--- Start with clean arrays
      
   }
   
   //--- This block is executed on new bar open
   if(prev_calculated != rates_total && prev_calculated != 0){
      
      //--- Update buffers on new bar open
   
   }
   
   //--- This block is executed on arrival of new price (tick) data
   if(prev_calculated == rates_total){
      
      //--- Update buffers on new tick
      
   }
   
   return(rates_total);
}

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

Ценовые массивы обрабатываются аккуратно: они копируются в локальные рабочие буферы. Это позволяет безопасно работать с данными, не изменяя исходные ценовые ряды, предоставленные терминалом.

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

Такое разделение сделано намеренно. Паттерны Hidden Smash Day зависят от завершенных баров и логики подтверждения. Организуя поток выполнения заранее, мы обеспечиваем обнаружение паттернов в нужный момент, без перерисовки и нестабильных сигналов.

На этом этапе эти блоки служат заготовками. Они показывают, куда позже будет добавлена логика, и позволяют индикатору развиваться контролируемо и предсказуемо.

Когда эта основа готова, следующий шаг — добавить собственно логику обнаружения паттернов Hidden Smash Day Buy и Hidden Smash Day Sell и связать ее с буферами индикатора. Далее каждое новое дополнение будет естественно опираться на уже определенную структуру.

Сначала мы обеспечиваем чистую и читаемую среду графика. Затем определяем переиспользуемые функции, которые обнаруживают паттерны Hidden Smash Day именно так, как их описывает Ларри Уильямс. После этого связываем эти функции с жизненным циклом индикатора, чтобы паттерны обнаруживались на истории, на новых барах и в реальном времени. Каждый шаг напрямую опирается на предыдущий, сохраняя индикатор структурированным, предсказуемым и удобным для сопровождения.

Подготовка графика для визуальной ясности

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

//+------------------------------------------------------------------+
//| This function configures the chart's appearance.                 |
//+------------------------------------------------------------------+
bool ConfigureChartAppearance()
{
   if(!ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite)){
      Print("Error while setting chart background, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_SHOW_GRID, false)){
      Print("Error while setting chart grid, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_MODE, CHART_CANDLES)){
      Print("Error while setting chart mode, ", GetLastError());
      return false;
   }

   if(!ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack)){
      Print("Error while setting chart foreground, ", GetLastError());
      return false;
   }

   if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrSeaGreen)){
      Print("Error while setting bullish candles color, ", GetLastError());
      return false;
   }
      
   if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrBlack)){
      Print("Error while setting bearish candles color, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_COLOR_CHART_UP, clrSeaGreen)){
      Print("Error while setting bullish candles color, ", GetLastError());
      return false;
   }
   
   if(!ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrBlack)){
      Print("Error while setting bearish candles color, ", GetLastError());
      return false;
   }
   
   return true;
}

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

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

Регистрация и подготовка буферов индикатора

После подготовки графика следующий шаг — инициализировать и зарегистрировать буферы индикатора. Индикатор использует два буфера:

  • Один буфер хранит значения для бычьих баров Hidden Smash Day
  • Второй буфер хранит значения для медвежьих баров Hidden Smash Day

Для обоих буферов явно задается индексация не как у таймсерии.

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){

   ...
   
   //--- Set arrays as series
   ArraySetAsSeries(buySmashArrowBuffer,  false);
   ArraySetAsSeries(sellSmashArrowBuffer, false);

   return(INIT_SUCCEEDED);
}

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

После задания направления индексации буферы регистрируются с помощью SetIndexBuffer.

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){

   ...
   
   //--- Bind arrays to indicator buffers
   SetIndexBuffer(0, buySmashArrowBuffer,  INDICATOR_DATA);
   SetIndexBuffer(1, sellSmashArrowBuffer, INDICATOR_DATA);

   return(INIT_SUCCEEDED);
}

С этого момента MetaTrader точно знает, откуда читать данные при отрисовке стрелок на графике.

Определение логики обнаружения баров Hidden Smash Day

Когда инфраструктура буферов готова, можно определить функции, которые обнаруживают паттерны Hidden Smash Day. Для обнаружения исходных паттернов создаются две базовые функции:

Одна обнаруживает бычьи бары Hidden Smash Day.

//+------------------------------------------------------------------+
//| Identifies a Bullish Hidden Smash Bar at a specific index        |
//| Larry Williams definition applied to any timeframe               |
//+------------------------------------------------------------------+
bool IsHiddenSmashBuyBarAtIndex(
   const int i,
   const double &open[],
   const double &high[],
   const double &low[],
   const double &close[],
   const bool requireCloseBelowOpen = false
)
{
   // We need a previous bar to confirm an up close
   if(i < 1)
      return false;

   // 1. Must close higher than the previous bar
   if(close[i] <= close[i - 1])
      return false;

   // 2. Use the bar's own range
   double range = high[i] - low[i];
   if(range <= 0.0)
      return false;

   // 3. Close must be in the lower 25 percent of the bar range
   double lowerQuarter = low[i] + (range * 0.25);
   if(close[i] > lowerQuarter)
      return false;

   // 4. Best patterns only if requested
   if(requireCloseBelowOpen && close[i] >= open[i])
      return false;

   return true;
}

Другая обнаруживает медвежьи бары Hidden Smash Day.

//+------------------------------------------------------------------+
//| Identifies a Bearish Hidden Smash Bar at a specific index        |
//| Larry Williams definition applied to any timeframe               |
//+------------------------------------------------------------------+
bool IsHiddenSmashSellBarAtIndex(
   const int i,
   const double &open[],
   const double &high[],
   const double &low[],
   const double &close[],
   const bool requireCloseAboveOpen = false
)
{
   // We need a previous bar to confirm a down close
   if(i < 1)
      return false;

   // 1. Must close lower than the previous bar
   if(close[i] >= close[i - 1])
      return false;

   // 2. Use the bar's own range
   double range = high[i] - low[i];
   if(range <= 0.0)
      return false;

   // 3. Close must be in the upper 25 percent of the bar range
   double upperQuarter = high[i] - (range * 0.25);
   if(close[i] < upperQuarter)
      return false;

   // 4. Best patterns only if requested
   if(requireCloseAboveOpen && close[i] <= open[i])
      return false;

   return true;
}

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

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

Подтверждение паттернов Hidden Smash Day

Ларри Уильямс подчеркивал, что поведение следующего бара подтверждает самые сильные паттерны Hidden Smash Day. Для этого вводятся две функции подтверждения. Бычий паттерн подтверждается только тогда, когда следующий бар закрывается выше максимума бара Hidden Smash.

//+------------------------------------------------------------------+
//| Returns true if a Hidden Smash Day Buy pattern is confirmed      |
//| Confirmation requires next bar to close above smash bar high     |
//+------------------------------------------------------------------+
bool IsConfirmedHiddenSmashBuyAtIndex(const double &open[],
                                      const double &high[],
                                      const double &low[],
                                      const double &close[],
                                      int index
                                      )
{
   int confirmationIndex = index + 1;

   // Ensure confirmation bar exists
   if(confirmationIndex >= ArraySize(close))
      return false;

   // Smash bar must be valid
   if(!IsHiddenSmashBuyBarAtIndex(index, open, high, low, close))
      return false;

   // Confirmation close above smash bar high
   if(close[confirmationIndex] > high[index])
      return true;

   return false;
}

Медвежий паттерн подтверждается только тогда, когда следующий бар закрывается ниже минимума бара Hidden Smash Day.

//+------------------------------------------------------------------+
//| Returns true if a Hidden Smash Day Sell pattern is confirmed     |
//| Confirmation requires next bar to close below smash bar low      |
//+------------------------------------------------------------------+
bool IsConfirmedHiddenSmashSellAtIndex(const double &open[],
                                       const double &high[],
                                       const double &low[],
                                       const double &close[],
                                       int index
                                       )
{
   int confirmationIndex = index + 1;

   // Ensure confirmation bar exists
   if(confirmationIndex >= ArraySize(close))
      return false;

   // Smash bar must be valid
   if(!IsHiddenSmashSellBarAtIndex(index, open, high, low, close))
      return false;

   // Confirmation close below smash bar low
   if(close[confirmationIndex] < low[index])
      return true;

   return false;
}

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

Отметка найденных паттернов при инициализации индикатора

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

//+------------------------------------------------------------------+
//| Scans historical bars and maps Hidden Smash patterns on load     |
//+------------------------------------------------------------------+
void MapHiddenSmashPatternsOnInitialization(
   const int rates_total,
   const double &open[],
   const double &high[],
   const double &low [],
   const double &close[],
   int hidden_SmashValidationMode,
   double closePercentThreshold = 25.0
)
{
   //--- Safety check
   if(rates_total <= 1)
      return;

   //--- Loop through all historical bars
   for(int i = 1; i <= rates_total - 1; i++)
   {
      //--- Default to empty
      buySmashArrowBuffer[i]  = EMPTY_VALUE;
      sellSmashArrowBuffer[i] = EMPTY_VALUE;

      //--- Mode 1: Bar only identification
      if(hiddenSmashValidationMode == HIDDEN_SMASH_BAR_ONLY)
      {
         if(IsHiddenSmashBuyBarAtIndex(i, open, high, low, close))
         {
            buySmashArrowBuffer[i] = low[i];
         }

         if(IsHiddenSmashSellBarAtIndex(i, open, high, low, close))
         {
            sellSmashArrowBuffer[i] = high[i];
         }
      }
      //--- Mode 2: Confirmed pattern identification
      else if(hiddenSmashValidationMode == HIDDEN_SMASH_CONFIRMED)
      {
         if(IsConfirmedHiddenSmashBuyAtIndex(open, high, low, close,
                                             i))
         {
            buySmashArrowBuffer[i] = low[i];
         }

         if(IsConfirmedHiddenSmashSellAtIndex(open, high, low, close,
                                              i))
         {
            sellSmashArrowBuffer[i] = high[i];
         }
      }
   }
}

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

Для каждого валидного паттерна значение стрелки записывается в соответствующий буфер. Все остальные бары остаются пустыми, поэтому отображаются только настоящие паттерны Hidden Smash Day. Эта логика выполняется один раз внутри блока prev_calculated == 0 чтобы избежать ненужного пересчета.

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t  rates_total,
                const int32_t  prev_calculated,
                const datetime &time[],
                const double   &open[],
                const double   &high[],
                const double   &low[],
                const double   &close[],
                const long     &tick_volume[],
                const long     &volume[],
                const int32_t  &spread[])
{  

   ...

   //--- This block will be executed whenever the indicator is initially attached on a chart
   if(prev_calculated == 0){
      
      //--- Start with clean arrays
      ArrayInitialize(buySmashArrowBuffer,  EMPTY_VALUE);
      ArrayInitialize(sellSmashArrowBuffer, EMPTY_VALUE);
      
      //--- Map all hidden smash bar patterns
      MapHiddenSmashPatternsOnInitialization(rates_total, lwOpen, lwHigh, lwLow, lwClose, hiddenSmashValidationMode);
      
   }
   
   ...
   
   return(rates_total);
}

Обновление паттернов при формировании нового бара

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

//+------------------------------------------------------------------+
//| Evaluates hidden smash patterns on new bar formation             |
//| Updates indicator buffers for the recently completed bar         |
//+------------------------------------------------------------------+
void ProcessHiddenSmashOnNewBar(
   const double &open[],
   const double &high[],
   const double &low[],
   const double &close[],
   int rates_total
)
{
   int completedBarIndex = rates_total - 2;
   int currentBarIndex   = rates_total - 1;

   //--- Safety check
   if(completedBarIndex < 0)
      return;

   //--- Always clear buffers for involved bars
   buySmashArrowBuffer [completedBarIndex] = EMPTY_VALUE;
   sellSmashArrowBuffer[completedBarIndex] = EMPTY_VALUE;

   buySmashArrowBuffer [currentBarIndex]   = EMPTY_VALUE;
   sellSmashArrowBuffer[currentBarIndex]   = EMPTY_VALUE;

   //--- Mode 1: Detect bar only
   if(hiddenSmashValidationMode == HIDDEN_SMASH_BAR_ONLY)
   {
      if(IsHiddenSmashBuyBarAtIndex(completedBarIndex, open, high, low, close))
         buySmashArrowBuffer[completedBarIndex] = low[completedBarIndex];

      if(IsHiddenSmashSellBarAtIndex(completedBarIndex, open, high, low, close))
         sellSmashArrowBuffer[completedBarIndex] = high[completedBarIndex];

      return;
   }

   //--- Mode 2: Confirmed smash
   if(hiddenSmashValidationMode == HIDDEN_SMASH_CONFIRMED)
   {
      int smashBarIndex = completedBarIndex - 1;
      if(smashBarIndex < 0)
         return;

      if(IsHiddenSmashBuyBarAtIndex(smashBarIndex, open, high, low, close))
      {
         if(close[completedBarIndex] > high[smashBarIndex])
            buySmashArrowBuffer[smashBarIndex] = low[smashBarIndex];
      }

      if(IsHiddenSmashSellBarAtIndex(smashBarIndex, open, high, low, close))
      {
         if(close[completedBarIndex] < low[smashBarIndex])
            sellSmashArrowBuffer[smashBarIndex] = high[smashBarIndex];
      }
   }
}

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

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t  rates_total,
                const int32_t  prev_calculated,
                const datetime &time[],
                const double   &open[],
                const double   &high[],
                const double   &low[],
                const double   &close[],
                const long     &tick_volume[],
                const long     &volume[],
                const int32_t  &spread[])
{  
   ...

   //--- This block is executed on new bar open
   if(prev_calculated != rates_total && prev_calculated != 0){
      
      //--- Update buffers on new bar open
      ProcessHiddenSmashOnNewBar(lwOpen, lwHigh, lwLow, lwClose, rates_total);
   
   }
   
   ...
   
   return(rates_total);
}

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

Поддержка тиковых обновлений в реальном времени

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

//+------------------------------------------------------------------+
//| Evaluates hidden smash patterns on tick updates                  |
//| Supports real-time detection and confirmation logic              |
//+------------------------------------------------------------------+
void ProcessHiddenSmashOnTick(
   const double &open[],
   const double &high[],
   const double &low[],
   const double &close[],
   int rates_total
)
{
   int currentBarIndex   = rates_total - 1;
   int completedBarIndex = rates_total - 2;

   if(currentBarIndex < 0)
      return;

   //--- Always reset current bar buffer values
   buySmashArrowBuffer [currentBarIndex] = EMPTY_VALUE;
   sellSmashArrowBuffer[currentBarIndex] = EMPTY_VALUE;

   //--- Mode 1: Bar-only detection in real time
   if(hiddenSmashValidationMode == HIDDEN_SMASH_BAR_ONLY)
   {
      if(IsHiddenSmashBuyBarAtIndex(currentBarIndex, open, high, low, close))
         buySmashArrowBuffer[currentBarIndex] = low[currentBarIndex];

      if(IsHiddenSmashSellBarAtIndex(currentBarIndex, open, high, low, close))
         sellSmashArrowBuffer[currentBarIndex] = high[currentBarIndex];

      return;
   }

   //--- Mode 2: Confirmed smash evaluated continuously
   if(hiddenSmashValidationMode == HIDDEN_SMASH_CONFIRMED)
   {
      int smashBarIndex = completedBarIndex;
      if(smashBarIndex < 0)
         return;

      if(IsHiddenSmashBuyBarAtIndex(smashBarIndex, open, high, low, close))
      {
         if(close[currentBarIndex] > high[smashBarIndex])
            buySmashArrowBuffer[smashBarIndex] = low[smashBarIndex];
      }

      if(IsHiddenSmashSellBarAtIndex(smashBarIndex, open, high, low, close))
      {
         if(close[currentBarIndex] < low[smashBarIndex])
            sellSmashArrowBuffer[smashBarIndex] = high[smashBarIndex];
      }
   }
}

На каждом входящем тике индикатор оценивает текущий бар и динамически корректирует значения буферов.

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t  rates_total,
                const int32_t  prev_calculated,
                const datetime &time[],
                const double   &open[],
                const double   &high[],
                const double   &low[],
                const double   &close[],
                const long     &tick_volume[],
                const long     &volume[],
                const int32_t  &spread[])
{  
   ...

   //--- This block is executed on arrival of new price (tick) data
   if(prev_calculated == rates_total){
      
      //--- Update buffers on new tick
      ProcessHiddenSmashOnTick(lwOpen, lwHigh, lwLow, lwClose, rates_total);
      
   }
   
   return(rates_total);
}

Это позволяет исходным барам Hidden Smash Day появляться сразу по мере формирования, а подтвержденным паттернам — обновляться в момент выполнения условий подтверждения. Такая отзывчивость в реальном времени делает индикатор практичным для дискреционного анализа и активного мониторинга.

Настройка визуального вывода через стрелочные серии отрисовки

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

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){

   ...
   
   //--- Configure Graphic Plots   
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_ARROW);
   PlotIndexSetInteger(0, PLOT_ARROW, 233);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrSeaGreen);
   PlotIndexSetInteger(0, PLOT_ARROW_SHIFT, +20);
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 2);
   PlotIndexSetDouble (0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetString (0, PLOT_LABEL, "Hidden Smash Buy Bar");
   
   PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_ARROW);
   PlotIndexSetInteger(1, PLOT_ARROW, 234);
   PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrBlack);
   PlotIndexSetInteger(1, PLOT_ARROW_SHIFT, -20);
   PlotIndexSetInteger(1, PLOT_LINE_WIDTH, 2);
   PlotIndexSetDouble (1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetString (1, PLOT_LABEL, "Hidden Smash Sell bar");
   
   //--- General indicator configurations
   IndicatorSetString(INDICATOR_SHORTNAME, "Larry Williams Market Structure Indicator");

   return(INIT_SUCCEEDED);
}

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

На этом этапе индикатор полностью функционален. Он обнаруживает паттерны Hidden Smash Day по правилам Ларри Уильямса, поддерживает несколько режимов валидации, динамически обновляется по мере изменения рынка и выводит на график понятные визуальные сигналы.

Полная реализация приведена в приложенном исходном файле с именем lwHiddenSmashDayIndicator.mq5. На практике предпочтительнее ссылаться на приложенный файл, а не вставлять полный исходный код в статью.

Этот раздел завершает полную разработку индикатора Hidden Smash Day и подготавливает переход к тестированию, интерпретации и дальнейшим экспериментам.


Тестирование и визуальная проверка

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

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

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

Ниже приведен скриншот, показывающий, как готовый индикатор выглядит на графике в реальном времени.

hidden smash bar patterns

Такое визуальное подтверждение помогает проверить как логику обнаружения, так и настройки отрисовки.

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


Заключение

В этой статье рассматривалась практическая задача технического анализа. Разворотные паттерны Hidden Smash Day концептуально просты, но последовательно обнаруживать их на графике бывает сложно, поскольку их сетапы зависят от нескольких точных структурных условий. К ним относятся соотношение последовательных закрытий, положение закрытия внутри диапазона бара и подтверждение на следующей торговой сессии. Без объективных правил разные наблюдатели могут по-разному трактовать один и тот же график.

Чтобы устранить эту неоднозначность, статья перевела концепцию Hidden Smash Day Ларри Уильямса в точную модель обнаружения и реализовала ее в виде пользовательского индикатора MQL5 под именем lwHiddenSmashDayIndicator.mq5. Индикатор оценивает завершенные бары с помощью явных правил, описывающих паттерн. Он проверяет соотношение закрытия с предыдущим баром, определяет, находится ли закрытие в заданной части диапазона бара, и обнаруживает валидные сетапы на покупку и продажу. Когда сетап обнаружен, индикатор отмечает его непосредственно на графике визуальными стрелками, делая паттерн сразу видимым.

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

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

После изучения этой статьи мы можем:
  • объективно обнаруживать сетапы Hidden Smash Day на покупку и продажу на ценовом графике
  • визуализировать разворотный паттерн Ларри Уильямса непосредственно с помощью пользовательского индикатора
  • последовательно изучать паттерн на разных инструментах и таймфреймах
  • расширять логику обнаружения для исследований или интеграции в автоматизированные системы
  • применять дополнительные контекстные фильтры при анализе потенциальных торговых возможностей
В результате индикатор подходит как для дискреционных, так и для алгоритмических задач. Он дает трейдерам, изучающим паттерн Hidden Smash Day, понятный визуальный ориентир и одновременно предоставляет структурированную основу, которую можно расширять до автоматизированных торговых систем или более широких исследовательских фреймворков.


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

Прикрепленные файлы |
Последние комментарии | Перейти к обсуждению на форуме трейдеров (2)
Israr Hussain Shah
Israr Hussain Shah | 16 мар. 2026 в 16:08
Спасибо за это
Chacha Ian Maroa
Chacha Ian Maroa | 16 мар. 2026 в 16:26
Israr Hussain Shah #:
Спасибо за это
Не за что
Разработка инструментария для анализа Price Action (Часть 68): Панель RSI с привязкой к цене на языке MQL5 Разработка инструментария для анализа Price Action (Часть 68): Панель RSI с привязкой к цене на языке MQL5
Мы представляем встроенную в график панель RSI, которая устраняет необходимость в отдельном окне, привязывая данные о моментуме непосредственно к текущей цене. В статье рассматриваются концепция решения и код на MQL5: получение значений RSI в реальном времени, классификация сигналов по наклону и адаптивное позиционирование. Трейдеры получают значение RSI, состояние и силу сигнала прямо в точке принятия решения, что повышает ясность анализа на разных таймфреймах.
Автоматизация торговых стратегий с помощью MQL5 (Часть 48): Блоки ордеров, провокация ликвидности, пробой структуры Автоматизация торговых стратегий с помощью MQL5 (Часть 48): Блоки ордеров, провокация ликвидности, пробой структуры
Мы реализуем советник на языке MQL5, который обнаруживает блоки ордеров, сформированные после пробоя консолидации, и подтверждает их с помощью разрывов справедливой стоимости. Каждая зона подтверждается пробоем структуры и предшествующей провокацией, а затем фильтруется по тренду на более высоком таймфрейме. Программа добавляет отслеживание смягчения зон, расчет лота на основе риска и два режима трейлинг-стопа, обеспечивая наглядное отображение на графике и логику исполнения сделок, готовую к тестированию на исторических данных.
Торговые инструменты на MQL5 (Часть 31): Создание интерактивной палитры инструментов в MQL5 Торговые инструменты на MQL5 (Часть 31): Создание интерактивной палитры инструментов в MQL5
Мы превращаем боковую панель "Палитра инструментов" из статической оболочки в интерактивную систему MQL5. В статье реализованы выпадающие меню для каждой категории, обработчик событий графика, механизм рисования с несколькими щелчками мыши (инструменты с одним, двумя и тремя щелчками), а также взаимодействие с мышью, включая перетаскивание, изменение размера нижнего края, прокрутку, состояния при наведении курсора и переключение тем в реальном времени. Вы сможете выбирать инструмент и размещать объекты графика непосредственно из палитры для анализа.
Разработка инструментария для анализа Price Action (Часть 67): Автоматизация мониторинга уровней поддержки и сопротивления в MQL5 Разработка инструментария для анализа Price Action (Часть 67): Автоматизация мониторинга уровней поддержки и сопротивления в MQL5
В этой статье реализован полноценный советник на языке MQL5, который в реальном времени отслеживает вручную построенные уровни поддержки и сопротивления. Он синхронизирует горизонтальные линии, обнаруживает приближения, касания, пробои, развороты и ретесты, а также выполняет проверку свечных паттернов при необходимости. Алерты и маркеры на графике обеспечивают четкую и воспроизводимую обратную связь, позволяя сохранить ручной анализ и при этом автоматизировать отслеживание ключевых ценовых уровней.