Разработка инструментария анализа Price Action (Часть 25): Пробой фракталов по двум EMA
Содержание
Введение
В этой статье рассматривается разработка инструмента, помогающего в анализе Price Action за счет более глубокой и содержательной оценки с использованием индикатора Fractals, разработанного Биллом Вильямсом.
Билл М. Уильямс (1932-2019) был влиятельным американским трейдером и автором, известным своим вкладом в психологию торговли, технический анализ и теорию хаоса на финансовых рынках. На протяжении своей карьеры Уильямс изучал фондовый, товарный и валютный (Forex) рынки, разработав несколько инновационных инструментов технического анализа для выявления трендов и потенциальных точек разворота. Среди наиболее известных его индикаторов – Accelerator/Decelerator Oscillator, индикатор Alligator, Awesome Oscillator, индикатор Fractals, Gator Oscillator и Market Facilitation Index. Сегодня эти индикаторы широко используются на рынке Forex, фондовом и других финансовых рынках благодаря своей эффективности при анализе поведения рынка.
Индикатор Fractals, ключевой компонент методологии Уильямса, в нашем подходе сочетается с экспоненциальными скользящими средними (EMA) с периодами 14 и 200. Интегрируя фрактальные паттерны с этими динамическими фильтрами тренда, наш советник точно выявляет потенциальные развороты рынка и при этом учитывает общее направление тренда. Эта комбинированная стратегия улучшает принятие торговых решений, позволяя раньше выявлять сигналы разворота и подтверждать силу тренда, что в итоге дает более надежные точки входа с высокой вероятностью отработки. Сочетание фрактального анализа и скользящих средних дает трейдерам мощный инструмент для более глубокого понимания Price Action, помогая точнее выбирать момент входа и улучшать результаты торговли.
Знакомство со стратегией
Наш советник использует три ключевых технических индикатора: индикатор Fractals, EMA 14 и EMA 200. Индикатор Fractals, разработанный Биллом Вильямсом, – популярный инструмент технического анализа для выявления потенциальных разворотов тренда. Он выявляет специфические ценовые паттерны, называемые фракталами, которые формируются как локальные максимумы или минимумы и сигнализируют о возможных точках разворота рынка. Эти фракталы служат уровнями поддержки и сопротивления, давая трейдерам визуальные ориентиры, которые помогают точнее выбирать моменты входа и выхода.
Экспоненциальная скользящая средняя (EMA) принципиально отличается от простой скользящей средней (SMA) тем, что придает больший вес последним ценовым данным, благодаря чему получается более чувствительный индикатор. Такое взвешивание достигается с помощью коэффициента сглаживания, который экспоненциально повышает вес последних цен, позволяя EMA быстрее реагировать на изменения рынка. Поэтому EMA хорошо подходят для выявления зарождающихся трендов и ранних сигналов их смены, особенно на меньших периодах.
В нашем сетапе EMA 14 отражает краткосрочный рыночный моментум и быстро реагирует на недавние движения цены, благодаря чему хорошо подходит для своевременных входов в сделки. EMA 200, напротив, служит индикатором долгосрочного тренда, сглаживая краткосрочный шум и показывая общее направление рынка. Когда цена находится выше EMA 200, это указывает на долгосрочный бычий тренд; когда ниже – на медвежий. Кроме того, EMA 200 часто выступает как динамический уровень поддержки или сопротивления, помогая трейдерам отфильтровывать ложные сигналы и подтверждать силу тренда.
Сигнал на покупку (бычий пробой):
Сигнал на покупку срабатывает, когда одновременно выполняются несколько условий, указывающих на сильное восходящее движение. Сначала советник отслеживает последний уровень фрактального минимума, то есть уровень поддержки. Он ищет ситуацию, при которой текущая рыночная цена поднимается выше этого фрактального уровня поддержки, сигнализируя о потенциальном пробое. Чтобы подтвердить восходящий тренд, советник проверяет, находится ли текущая цена выше EMA 14 и EMA 200, а сама EMA 14 – выше EMA 200. Когда все эти условия выполняются, формируется сигнал на покупку. На графике размещаются визуальные подсказки – стрелка вверх и метка, а при необходимости может сработать алерт для уведомления трейдера.
- Цена поднимается выше последнего фрактального уровня поддержки.
- Текущая цена находится выше EMA 14 и EMA 200.
- EMA 14 выше EMA 200, что подтверждает восходящий тренд.

Рис. 1. Бычий пробой
Сигнал на продажу (медвежий пробой):
Сигнал на продажу, напротив, возникает, когда цена опускается ниже значимого фрактального максимума, то есть уровня сопротивления, указывая на потенциальное движение вниз. Советник отслеживает последний фрактальный максимум и ждет, когда рыночная цена пробьет этот уровень вниз. Чтобы подтвердить нисходящий тренд, советник проверяет, что текущая цена находится ниже обеих EMA, а EMA 14 – ниже EMA 200. Когда эти критерии выполнены – то есть цена пробивает вниз фрактальный уровень сопротивления, а тренд остается медвежьим, – формируется сигнал на продажу. На график наносятся аналогичные визуальные маркеры – стрелки вниз и метки, а при необходимости активируются алерты.
- Цена опускается ниже последнего фрактального уровня сопротивления.
- Текущая цена находится ниже EMA 14 и EMA 200.
- EMA 14 ниже EMA 200, что подтверждает нисходящий тренд.

Рис. 2. Медвежий пробой
Разбор компонентов кода
Этот советник сочетает фрактальный анализ с трендовыми фильтрами на основе скользящих средних, чтобы выявлять и визуализировать потенциальные точки пробоя на рынке. Рисуя горизонтальные уровни по недавним фрактальным максимумам и минимумам, он обозначает ключевые зоны поддержки и сопротивления. Когда цена пересекает эти уровни в направлении, подтверждаемом трендом EMA, советник генерирует визуальные сигналы – стрелки и метки – а также звуковые алерты, упрощая трейдеру процесс принятия решений. Благодаря модульной структуре и функциям, отвечающим за отрисовку, сигналы и управление данными, советник легко адаптируется под разные стили торговли и предпочтения пользователя. Кроме того, внимание к управлению ресурсами и очистке обеспечивает стабильную и аккуратную работу советника. В целом, такое продуманное сочетание индикаторов и визуальных подсказок дает трейдерам комплексный инструмент для работы с пробоями фракталов в условиях выраженного тренда.Заголовок и метаданные
В начальном разделе кода содержатся метаданные, описывающие авторство скрипта, его версию и лицензионную информацию. Комментарии, заключенные в блоки "//+------------------------------------------------------------------+", помогают обозначить назначение скрипта и указать авторство. Директивы #property указывают владельца авторских прав, ссылку на профиль автора в сообществе MetaTrader, номер версии и задают строгие правила компиляции. Директива #property strict особенно важна, поскольку предписывает компилятору придерживаться более строгих стандартов кодирования и тем самым выявлять потенциальные ошибки, такие как необъявленные переменные или несоответствие типов. Эти метаданные и директивы не влияют на логику выполнения, но служат документацией и помогают поддерживать качество кода на этапе компиляции.
//+------------------------------------------------------------------+ //| Fractal Breakout, EMA 14 and EMA 200| //| Copyright 2025, MetaQuotes Ltd.| //| https://www.mql5.com/ru/users/lynnchris| //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/ru/users/lynnchris" #property version "1.0" #property strict
Входные параметры
В этом разделе задаются все настраиваемые параметры, которые пользователь может изменять без вмешательства в основной код. Среди них – таймфрейм для анализа (InpTimeframe), количество анализируемых баров (InpHistoryBars) и периоды двух EMA, которые служат фильтрами тренда (InpEMA14Period и InpEMA200Period).
Параметры цвета (InpBullColor и InpBearColor) позволяют визуально настраивать стрелки и линии, обозначающие пробои. Текстовые метки (InpBullText и InpBearText) задают поясняющие подписи для сигналов, делая график нагляднее. Смещение стрелки (InpArrowOffset) и размер шрифта (InpArrowFontSize) дают дополнительный контроль над отображением, позволяя трейдеру удобно размещать метки.
За систему алертов отвечают InpAlertsEnabled – этот параметр включает или отключает всплывающие уведомления, – и InpAlertSoundFile, который задает звуковой файл, воспроизводимый при обнаружении сигнала. Эти параметры делают советник гибким и позволяют адаптировать его под разные стили торговли и визуальные предпочтения.
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // chart TF input int InpHistoryBars = 200; // bars back to scan input int InpEMA14Period = 14; // fast EMA input int InpEMA200Period = 200; // slow EMA input color InpBullColor = clrLime; // bullish arrow color input color InpBearColor = clrRed; // bearish arrow color input string InpBullText = "BULL Break"; // bullish label input string InpBearText = "BEAR Break"; // bearish label input int InpArrowOffset = 20; // offset in points for label input int InpArrowFontSize = 12; // size of the arrow glyph input bool InpAlertsEnabled = true; // show pop-up alerts input string InpAlertSoundFile = "alert.wav"; // sound file in /Sounds/
Глобальные переменные и хэндлы индикаторов
Переменные, объявленные вне функций, служат для хранения хэндлов индикаторов и массивов данных фракталов. Хэндлы (hFractals, hEMA14, hEMA200) представляют собой ссылки на экземпляры индикаторов, созданные во время инициализации. Они необходимы, потому что позволяют советнику взаимодействовать с буферами индикаторов и получать данные в реальном времени, а также исторические данные. Массивы fractalUp[] и fractalDown[] представляют собой динамически выделяемые буферы, в которых будут храниться соответственно точки фрактальных максимумов и минимумов. Использование этих переменных как глобальных гарантирует доступ к ним из любого места в коде, особенно во время обработки OnTick, где выполняется анализ в реальном времени.
int hFractals, hEMA14, hEMA200; double fractalUp[], fractalDown[];
Инициализация (OnInit)
Во время запуска вызывается функция OnInit, которая настраивает необходимые ресурсы. В ней создаются хэндлы индикаторов для фракталов и EMA с помощью функций iFractals и iMA, где задаются символ и таймфрейм. Успешное создание этих хэндлов критически важно: если хотя бы один из них окажется недействительным, например из-за неверных параметров или недоступных данных, инициализация завершится ошибкой и советник не запустится.
Затем массивы данных по фракталам настраиваются для работы в режиме серии, то есть последние данные будут находиться по индексу 0, что упрощает обратный анализ по истории. Изменение размера этих массивов в соответствии с заданным числом баров гарантирует, что буферы данных будут иметь подходящий размер для эффективной обработки. В целом, этот шаг закладывает основу для надежного получения данных, что крайне важно для точного выявления пробоев.
int OnInit() { hFractals = iFractals(_Symbol, InpTimeframe); hEMA14 = iMA(_Symbol, InpTimeframe, InpEMA14Period, 0, MODE_EMA, PRICE_CLOSE); hEMA200 = iMA(_Symbol, InpTimeframe, InpEMA200Period,0, MODE_EMA, PRICE_CLOSE); if(hFractals==INVALID_HANDLE || hEMA14==INVALID_HANDLE || hEMA200==INVALID_HANDLE) return(INIT_FAILED); ArraySetAsSeries(fractalUp, true); ArraySetAsSeries(fractalDown, true); ArrayResize(fractalUp, InpHistoryBars); ArrayResize(fractalDown, InpHistoryBars); return(INIT_SUCCEEDED); }
Деинициализация (OnDeinit)
Когда советник удаляется с графика или терминал закрывается, OnDeinit выполняет очистку ресурсов. Функция освобождает хэндлы индикаторов с помощью IndicatorRelease, высвобождая выделенную под них память и предотвращая утечки. Кроме того, функция проходит по всем объектам на графике, находит и удаляет те, у которых есть префикс "FB_" – это визуальные сигналы, то есть стрелки, метки и линии, созданные в процессе работы. Такая очистка не позволяет оставшимся объектам загромождать график после отключения советника, поддерживает порядок и предотвращает возможные конфликты или путаницу при последующем анализе.
void OnDeinit(const int reason) { if(hFractals!=INVALID_HANDLE) IndicatorRelease(hFractals); if(hEMA14 !=INVALID_HANDLE) IndicatorRelease(hEMA14); if(hEMA200 !=INVALID_HANDLE) IndicatorRelease(hEMA200); for(int i=ObjectsTotal(0)-1; i>=0; i--) { string n = ObjectName(0,i); if(StringFind(n,"FB_")>=0) ObjectDelete(0,n); } }
Основная обработка (OnTick)
Основная логика сосредоточена в функции OnTick, которая выполняется при каждом поступлении нового рыночного тика. Сначала функция получает последние значения двух EMA с помощью CopyBuffer. Эти значения EMA служат фильтрами тренда: их взаимное расположение показывает, находится ли рынок в восходящем или нисходящем тренде, что помогает оценить валидность пробоя. Если получить данные EMA не удается, функция завершается раньше, чтобы не допустить ложных сигналов. Затем функция получает буферы данных фракталов как для последнего верхнего, так и для последнего нижнего фрактала, снова с проверкой на ошибки. Затем код просматривает эти буферы в обратном порядке, чтобы найти последние валидные фракталы, игнорируя служебные значения EMPTY_VALUEs. Выявляя последние значимые фрактальные точки, советник определяет ключевые уровни поддержки и сопротивления, пробой которых может запустить сигнал. Затем с помощью вспомогательной функции он рисует на этих уровнях горизонтальные линии для наглядности. Отладочный вывод в терминале дает информацию в реальном времени об уровнях, ценах и состоянии EMA, что позволяет трейдерам проверить логику работы.
Наконец, советник проверяет условия пробоя: медвежий пробой возникает, когда предыдущая цена закрытия была выше нижнего фрактального уровня, текущая цена закрытия опускается ниже него, а сама цена находится ниже обеих EMA в нисходящем тренде. Бычий пробой, напротив, фиксируется, когда предыдущая цена закрытия была ниже верхнего фрактального уровня, текущая цена закрытия поднимается выше него, а цена находится выше обеих EMA в восходящем тренде. Обнаружение этих условий запускает функцию формирования сигнала.
void OnTick() { // 1) Read current EMAs double ema14Arr[1], ema200Arr[1]; if(CopyBuffer(hEMA14,0,0,1,ema14Arr)<=0 || CopyBuffer(hEMA200,0,0,1,ema200Arr)<=0) return; double ema14_now = ema14Arr[0]; double ema200_now = ema200Arr[0]; // 2) Read fractal history (skip current bar) if(CopyBuffer(hFractals,0,1,InpHistoryBars,fractalUp)<=0 || CopyBuffer(hFractals,1,1,InpHistoryBars,fractalDown)<=0) return; // 3) Find most recent valid fractals (ignore EMPTY_VALUE) int upShift=-1, downShift=-1; for(int i=1; i<InpHistoryBars; i++) { if(fractalUp[i] != EMPTY_VALUE && upShift<0) upShift = i+1; if(fractalDown[i] != EMPTY_VALUE && downShift<0) downShift = i+1; if(upShift>0 && downShift>0) break; } // 4) Levels double lvlUp = (upShift>0) ? fractalUp[upShift-1] : 0.0; double lvlDown = (downShift>0) ? fractalDown[downShift-1] : 0.0; // 5) Draw level lines DrawHLine("FB_LevelUp", lvlUp, InpBullColor); DrawHLine("FB_LevelDown", lvlDown, InpBearColor); // 6) DEBUG print double prevC = iClose(_Symbol,InpTimeframe,1); double currC = iClose(_Symbol,InpTimeframe,0); PrintFormat( "DBG lvlUp=%.5f lvlDown=%.5f prevC=%.5f currC=%.5f EMA14=%.5f EMA200=%.5f", lvlUp, lvlDown, prevC, currC, ema14_now, ema200_now ); // 7) Breakouts on the last closed candle (shift=1) // Bearish breakout detection if(lvlDown>0 && prevC>=lvlDown && currC<lvlDown && currC<ema14_now && currC<ema200_now && ema200_now>ema14_now) { Print(">>> Bear breakout triggered"); Signal(false, 1, lvlDown, ema14_now, ema200_now); } // Bullish breakout detection if(lvlUp>0 && prevC<=lvlUp && currC>lvlUp && currC>ema14_now && currC>ema200_now && ema14_now>ema200_now) { Print(">>> Bull breakout triggered"); Signal(true, 1, lvlUp, ema14_now, ema200_now); } }
Отрисовка горизонтальных линий (DrawHLine)
Эта вспомогательная функция отвечает за создание и обновление горизонтальных линий на графике. При вызове функция проверяет, существует ли линия с указанным именем; если нет, она создает новую пунктирную линию на заданном ценовом уровне с указанным цветом. Если линия уже существует, функция просто обновляет ее положение. Такой подход предотвращает появление нескольких перекрывающихся линий и гарантирует, что визуальные уровни остаются актуальными с учетом последнего фрактального анализа. Пунктир помогает отличать эти линии от других объектов графика, подчеркивая их роль как уровней поддержки или сопротивления. Такие визуальные ориентиры очень полезны для трейдеров: они позволяют быстро распознавать зоны пробоя и облегчают принятие решений как в ручной, так и в автоматической торговле.
void DrawHLine(string name, double price, color clr) { if(price<=0) return; if(ObjectFind(0,name)<0) { ObjectCreate(0,name,OBJ_HLINE,0,0,price); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); } else ObjectSetDouble(0,name,OBJPROP_PRICE,price); }
Сигналы и визуализация (Signal)
Функция Signal объединяет все действия, связанные с формированием сигнала о пробое. Сначала функция получает временную метку бара, на котором возник сигнал, чтобы точно разместить визуальные объекты. Затем она создает объект-стрелку на уровне пробоя: вверх для бычьего сигнала и вниз для медвежьего, с цветом, соответствующим тренду. Для наглядности внешний вид стрелки настраивается параметрами ширины и размера. Рядом со стрелкой с небольшим вертикальным смещением добавляется текстовая метка с сообщением "BULL Break" или "BEAR Break", что усиливает визуальный сигнал.
Функция также записывает подробное сообщение во вкладку Experts, включая точное время, уровень, цену закрытия и значения EMA, формируя полный журнал сигналов. Если алерты включены, появляется всплывающее сообщение и воспроизводится звуковой файл, чтобы сразу уведомить трейдера. Такое сочетание визуальных, звуковых и лог-сигналов гарантирует, что трейдер быстро узнает о потенциальных точках пробоя и сможет своевременно отреагировать.
void Signal(bool isBull, int shift, double level, double ema14, double ema200) { datetime t = iTime(_Symbol,InpTimeframe,shift); double price = level; string side = isBull ? "Bull" : "Bear"; // Arrow string arrowName = StringFormat("FB_%sArrow_%d", side, (int)t); ObjectCreate(0, arrowName, OBJ_ARROW, 0, t, price); ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, isBull?233:234); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, isBull?InpBullColor:InpBearColor); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2); ObjectSetInteger(0, arrowName, OBJPROP_FONTSIZE, InpArrowFontSize); // Label string lab = arrowName + "_L"; double offset = (isBull ? InpArrowOffset : -InpArrowOffset) * _Point; ObjectCreate(0, lab, OBJ_TEXT, 0, t, price + offset); ObjectSetString(0, lab, OBJPROP_TEXT, isBull?InpBullText:InpBearText); ObjectSetInteger(0, lab, OBJPROP_COLOR, isBull?InpBullColor:InpBearColor); ObjectSetInteger(0, lab, OBJPROP_FONTSIZE, 11); // Log message string msg = StringFormat( "%s breakout at %s | Level=%.5f | Close=%.5f | EMA14=%.5f | EMA200=%.5f", side, TimeToString(t, TIME_DATE|TIME_SECONDS), level, iClose(_Symbol,InpTimeframe,shift), ema14, ema200 ); Print(msg); // Alert and sound if(InpAlertsEnabled) { Alert(msg); if(StringLen(InpAlertSoundFile)>0) PlaySound(InpAlertSoundFile); } }
Код на MQL5
//+------------------------------------------------------------------+ //| Fractal Breakout, EMA 14 and EMA 200| //| Copyright 2025, MetaQuotes Ltd.| //| https://www.mql5.com/ru/users/lynnchris| //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/ru/users/lynnchris" #property version "1.0" #property strict //---inputs input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // chart TF input int InpHistoryBars = 200; // bars back to scan input int InpEMA14Period = 14; // fast EMA input int InpEMA200Period = 200; // slow EMA input color InpBullColor = clrLime; // bullish arrow color input color InpBearColor = clrRed; // bearish arrow color input string InpBullText = "BULL Break"; // bullish label input string InpBearText = "BEAR Break"; // bearish label input int InpArrowOffset = 20; // offset in points for label input int InpArrowFontSize = 12; // size of the arrow glyph input bool InpAlertsEnabled = true; // show pop-up alerts input string InpAlertSoundFile = "alert.wav"; // sound file in /Sounds/ //---indicator handles & buffers int hFractals, hEMA14, hEMA200; double fractalUp[], fractalDown[]; //+------------------------------------------------------------------+ //| Expert initialization | //+------------------------------------------------------------------+ int OnInit() { hFractals = iFractals(_Symbol, InpTimeframe); hEMA14 = iMA(_Symbol, InpTimeframe, InpEMA14Period, 0, MODE_EMA, PRICE_CLOSE); hEMA200 = iMA(_Symbol, InpTimeframe, InpEMA200Period,0, MODE_EMA, PRICE_CLOSE); if(hFractals==INVALID_HANDLE || hEMA14==INVALID_HANDLE || hEMA200==INVALID_HANDLE) return(INIT_FAILED); ArraySetAsSeries(fractalUp, true); ArraySetAsSeries(fractalDown, true); ArrayResize(fractalUp, InpHistoryBars); ArrayResize(fractalDown, InpHistoryBars); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(hFractals!=INVALID_HANDLE) IndicatorRelease(hFractals); if(hEMA14 !=INVALID_HANDLE) IndicatorRelease(hEMA14); if(hEMA200 !=INVALID_HANDLE) IndicatorRelease(hEMA200); for(int i=ObjectsTotal(0)-1; i>=0; i--) { string n = ObjectName(0,i); if(StringFind(n,"FB_")>=0) ObjectDelete(0,n); } } //+------------------------------------------------------------------+ //| Tick handler | //+------------------------------------------------------------------+ void OnTick() { // 1) Read current EMAs double ema14Arr[1], ema200Arr[1]; if(CopyBuffer(hEMA14,0,0,1,ema14Arr)<=0 || CopyBuffer(hEMA200,0,0,1,ema200Arr)<=0) return; double ema14_now = ema14Arr[0]; double ema200_now = ema200Arr[0]; // 2) Read fractal history (skip current bar) if(CopyBuffer(hFractals,0,1,InpHistoryBars,fractalUp)<=0 || CopyBuffer(hFractals,1,1,InpHistoryBars,fractalDown)<=0) return; // 3) Find most recent valid fractals (ignore EMPTY_VALUE) int upShift=-1, downShift=-1; for(int i=1; i<InpHistoryBars; i++) { if(fractalUp[i] != EMPTY_VALUE && upShift<0) upShift = i+1; if(fractalDown[i] != EMPTY_VALUE && downShift<0) downShift = i+1; if(upShift>0 && downShift>0) break; } // 4) Levels double lvlUp = (upShift>0) ? fractalUp[upShift-1] : 0.0; double lvlDown = (downShift>0) ? fractalDown[downShift-1] : 0.0; // 5) Draw level lines DrawHLine("FB_LevelUp", lvlUp, InpBullColor); DrawHLine("FB_LevelDown", lvlDown, InpBearColor); // 6) DEBUG print double prevC = iClose(_Symbol,InpTimeframe,1); double currC = iClose(_Symbol,InpTimeframe,0); PrintFormat( "DBG lvlUp=%.5f lvlDown=%.5f prevC=%.5f currC=%.5f EMA14=%.5f EMA200=%.5f", lvlUp, lvlDown, prevC, currC, ema14_now, ema200_now ); // 7) Breakouts on the last closed candle (shift=1) // Bearish breakout if(lvlDown>0 && prevC>=lvlDown && currC<lvlDown && currC<ema14_now && currC<ema200_now && ema200_now>ema14_now) { Print(">>> Bear breakout triggered"); Signal(false, 1, lvlDown, ema14_now, ema200_now); } // Bullish breakout if(lvlUp>0 && prevC<=lvlUp && currC>lvlUp && currC>ema14_now && currC>ema200_now && ema14_now>ema200_now) { Print(">>> Bull breakout triggered"); Signal(true, 1, lvlUp, ema14_now, ema200_now); } } //+------------------------------------------------------------------+ //| Draw or update a dotted HLine | //+------------------------------------------------------------------+ void DrawHLine(string name, double price, color clr) { if(price<=0) return; if(ObjectFind(0,name)<0) { ObjectCreate(0,name,OBJ_HLINE,0,0,price); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); } else ObjectSetDouble(0,name,OBJPROP_PRICE,price); } //+------------------------------------------------------------------+ //| Plot arrow, label, log & alert | //+------------------------------------------------------------------+ void Signal(bool isBull, int shift, double level, double ema14, double ema200) { datetime t = iTime(_Symbol,InpTimeframe,shift); double price = level; string side = isBull ? "Bull" : "Bear"; // Arrow string arrowName = StringFormat("FB_%sArrow_%d", side, (int)t); ObjectCreate(0, arrowName, OBJ_ARROW, 0, t, price); ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, isBull?233:234); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, isBull?InpBullColor:InpBearColor); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2); ObjectSetInteger(0, arrowName, OBJPROP_FONTSIZE, InpArrowFontSize); // Label string lab = arrowName + "_L"; double offset = (isBull ? InpArrowOffset : -InpArrowOffset) * _Point; ObjectCreate(0, lab, OBJ_TEXT, 0, t, price + offset); ObjectSetString(0, lab, OBJPROP_TEXT, isBull?InpBullText:InpBearText); ObjectSetInteger(0, lab, OBJPROP_COLOR, isBull?InpBullColor:InpBearColor); ObjectSetInteger(0, lab, OBJPROP_FONTSIZE, 11); // Expert log string msg = StringFormat( "%s breakout at %s | Level=%.5f | Close=%.5f | EMA14=%.5f | EMA200=%.5f", side, TimeToString(t, TIME_DATE|TIME_SECONDS), level, iClose(_Symbol,InpTimeframe,shift), ema14, ema200 ); Print(msg); // Pop-up alert + optional sound if(InpAlertsEnabled) { Alert(msg); if(StringLen(InpAlertSoundFile)>0) PlaySound(InpAlertSoundFile); } } //+------------------------------------------------------------------+
Результат
Чтобы протестировать советник, сначала скомпилируйте код в MetaEditor. После компиляции его можно применить к графику в MetaTrader 5 для тестирования в реальных условиях или запустить через Strategy Tester для тестирования на исторических данных. Я протестировал этот советник как в реальных рыночных условиях, так и на исторических данных. Этот этап необходим для точной настройки параметров советника, чтобы добиться нужного торгового поведения и оптимизировать его работу.
График на изображении ниже показывает, как советник выявляет значимый разворот рынка с помощью фракталов и индикаторов EMA. В частности, советник фиксирует медвежий пробой ключевого уровня поддержки, определенного фракталом, и визуально отмечает его на графике. Последующее движение цены подтверждает разворот: рынок продолжает снижаться в соответствии с трендом EMA, а EMA 14 опускается ниже EMA 200, указывая на переход к медвежьему тренду. Визуальные подсказки, такие как метка "BEAR Break", помогают принимать более дисциплинированные решения по входу и выходу. Этот результат показывает способность советника распознавать ранние признаки разворота тренда, позволяя трейдерам использовать возможности с высокой вероятностью успеха и избегать ложных сигналов.

Рис. 3. Сигнал "BEAR Break" на Step Index
GIF ниже показывает, как советник в реальном времени обнаруживает и подтверждает разворот тренда. Он показывает, как система индикаторов определяет фрактальный уровень поддержки или сопротивления и сигнализирует о потенциальном пробое, побуждая трейдера рассмотреть открытие позиции. По мере того как рынок движется в прогнозируемом направлении, сигналы советника подтверждаются взаимным положением EMA: пересечение EMA 14 ниже EMA 200 подтверждает медвежий тренд. Визуальные подсказки, такие как стрелки и алерты, показывают, как советник помогает своевременно принимать решения. Этот пример подчеркивает важность раннего обнаружения в сочетании с подтверждением тренда, что повышает уверенность трейдера и снижает вероятность ложных входов.

Рис. 4. Тестирование на исторических данных на V75 (1s)
Заключение
Этот советник использует индикатор Fractals Билла Вильямса вместе с краткосрочной и долгосрочной экспоненциальными скользящими средними, чтобы находить точки входа с высокой вероятностью успеха. Комбинируя эти инструменты, он улавливает ранние сигналы разворота, которые затем подтверждаются преобладающим рыночным трендом, повышая точность и стабильность исполнения сделок. Тщательное тестирование на исторических данных и в реальных условиях показало его гибкость в различных рыночных условиях, а при тонкой настройке его параметры можно адаптировать для достижения оптимальных результатов. Благодаря наглядным стрелкам и меткам на графике, а также полностью автоматическому размещению ордеров, этот советник привносит в торговлю дисциплину и скорость. По сути, он предлагает системный, основанный на четких правилах подход к анализу Price Action, который хорошо подходит трейдерам, стремящимся сочетать техническую строгость с автоматизацией.
Ознакомьтесь с нашими рекомендуемыми инструментами в таблице ниже.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/18297
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Особенности написания Пользовательских Индикаторов
Торговые инструменты на MQL5 (Часть 17): Изучение векторных скругленных прямоугольников и треугольников
Внедрение в MQL5 практических модулей из других языков (Часть 05): Модуль Logging из Python — ведите логи профессионально
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Интересная статья, и спасибо за исходный код советника. Я опробую его и оставлю отзыв.