Разработка индикатора паттерна "Мегафон" на MQL5
Введение
Хотя платформа MetaTrader 5 предоставляет базовые инструменты для ручного анализа графиков, она не предлагает автоматизированного решения для выявления и подтверждения таких расширяющихся формаций, как паттерн «Мегафон». В результате трейдеры вынуждены анализировать свинговые структуры вручную, создавать расширяющиеся линии тренда и непрерывно отслеживать поведение цены при пробое, что может снизить эффективность и внести непоследовательность в процесс анализа. В этой статье мы создадим собственный индикатор паттерна «Мегафон» на языке MQL5, способный автоматически обнаруживать расширяющиеся бычьи и медвежьи структуры непосредственно на графике. Реализация будет включать в себя обнаружение свингов, уточнение структуры, проверку линий тренда, подтверждение пробоя, а также прогнозирование уровней стоп-лосса и тейк-профита.
Обзор проекта и план его реализации
Прежде чем реализовать это в MQL5, важно четко определить, что именно мы создаем. Процесс разработки становится значительно более целенаправленным и плавным, когда с самого начала есть четкое понимание, каким должен быть конечный результат. Кроме того, это облегчает отслеживание логики и понимание того, как каждый компонент индикатора связан с другими на протяжении всего процесса реализации. В этой главе сосредоточимся на общем обзоре проекта и обсудим пошаговый план его реализации.
Что мы будем создавать
В этом проекте мы разрабатываем индикатор, который обнаруживает паттерн «Мегафон», также известный как расширяющаяся формация. Этот паттерн называется «Мегафон», потому что его структура визуально напоминает громкоговоритель или мегафон на графике, где движение цены становится все шире по мере развития рынка.
Когда колебания цен (свинги) становятся все более агрессивными и приводят к увеличению разрывов между последовательными максимумами и минимумами, возникает паттерн «Мегафон». Расширяющаяся структура, давшая название этому паттерну, образуется в результате вызванного таким расширением постепенного разнесения границ линий тренда. В отсутствие устойчивого доминирования бычьего или медвежьего тренда, подобное усиление активности часто указывает на растущую неопределенность в направлении движения рынка.
При создании этой структуры используются четыре ключевые точки свинга. Сначала мы отмечаем свинг-максимум, а затем свинг-минимум в бычьем паттерне «Мегафон».

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


Кроме того, наряду с этой структурой мы устанавливаем требование пропорционального расстояния, которое гласит, что диапазон между вторым максимумом и вторым минимумом свингов не может значительно увеличиться по сравнению с исходным диапазоном между первым максимумом и минимумом свингов. Ожидается более широкий диапазон значений, но он не должен превышать заранее определенный порог (например, 150% от первоначального диапазона). Это обеспечивает достоверность паттерна и предотвращает искажения. Весь бычий паттерн «Мегафон» формируется за счет такой чередующейся структуры более высоких максимумов и более низких минимумов, при этом линии тренда расширяются с каждым последующим свингом.
Эта серия имеет ту же структурную логику и в медвежьем паттерне «Мегафон»; однако сначала она демонстрирует расширение вниз. Сначала возникает свинг-минимум, а затем — свинг-максимум. Далее мы подтверждаем более глубокое нисходящее движение, обнаруживая второй свинг-минимум, который находится ниже начального свинг-минимума. Более сильный отбой вверх подтверждается последним свинг-максимумом, который располагается выше первого свинг-максимума.

Для поддержания целостности и сбалансированности структуры диапазон между вторыми максимумом и минимумом свингов не должен выходить за пределы заранее определенного процента от начального диапазона свингов. Здесь также применяется то же самое правило пропорциональности. Медвежий вариант паттерна формируется за счет такого чередования более низких минимумов и более высоких максимумов; по мере развития структуры расширяющиеся линии тренда еще больше отдаляются друг от друга.
Наш индикатор автоматически выявит эти свинг-структуры, подтвердит условия их формирования, построит расширяющиеся линии тренда и будет отслеживать рынок на предмет потенциальных возможностей пробоя.
Примечание: во избежание повторений, мы сосредоточимся на объяснении процесса обнаружения бычьего паттерна «Мегафон», поскольку медвежий паттерн следует очень похожей логике.
План реализации
В этом разделе мы пошагово опишем процесс реализации системы обнаружения паттерна «Мегафон» на языке MQL5. В этом разделе представлен план действий, начиная от исходных данных о ценах и заканчивая свинг-точками, проверенными структурами и рабочим индикатором распознавания паттернов с построенными на графике линиями тренда и сигналами.
Определение свинг-точек:
На первом этапе мы сосредоточимся на выявлении подтвержденных свинг-максимумов и свинг-минимумов на основе исторических данных, поскольку эти точки составляют основу всего процесса обнаружения паттернов. Без правильного определения реальных точек разворота рынка становится невозможным построение надежной структуры или подтверждение какой-либо значимой формации. Это достигается путем сканирования заранее определенного диапазона просмотра истории свечей, который определяет объем исторических данных о ценах, которые индикатор будет учитывать при поиске достоверных структур. Например, если параметр lookback установлен на 100, алгоритм будет анализировать только последние 100 свечей на графике, а не всю историю цен.
Мы используем логику проверки с фиксированной глубиной подтверждения в пределах этого диапазона сканирования. Например, если эта глубина установлена на 3, то свинг-максимум считается действительным только в случае превышения максимумом текущей свечи максимумов трех свечей, которые были до и после нее. Аналогичным образом, свинг-минимум подтверждается, когда минимум текущей свечи оказывается ниже минимумов трех свечей по обе стороны от нее. Незначительные свинги цен отфильтровываются, что гарантирует фиксацию только значимых и мощных поворотных моментов на рынке.

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

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

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

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

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

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


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

Однако, прежде чем подтвердить пробой, мы проводим дополнительную проверку целостности на нижней границе, чтобы убедиться, что ни одна свеча ранее не закрывалась ниже нижней линии тренда в течение фазы развития пробоя. Если нижняя граница уже нарушена, конструкция становится недействительной.
Размещение стоп-лосса и тейк-профита:
После подтверждения пробоя заключительным шагом является определение уровней управления сделкой, включая стоп-лосс и тейк-профит. Такие уровни выводятся непосредственно из структуры паттерна «Мегафон», и это гарантирует, что риск и вознаграждение основаны на реальной геометрии рынка, а не на произвольных значениях. Стоп-лосс рассчитывается с использованием расстояния между двумя линиями тренда в зоне пробоя. В частности, он расположен посередине вертикального диапазона этой структуры, обеспечивая сбалансированный буфер риска между обеими границами. Это обеспечивает защиту сделки, сохраняя при этом естественную структуру паттерна.
Прогнозируемый уровень тейк-профита рассчитывается с использованием того же структурного диапазона, но расширенного за пределы точки пробоя. Этот прогноз основан на расстоянии между границами линий тренда, фактически отражающем высоту структуры, что позволяет оценить реалистичную целевую цену. Для обеспечения их визуальной различимости на графике уровни SL и TP представлены с помощью графических объектов. На каждом уровне проводится горизонтальная линия, а соответствующая им текстовая метка («SL» или «TP») добавляется для четкого обозначения их позиций. Это позволяет трейдерам визуально отслеживать риски и потенциальную прибыль непосредственно на графике после получения сигнала о пробое.

Примечание: проект, описанный в этой статье, полностью основан на практическом применении знания языка MQL5 и предназначен для практического обучения читателей этому языку. Он не является гарантированным методом получения прибыли при реальной торговле.
Реализация на языке MQL5
В этой главе перейдем от теоретического проектирования системы обнаружения паттернов «Мегафон» к ее практической реализации на языке MQL5. Используя логику, изложенную в предыдущих разделах, будем постепенно, шаг за шагом, создавать индикатор, преобразуя каждый компонент в работающий элемент функциональности MQL5.
Определение свинг-точек
Как и обсуждалось в плане реализации, начнем с определения подтвержденных свинг-максимумов и свинг-минимумов, поскольку они составляют основу всего процесса обнаружения паттернов «Мегафон».
Пример:
#property indicator_chart_window #property indicator_buffers 0 #property indicator_plots 0 #define OBJ_PREFIX "MG_" // Prefix for all chart objects int look_back = 300; // number of candles to scan for pattern detection int SwingLookback = 3; // swing validation range (left and right candles) int window_start; // starting index of scan window datetime lastTradeBarTime = 0; // ensures logic runs once per new bar //--- Bullish Megaphone Pattern Swing Structure Variables (Pattern Anchors) double s1_h; // first swing high price (S1) datetime s1_h_t; // first swing high time double s2_l; // first swing low price (S2) datetime s2_l_t; // first swing low time double s3_h; // second swing high price (S3) datetime s3_h_t; // second swing high time double s4_l; // second swing low price (S4) datetime s4_l_t; // second swing low time //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- 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[]) { //--- ensure enough history is available before processing if(rates_total < look_back) return 0; window_start = rates_total - look_back + SwingLookback; // define scanning window datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0); // current candle time //--- execute logic only once per new candle if(currentBarTime != lastTradeBarTime) { //--- loop through candles within lookback window for(int i = window_start; i < rates_total - SwingLookback - 2; i++) { //--- detect first swing high (S1) if(IsSwingHigh(high, i, SwingLookback)) { s1_h = high[i]; // store S1 price s1_h_t = time[i]; // store S1 time //--- search for first swing low (S2) for(int j = i; j < rates_total - SwingLookback - 2; j++) { if(IsSwingLow(low, j, SwingLookback)) { s2_l = low[j]; // store S2 price s2_l_t = time[j]; // store S2 time //--- search for second swing high (S3) for(int k = j; k < rates_total - SwingLookback - 2; k++) { if(IsSwingHigh(high, k, SwingLookback) && high[k] > s1_h) { s3_h = high[k]; // store S3 price s3_h_t = time[k]; // store S3 time //--- search for second swing low (S4) for(int l = k; l < rates_total - SwingLookback - 2; l++) { if(IsSwingLow(low, l, SwingLookback) && low[l] < s2_l) { s4_l = low[l]; // store S4 price s4_l_t = time[l]; // store S4 time break; } } break; } } break; } } } } lastTradeBarTime = currentBarTime; // update last processed bar } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| FUNCTION FOR SWING LOW | //+------------------------------------------------------------------+ bool IsSwingLow(const double &low_price[], int index, int lookback) { for(int i = 1; i <= lookback; i++) { if(low_price[index] > low_price[index - i] || low_price[index] > low_price[index + i]) return false; } return true; } //+------------------------------------------------------------------+ //| FUNCTION FOR SWING HIGH | //+------------------------------------------------------------------+ bool IsSwingHigh(const double &high_price[], int index, int lookback) { for(int i = 1; i <= lookback; i++) { if(high_price[index] < high_price[index - i] || high_price[index] < high_price[index + i]) return false; } return true; } //+------------------------------------------------------------------+
То есть:
Чтобы определить, сколько исторических свечей индикатор будет анализировать при поиске паттерна «Мегафон», процесс начинается с определения фиксированного диапазона просмотра истории. В данном случае значение ограничивает сканирование последними 300 свечей, гарантируя, что алгоритм сосредоточится на существенной рыночной информации, избегая при этом ненужных вычислений на основе истории цен за прошлые периоды. Затем значение SwingLookback используется для определения глубины проверки свинга. Это регулирует количество свечей слева и справа, используемых для выяснения, является свеча свинг-максимумом или свинг-минимумом цены. В то время как более высокое значение отфильтровывает шум и концентрируется преимущественно на более важных поворотных точках рынка, меньшее значение повышает чувствительность системы к небольшим колебаниям.
Затем с помощью переменной window_start задается начальная точка операции сканирования внутри диапазона просмотра истории. Это гарантирует, что функция не начнет работу в наборе данных слишком рано, когда отсутствие окружающих свечей сделает проверку свингов ненадежной. Это позволяет успешно установить надежный предел для структурированного анализа. Логика настроена таким образом, чтобы работать именно один раз для каждой новой произведенной свечи, чтобы обеспечивать эффективность. Время последнего обработанного бара хранится в переменной lastTradeBarTime, которая используется для регулирования этого аспекта.
Система позволяет избежать выполнения всего процесса обнаружения на каждом тике, сравнивая его с текущим временем свечи, что способствует сохранению эффективности и исключает повторные вычисления. Индикатор начинает просмотр исторических свечей в пределах заданного окна после того, как будут выполнены критерии исполнения. Он последовательно анализирует данные о ценах для выявления возможных свинг-максимумов, которые могут стать началом формирования бычьего тренда с паттерном «Мегафон». Индикатор фиксирует действительный свинг-максимум на уровне S1 — начальной опорной точке бычьей структуры «Мегафон». После этого цена движется в поисках подтвержденного свинг-минимума (S2) и второго свинг-максимума (S3). Для того чтобы структура оставалась допустимой, значение S3 должно быть больше значения S1, что указывает на расширение, а не сужение структуры движения цены.
Система ищет S4, второй свинг-минимум, который должен быть ниже S2. Необходимая для формирования бычьего паттерна «Мегафон» структура на четырех точках теперь сформирована. Каждый оператор прерывания гарантирует, что поиск будет продолжаться последовательно, без наложения или повторного обнаружения структуры после того, как будет идентифицирована допустимая свинг-точка. На протяжении всего процесса используются специальные функции проверки свингов, чтобы подтвердить, действительно ли свеча является свинг-максимумом или свинг-минимумом.
Свинг-максимум считается достигнутым только в том случае, если его максимум превышает максимумы окружающих свечей в пределах заданного диапазона просмотра истории, тогда как свинг-минимум должен быть ниже минимумов соседних свечей. Это гарантирует, что при построении структуры паттерна используются только значимые точки разворота рынка. Для эффективного восприятия структуры, с которой мы работаем на графике, крайне важно начать с построения линий тренда как части процесса разработки. Это позволяет нам убедиться в точности определения свинг-точек и в том, что формирование паттернов соответствует реальной структуре рынка.
Пример://--- Trendline Object Variables string line_s1_3; string line_s2_4; //+------------------------------------------------------------------+ //| Create or update a trendline | //| Returns true if a new object was created | //+------------------------------------------------------------------+ bool DrawTrend(const string name, datetime x1t, double x1, datetime x2t, double x2, color fillCol) { bool created = false; //--- Create object only if it does not exist if(ObjectFind(0, name) < 0) { ObjectCreate(0, name, OBJ_TREND, 0, x1t, x1, x2t, x2); //--- Set object properties ObjectSetInteger(0,name,OBJPROP_COLOR,fillCol); created = true; } return created; } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| OnDeinit - runs when indicator is removed | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ObjectsDeleteAll(0,OBJ_PREFIX); // delete all indicator's objects }
//+------------------------------------------------------------------+ //| 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[]) { //--- ensure enough history is available before processing if(rates_total < look_back) return 0; window_start = rates_total - look_back + SwingLookback; // define scanning window datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0); // current candle time bool need_redraw = false; //--- execute logic only once per new candle if(currentBarTime != lastTradeBarTime) { //--- loop through candles within lookback window for(int i = window_start; i < rates_total - SwingLookback - 2; i++) { //--- detect first swing high (S1) if(IsSwingHigh(high, i, SwingLookback)) { s1_h = high[i]; // store S1 price s1_h_t = time[i]; // store S1 time //--- search for first swing low (S2) for(int j = i; j < rates_total - SwingLookback - 2; j++) { if(IsSwingLow(low, j, SwingLookback)) { s2_l = low[j]; // store S2 price s2_l_t = time[j]; // store S2 time //--- search for second swing high (S3) for(int k = j; k < rates_total - SwingLookback - 2; k++) { if(IsSwingHigh(high, k, SwingLookback) && high[k] > s1_h) { s3_h = high[k]; // store S3 price s3_h_t = time[k]; // store S3 time //--- search for second swing low (S4) for(int l = k; l < rates_total - SwingLookback - 2; l++) { if(IsSwingLow(low, l, SwingLookback) && low[l] < s2_l) { s4_l = low[l]; // store S4 price s4_l_t = time[l]; // store S4 time line_s1_3 = OBJ_PREFIX + "Line S13" + TimeToString(time[i]) + TimeToString(time[k]); if(DrawTrend(line_s1_3,s1_h_t,s1_h,s3_h_t,s3_h,clrBlue)) { need_redraw = true; } line_s2_4 = OBJ_PREFIX + "Line S24" + TimeToString(time[j]) + TimeToString(time[l]); if(DrawTrend(line_s2_4,s2_l_t,s2_l,s4_l_t,s4_l,clrBlue)) { need_redraw = true; } break; } } break; } } break; } } } } lastTradeBarTime = currentBarTime; // update last processed bar } //--- Redraw only if something changed if(need_redraw) ChartRedraw(0); //--- return value of prev_calculated for next call return(rates_total); }
Выводимая информация:

То есть:
На этом этапе алгоритм начинает управлять визуальным отображением бычьей структуры «Мегафона», создавая соответствующие линии тренда. Перед созданием любого объекта объявляются две строковые переменные (line_s1_3 и line_s2_4) для различения верхней и нижней линий тренда. Каждая структура типа «Мегафон» управляется независимо, а конфликты между объектами графика предотвращаются за счет использования для них различных имен. Основная задача функции DrawTrend — построение линий тренда, необходимых для отображения бычьей структуры «Мегафон». Эта функция создает объект линии тренда на графике, соединяя две опорные точки с использованием их временных и ценовых координат.
Во избежание постоянного построения одних и тех же линий тренда во время выполнения индикатора функция сначала использует ObjectFind для поиска существующего объекта с тем же именем, что обеспечивает четкость управления объектами. Основная задача функции DrawTrend — создание линий тренда, используемых для представления бычьей структуры «Мегафон». Принцип работы заключается в соединении двух опорных точек по временным и ценовым координатам для создания на графике объекта «линия тренда». Для обеспечения корректного управления объектами функция сначала проверяет наличие существующего объекта с тем же именем с помощью функции ObjectFind, что помогает избежать многократного построения идентичных линий тренда во время работы индикатора.
Кроме того, для корректной очистки графика при удалении индикатора используется метод OnDeinit. При удалении индикатора все объекты, созданные этой системой, удаляются с использованием общего префикса. После выгрузки индикатора это предотвращает перегрузку графика оставшимися линиями тренда. Первый свинг-максимум (S1) и второй свинг-максимум (S3) образуют верхнюю линию тренда в основной логике, а первый свинг-минимум (S2) и второй свинг-минимум (S4) формируют нижнюю линию тренда. Чтобы гарантировать сохранение уникальности каждого обнаруженного на графике паттерна, каждой линии присваивается уникальный идентификатор, созданный на основе префикса объекта и временных меток свингов. После каждой успешно завершенной операции отрисовки флаг need_redraw устанавливается в значение true. Это означает, что требуется обновление, поскольку изменилось состояние графика. Наконец, функция ChartRedraw(0) вызывается для обновления графика и мгновенного отображения вновь созданной структуры, когда создан или изменен хотя бы один новый объект.
Доведение свинг-точек до истинных экстремумов
Следующий шаг направлен на приведение первоначально обнаруженных свинг-точек к их истинным рыночным экстремумам в рамках каждого свинг-сегмента.
Пример:
//--- S3 to S4 refinement (upper expansion leg) int s3_s4_hbars; // bars between S3 and S4 for extreme search double s3_highest; // highest price between S3 and S4 datetime s3_highest_t; // time of highest price between S3 and S4 int s3_highest_index; // index of highest price between S3 and S4 //--- S2 to S3 refinement (middle structure leg) int s2_s3_lbars; // bars between S2 and S3 for extreme search double s2_lowest; // lowest price between S2 and S3 datetime s2_lowest_t; // time of lowest price between S2 and S3 int s2_lowest_index; // index of lowest price between S2 and S3 //--- S1 to S2 refinement (initial structure leg) int s1_s2_hbars; // bars between S1 and S2 for extreme search double s1_highest; // highest price between S1 and S2 datetime s1_highest_t; // time of highest price between S1 and S2 int s1_highest_index; // index of highest price between S1 and S2
//--- search for second swing low (S4) for(int l = k; l < rates_total - SwingLookback - 2; l++) { if(IsSwingLow(low, l, SwingLookback) && low[l] < s2_l) { s4_l = low[l]; // store S4 price s4_l_t = time[l]; // store S4 time //--- refine S3 by locating the true highest high between S3 and S4 s3_s4_hbars = Bars(_Symbol, PERIOD_CURRENT, s3_h_t, s4_l_t); // total bars between S3 and S4 s3_highest = high[ArrayMaximum(high, k, s3_s4_hbars)]; // highest price within S3 to S4 range s3_highest_t = time[ArrayMaximum(high, k, s3_s4_hbars)]; // time of refined S3 high s3_highest_index = ArrayMaximum(high, k, s3_s4_hbars); // index of refined S3 high //--- refine S2 by locating the true lowest low between S2 and refined S3 s2_s3_lbars = Bars(_Symbol, PERIOD_CURRENT, s2_l_t, s3_highest_t); // total bars between S2 and refined S3 s2_lowest_index = ArrayMinimum(low, j, s2_s3_lbars); // index of refined S2 low s2_lowest = low[s2_lowest_index]; // lowest price within S2 to S3 range s2_lowest_t = time[s2_lowest_index]; // time of refined S2 low //--- refine S1 by locating the true highest high between S1 and refined S2 s1_s2_hbars = Bars(_Symbol, PERIOD_CURRENT, s1_h_t, s2_lowest_t); // total bars between S1 and refined S2 s1_highest_index = ArrayMaximum(high, i, s1_s2_hbars); // index of refined S1 high s1_highest = high[s1_highest_index]; // highest price within S1 to S2 range s1_highest_t = time[s1_highest_index]; // time of refined S1 high //--- create trend line connecting first swing high (S1) and second swing high (S3) line_s1_3 = OBJ_PREFIX + "Line S13" + TimeToString(time[i]) + TimeToString(time[k]); //--- draw upper trend line of bullish megaphone structure (S1 to S3) if(DrawTrend(line_s1_3, s1_highest_t, s1_h, s3_highest_t, s3_highest, clrBlue)) { need_redraw = true; // flag chart for update after successful drawing } //--- create trend line connecting first swing low (S2) and second swing low (S4) line_s2_4 = OBJ_PREFIX + "Line S24" + TimeToString(time[j]) + TimeToString(time[l]); //--- draw lower trend line of bullish megaphone structure (S2 to S4) if(DrawTrend(line_s2_4, s2_lowest_t, s2_lowest, s4_l_t, s4_l, clrBlue)) { need_redraw = true; // flag chart for update after successful drawing } break; } }
Выводимая информация:

То есть:
В этом разделе выполняется описанный ранее процесс уточнения путем замены первоначально обнаруженных свинг-точек истинными рыночными экстремумами, найденными в каждом свинг-сегменте. Вместо того чтобы полагаться только на первые обнаруженные свинг-точки, алгоритм сканирует каждый сегмент структуры, чтобы определить действительно самые высокие максимумы и самые низкие минимумы, которые лучше всего отражают бычий паттерн «Мегафон». Второй свинг-максимум (S3) — это первый шаг в процедуре. Во-первых, система использует функцию Bars() для определения количества баров между идентифицированными точками S3 и S4. Это указывает на количество свечей, имеющихся в целом в данном свинг-сегменте. Затем самая высокая цена обнаруживается путем поиска по массиву максимальных цен в этом диапазоне с помощью функции ArrayMaximum().
Возвращаемое значение указывает на местоположение самой высокой точки между S3 и S4. Далее алгоритм использует этот индекс для сохранения точной точки индекса, уточненной максимальной цены и ее временной метки. Затем происходит уточнение до начального свинг-минимума (S2). После этого система определяет количество свечей между S2 и недавно уточненным максимумом S3 после получения уточненной точки S3. Затем массив низких цен внутри этого региона сканируется с помощью функции ArrayMinimum() для определения фактического самого низкого минимума. После определения местоположения алгоритм сохраняет индекс массива, метку времени и уточненную минимальную цену. На заключительном этапе уточнения обновляется первый свинг-максимум (S1). Теперь алгоритм сканирует пространство между исходным уровнем S1 и только что уточненным минимумом S2, чтобы определить истинный самый высокий максимум в этом сегменте. С помощью функции ArrayMaximum() извлекается уточненный индекс S1, а затем эта позиция используется для получения соответствующих значений цены и времени.
В результате этого процесса доработки обновляется и логика построения линий тренда. Вместо соединения исходных свинг-точек, верхняя линия тренда теперь соединяет уточненные максимумы S1 и S3, а нижняя линия тренда соединяет уточненный минимум S2 и существующий минимум S4. Это позволяет получить более точное представление о бычьей структуре типа «Мегафон», поскольку линии тренда теперь привязаны к истинным рыночным экстремумам, а не к первоначально обнаруженным свинг-точкам.
Проверка целостности линии тренда
Следующий шаг направлен на проверку целостности бычьих линий тренда типа «Мегафон», чтобы убедиться, что ни одна свеча не закрылась некорректно, пересекая границы структуры до подтверждения пробоя.
Пример://--- Trend line integrity validation variables bool is_line_s13_break; // tracks if any candle closed below upper trend line (S1 to S3) bool is_line_s24_break; // tracks if any candle closed above lower trend line (S2 to S4) double line_s13_value; // stores upper trend line price at a specific candle double line_s24_value; // stores lower trend line price at a specific candle //--- validation thresholds for structural integrity of bullish megaphone pattern double s1_2_limit; // maximum allowed expansion limit between S1 and S2 leg double s2_4_interval; // measured distance between S2 and S4 swing legs
//--- search for second swing low (S4) for(int l = k; l < rates_total - SwingLookback - 2; l++) { if(IsSwingLow(low, l, SwingLookback) && low[l] < s2_l) { s4_l = low[l]; // store S4 price s4_l_t = time[l]; // store S4 time //--- refine S3 by locating the true highest high between S3 and S4 s3_s4_hbars = Bars(_Symbol, PERIOD_CURRENT, s3_h_t, s4_l_t); // total bars between S3 and S4 s3_highest = high[ArrayMaximum(high, k, s3_s4_hbars)]; // highest price within S3 to S4 range s3_highest_t = time[ArrayMaximum(high, k, s3_s4_hbars)]; // time of refined S3 high s3_highest_index = ArrayMaximum(high, k, s3_s4_hbars); // index of refined S3 high //--- refine S2 by locating the true lowest low between S2 and refined S3 s2_s3_lbars = Bars(_Symbol, PERIOD_CURRENT, s2_l_t, s3_highest_t); // total bars between S2 and refined S3 s2_lowest_index = ArrayMinimum(low, j, s2_s3_lbars); // index of refined S2 low s2_lowest = low[s2_lowest_index]; // lowest price within S2 to S3 range s2_lowest_t = time[s2_lowest_index]; // time of refined S2 low //--- refine S1 by locating the true highest high between S1 and refined S2 s1_s2_hbars = Bars(_Symbol, PERIOD_CURRENT, s1_h_t, s2_lowest_t); // total bars between S1 and refined S2 s1_highest_index = ArrayMaximum(high, i, s1_s2_hbars); // index of refined S1 high s1_highest = high[s1_highest_index]; // highest price within S1 to S2 range s1_highest_t = time[s1_highest_index]; // time of refined S1 high //--- create trend line connecting first swing high (S1) and second swing high (S3) line_s1_3 = OBJ_PREFIX + "Line S13" + TimeToString(time[i]) + TimeToString(time[k]); //--- draw upper trend line of bullish megaphone structure (S1 to S3) if(DrawTrend(line_s1_3, s1_highest_t, s1_h, s3_highest_t, s3_highest, clrBlue)) { ObjectSetInteger(0, line_s1_3, OBJPROP_TIMEFRAMES, OBJ_NO_PERIODS); need_redraw = true; // flag chart for update after successful drawing } //--- create trend line connecting first swing low (S2) and second swing low (S4) line_s2_4 = OBJ_PREFIX + "Line S24" + TimeToString(time[j]) + TimeToString(time[l]); //--- draw lower trend line of bullish megaphone structure (S2 to S4) if(DrawTrend(line_s2_4, s2_lowest_t, s2_lowest, s4_l_t, s4_l, clrBlue)) { ObjectSetInteger(0, line_s2_4, OBJPROP_TIMEFRAMES, OBJ_NO_PERIODS); need_redraw = true; // flag chart for update after successful drawing } //--- validate upper trend line integrity (S1 to S3) is_line_s13_break = false; //--- scan candles between refined S1 and refined S3 for(int y = s1_highest_index; y <= s3_highest_index; y++) { // retrieve upper trend line price at current candle time line_s13_value = ObjectGetValueByTime(0, line_s1_3, time[y], 0); // check if candle closed above the upper trend line if(close[y] > line_s13_value) { is_line_s13_break = true; // invalidate structure if breakout occurs inside pattern break; } } //--- validate lower trend line integrity (S2 to S4) is_line_s24_break = false; //--- scan candles between refined S2 and S4 for(int z = s2_lowest_index; z <= l; z++) { // retrieve lower trend line price at current candle time line_s24_value = ObjectGetValueByTime(0, line_s2_4, time[z], 0); // check if candle closed below the lower trend line if(close[z] < line_s24_value) { is_line_s24_break = true; // invalidate structure if breakout occurs inside pattern break; } } //--- calculate maximum allowed structure expansion limit (based on S1 to S2 range) s1_2_limit = (s1_highest - s2_lowest) * 1.5; //--- measure actual expansion between upper and lower refined swings (S3 to S4) s2_4_interval = s3_highest - s4_l; //--- confirm bullish megaphone structure validity conditions if(is_line_s13_break == false && is_line_s24_break == false && s2_lowest < s1_highest && s3_highest > s1_highest && s4_l < s2_lowest && s2_4_interval <= s1_2_limit) { //--- temporarily activate trend lines across all timeframes once structure is validated ObjectSetInteger(0, line_s1_3, OBJPROP_TIMEFRAMES, OBJ_ALL_PERIODS); ObjectSetInteger(0, line_s2_4, OBJPROP_TIMEFRAMES, OBJ_ALL_PERIODS); } break; } }
То есть:
Линии тренда для бычьей формации типа «Мегафон» сразу же скрываются на графике после создания. Это сделано умышленно, чтобы пользователю не пришлось видеть неполные или неподтвержденные структуры. Система еще не проверила корректность конструкции; она лишь выявила возможные свинг-точки и определила соответствующие верхние и нижние границы. Линии тренда используются внутри системы для проверки и в качестве ориентира, когда для параметра отображения установлено значение «без периодов», но они не отображаются до тех пор, пока не будут выполнены все требования.
Проверка начинается с оценки целостности верхней линии тренда, соединяющей S1 и S3. Алгоритм сканирует каждую свечу между этими двумя уточненными свинг-точками, после чего сравнивает цену закрытия каждой свечи со значением линии тренда в данный конкретный момент. Любая свеча, закрывающаяся выше верхней линии тренда, указывает на то, что формация больше недействительна, поскольку цена преждевременно пробила прогнозируемую структуру. В этом случае формация оперативно идентифицируется как поврежденная и не подлежит дополнительной проверке. Нижняя линия тренда, соединяющая S2 и S4, проходит через аналогичный процесс.
Система проверяет каждую свечу между этими участками, определяя, закрылись ли какие-либо свечи ниже нижней границы. Если этот критерий выполняется, в этом случае паттерн считается недействительным, поскольку структура нарушена. Это гарантирует, что единственными ценовыми колебаниями, которые признаются приемлемыми формациями типа «Мегафон», являются те, которые сохраняют четкость и непрерывность в пределах установленных границ. Данный метод оценивает общие характеристики расширения паттерна после проверки его структурной целостности. Он позволяет установить ограничение, предотвращающее чрезмерное растяжение конструкции путем измерения начального свинг-диапазона и сравнения его с полным расширением между последующими свинг-позициями. Это помогает устранить ошибочные паттерны, которые неточно отображают паттерн «Мегафон».
Наконец, когда выполнены все условия, включая отсутствие внутренних пробоев и надлежащее расширение с обеих сторон, ранее скрытые линии тренда активируются и становятся видимыми на всех таймфреймах. На данном этапе структура считается полностью подтвержденной, а рыночная формация официально признана полноценным бычьим паттерном «Мегафон».
Подтверждение структурного пробоя
На этом этапе мы подтверждаем фактический пробой проверенной структуры «Мегафон», отслеживая движение цены за пределы линий тренда, чтобы определить окончательное направленное движение, сигнализирующее о потенциальной возможности торговли.
Пример:
//-- object variables string buy_obj; //+------------------------------------------------------------------+ //| Create buy and sell objects | //+------------------------------------------------------------------+ bool DrawObject(const string name, datetime xt, double x, ENUM_OBJECT obj_type) { bool created = false; //--- Create object only if it does not exist if(ObjectFind(0, name) < 0) { ObjectCreate(0,name,obj_type,0,xt,x); created = true; } return created; }
//--- confirm bullish megaphone structure validity conditions if(is_line_s13_break == false && is_line_s24_break == false && s2_lowest < s1_highest && s3_highest > s1_highest && s4_l < s2_lowest && s2_4_interval <= s1_2_limit) { //--- hide trend lines from chart ObjectSetInteger(0, line_s1_3, OBJPROP_TIMEFRAMES, OBJ_NO_PERIODS); ObjectSetInteger(0, line_s2_4, OBJPROP_TIMEFRAMES, OBJ_NO_PERIODS); //--- extend trend lines to the right for real-time breakout monitoring ObjectSetInteger(0, line_s1_3, OBJPROP_RAY_RIGHT, true); ObjectSetInteger(0, line_s2_4, OBJPROP_RAY_RIGHT, true); //--- scan forward from pattern completion point to detect breakout event for(int m = l; m <= rates_total - 2; m++) { //--- get current upper and lower trend line values at candle time line_s13_cross_value = ObjectGetValueByTime(0, line_s1_3, time[m], 0); line_s24_cross_value = ObjectGetValueByTime(0, line_s2_4, time[m], 0); //--- check if price breaks above upper trend line (bullish breakout trigger) if(close[m] > line_s13_cross_value) { //--- move trend lines forward to breakout point for accurate alignment ObjectMove(0, line_s1_3, 1, time[m], line_s13_cross_value); ObjectMove(0, line_s2_4, 1, time[m], line_s24_cross_value); //--- reset revalidation flag for lower structure check is_line_s24_break_check = false; //--- confirm lower trend line has not been violated before breakout for(int x = l; x <= m; x++) { line_s24_break_check = ObjectGetValueByTime(0, line_s2_4, time[x], 0); //--- invalidate breakout if price closed below lower trend line earlier if(close[x] < line_s24_break_check) { is_line_s24_break_check = true; break; } } //--- confirm valid bullish breakout (no internal structure violation) if(is_line_s24_break_check == false) { //--- finalize trend line state and make it visible across all timeframes ObjectSetInteger(0, line_s1_3, OBJPROP_RAY_RIGHT, false); ObjectSetInteger(0, line_s2_4, OBJPROP_RAY_RIGHT, false); ObjectSetInteger(0, line_s1_3, OBJPROP_TIMEFRAMES, OBJ_ALL_PERIODS); ObjectSetInteger(0, line_s2_4, OBJPROP_TIMEFRAMES, OBJ_ALL_PERIODS); //--- generate bullish entry signal at breakout candle buy_obj = OBJ_PREFIX + "Buy OBJ" + TimeToString(time[m]); if(DrawObject(buy_obj, time[m], close[m], OBJ_ARROW_BUY)) { need_redraw = true; // refresh chart after signal creation } } break; // stop scanning after first valid breakout } } }
Выводимая информация:

То есть:
Функция DrawObject обрабатывает эти сигнальные маркеры, принимая во внимание тип объекта, ценовой уровень, время сигнальной свечи и уникальное имя. Во-первых, код проверяет график, чтобы узнать, существует ли уже объект с таким же идентификатором. Благодаря этому удается избежать дублирования сигнальных маркеров. Функция возвращает true, указывая на успешное выполнение отрисовки, если объект еще не существует и создается по указанной цене и в указанное время.
На этом этапе линии тренда сначала скрываются с графика с помощью элемента управления таймфреймами. Это исключает их отображение на всех таймфреймах графика, хотя они по-прежнему присутствуют внутри индикатора. Цель этого действия — предотвратить преждевременную или вводящую в заблуждение визуализацию структуры, для которой еще не подтвержден достоверный пробой. Мы фактически оставляем паттерн «в режиме наблюдения», не показывая его пользователю. Несмотря на то что линии скрыты, они не являются неактивными. Вместо этого, они продолжаются вправо с помощью расширения лучей, так что они продолжают проецироваться вперед во времени. Это важно, поскольку позволяет индикатору в реальном времени отслеживать движение цены относительно структурных границ. Иными словами, линии невидимы, но по-прежнему активно используются для обнаружения пробоев.
После этой настройки система начинает сканирование вперед от точки, где полностью завершена сборка свинг-структуры. Этот цикл представляет собой переход от формирования паттернов к мониторингу пробоев. Для каждой новой свечи после завершения формирования паттерна индикатор извлекает текущее значение верхней и нижней линий тренда на соответствующий момент времени. Это позволяет ему постоянно сравнивать поведение цен с развивающейся структурой рынка. Возможный бычий пробой определяется закрытием цены выше верхней линии тренда. В этот момент система не подтверждает сделку мгновенно. Вместо этого, первоначально линии тренда корректируются: их вторые опорные точки переносятся к свече пробоя. Это сохраняет линии тренда выровненными по фактической точке пробоя.
Однако до подтверждения пробоя проводится дополнительная проверка. Система проверяет, не нарушила ли какая-либо свеча нижнюю линию тренда в промежутке между завершением формирования паттерна и пробоем. Этот шаг имеет решающее значение, поскольку подтвержденный бычий пробой не должен был ранее пробивать противоположную границу. Если в течение этого периода какая-либо свеча закроется ниже нижней линии тренда, структура считается недействительной, а пробой отклоняется.
Только если структура пройдет эту проверку на целостность, пробой будет признан действительным. На этом этапе линии тренда окончательно формируются путем отключения расширения лучей и повторного отображения их на всех таймфреймах. Это знаменует переход от скрытой аналитической структуры к подтвержденному графическому паттерну. Объект «сигнал на покупку» создается в точке свечи пробоя. Этот объект представляет собой подтвержденную точку входа бычьего паттерна «Мегафон» и отображается на графике как конечный результат процесса обнаружения.
Размещение стоп-лосса и тейк-профита
На этом заключительном этапе мы рассчитываем и устанавливаем уровни стоп-лосса и тейк-профита на основе подтвержденной структуры пробоя и отображаем их на графике с помощью объектов для наглядной визуализации риска и потенциальной прибыли.
Пример://-- object variables string buy_obj; double sl; string sl_line_obj; string sl_txt_obj; double tp; string tp_line_obj; string tp_txt_obj;
//--- scan forward from pattern completion point to detect breakout event for(int m = l; m <= rates_total - 2; m++) { //--- get current upper and lower trend line values at candle time line_s13_cross_value = ObjectGetValueByTime(0, line_s1_3, time[m], 0); line_s24_cross_value = ObjectGetValueByTime(0, line_s2_4, time[m], 0); //--- check if price breaks above upper trend line (bullish breakout trigger) if(close[m] > line_s13_cross_value) { //--- move trend lines forward to breakout point for accurate alignment ObjectMove(0, line_s1_3, 1, time[m], line_s13_cross_value); ObjectMove(0, line_s2_4, 1, time[m], line_s24_cross_value); //--- reset revalidation flag for lower structure check is_line_s24_break_check = false; //--- confirm lower trend line has not been violated before breakout for(int x = l; x <= m; x++) { line_s24_break_check = ObjectGetValueByTime(0, line_s2_4, time[x], 0); //--- invalidate breakout if price closed below lower trend line earlier if(close[x] < line_s24_break_check) { is_line_s24_break_check = true; break; } } //--- confirm valid bullish breakout (no internal structure violation) if(is_line_s24_break_check == false) { //--- finalize trend line state and make it visible across all timeframes ObjectSetInteger(0, line_s1_3, OBJPROP_RAY_RIGHT, false); ObjectSetInteger(0, line_s2_4, OBJPROP_RAY_RIGHT, false); ObjectSetInteger(0, line_s1_3, OBJPROP_TIMEFRAMES, OBJ_ALL_PERIODS); ObjectSetInteger(0, line_s2_4, OBJPROP_TIMEFRAMES, OBJ_ALL_PERIODS); //--- generate bullish entry signal at breakout candle buy_obj = OBJ_PREFIX + "Buy OBJ" + TimeToString(time[m]); if(DrawObject(buy_obj, time[m], close[m], OBJ_ARROW_BUY)) { need_redraw = true; // refresh chart after signal creation } //--- calculate stop loss at midpoint of breakout structure range sl = ((line_s13_cross_value - line_s24_cross_value) / 2) + line_s24_cross_value; //--- create stop loss trend line object identifier sl_line_obj = OBJ_PREFIX + "SL line" + TimeToString(time[l]) + TimeToString(time[m]); //--- draw stop loss level on chart if(DrawTrend(sl_line_obj, time[l], sl, time[m], sl, clrRed)) { need_redraw = true; // refresh chart after SL line is drawn } //--- create stop loss label object at breakout candle sl_txt_obj = OBJ_PREFIX + "SL Text" + TimeToString(time[m]); //--- display "SL" text on chart at calculated stop loss level if(DrawTxt(sl_txt_obj, time[m], sl, "SL", clrRed)) { need_redraw = true; // refresh chart after SL label is drawn } //--- calculate take profit based on full height of breakout structure tp = (line_s13_cross_value - line_s24_cross_value) + line_s13_cross_value; //--- create take profit trend line object identifier tp_line_obj = OBJ_PREFIX + "TP line" + TimeToString(time[l]) + TimeToString(time[m]); //--- draw take profit level on chart if(DrawTrend(tp_line_obj, time[l], tp, time[m], tp, clrGreen)) { need_redraw = true; // refresh chart after TP line is drawn } //--- create take profit label object at breakout candle tp_txt_obj = OBJ_PREFIX + "TP Text" + TimeToString(time[m]); //--- display "TP" text on chart at calculated take profit level if(DrawTxt(tp_txt_obj, time[m], tp, "TP", clrGreen)) { need_redraw = true; // refresh chart after TP label is drawn } } break; // stop scanning after first valid breakout } }
Выводимая информация:

То есть:
В этой стратегии для расчета уровня стоп-лосса используется среднее значение разницы между верхней и нижней линиями тренда пробойной структуры. Все расстояние между двумя пределами измеряется, делится на два и прибавляется к нижнему уровню. Размещая уровень стоп-лосса в середине структуры, эта стратегия гарантирует, что он будет соответствовать волатильности паттерна и не окажется слишком близко или слишком далеко от ценового движения.
После определения значения уровня стоп-лосса для него генерируется уникальное имя объекта, а на графике на этом ценовом уровне рисуется горизонтальная линия. Это визуальное представление помогает четко обозначить границы риска. Кроме того, на том же уровне размещается текстовая метка с обозначением «SL», чтобы трейдер мог легко идентифицировать ее на графике. Каждый раз при успешном создании этих объектов график помечается для перерисовки, чтобы обновления стали видны на графике.
После этого на основе полной высоты структуры пробоя рассчитывается уровень тейк-профита. Расстояние между верхней и нижней линиями тренда проецируется вверх от верхней границы, фактически создавая целевую точку для расчетного движения. Такой подход предполагает, что после пробоя цена увеличится примерно на ту же величину. Затем на уровне тейк-профита строится линия тренда с использованием еще одного уникального идентификатора объекта, за которой следует текстовая метка «TP», указывающая на целевой уровень прибыли. Точно так же, как и в случае со стоп-лоссом, график обновляется с учетом этих новых объектов.
Заключение
Завершив эту статью, мы разработали полную и структурированную основу для обнаружения паттерна «Мегафон» на MQL5, предназначенную для практического и проверяемого применения перед полномасштабной реализацией. Основное внимание было уделено разделению процесса обнаружения на четкие, логичные этапы, обеспечивающие точность, согласованность и более эффективную отладку на протяжении всего процесса разработки. Система построена на основе следующих ключевых компонентов:
- обнаружение свингов для определения достоверных точек разворота рынка;
- уточнение свингов для выявления истинных ценовых экстремумов в каждом интервале;
- создание линий тренда и проверка их целостности;
- подтверждение пробоя на основе правил закрытия свечей;
- прогнозирование уровней стоп-лосса и тейк-профита на основе геометрии конструкции.
Этот фреймворк обеспечивает структурированный и основанный на правилах подход к обнаружению паттернов «Мегафон» на MQL5, повышая надежность и четкость распознавания паттернов.
Проект доступен в Algo Forge.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/22572
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Вероятностный метод главных компонент на MQL5
Нейроструктурный торговый движок — NSTE (Часть I): Построение мультиаккаунтной системы с учетом ограничений проп-фирм
Свинговые экстремумы и откаты в MQL5 (Часть 2): Автоматизация стратегии с помощью советника
Свинговые экстремумы и откаты в MQL5 (Часть 1): Разработка мультитаймфреймового индикатора
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования