
От новичка до эксперта: Индикатор силы уровней поддержки и сопротивления (SRSI)
Разделы
- Введение
- Обзор обсуждения
- Свидетельство современной рыночной природы.
- Реализация на MQL5 для разработки SRSI.
- Тестирование и результаты
- Заключение
- Приложение (исходный файл SRSI)
Введение
Рынки неизменно соблюдают прошлые уровни цен, которые повлияли на их динамику. Обычный рабочий день трейдера часто начинается с того, что он вручную рисует эти ключевые уровни с помощью хорошо известного линейного инструмента в MetaTrader 5. Однако этот ручной процесс может привести к пропуску важных уровней или неправильной оценке значимости, что подчеркивает необходимость автоматизированного решения.
Кто-то может спросить, зачем нужна автоматизация. Хотя люди преуспевают в решении сложных творческих задач и адаптации к новым ситуациям, нам часто трудно обеспечить последовательность и обрабатывать большие объемы данных. Исследование Марка Анджело Д. Джулиана (Mark Angelo D. Julian), Данило Б. Вилларино (Danilo B. Villarino) и Кристин Т. Соберано (Kristine T. Soberano), опубликованное 7 июля 2024 года в статье «Человеческий мозг против компьютера: кто умнее?» ("The Human Brain Versus Computer: Which is Smarter?"), подчеркивает этот момент. Их исследование показывает, что, хотя люди и преуспевают в понимании контекста, компьютеры значительно превосходят их в скорости обработки, точности данных и выполнении повторяющихся вычислений. Этот контраст стимулирует нашу постоянную разработку алгоритмов для торговли и анализа данных.
Обзор обсуждения
Сегодня для решения вышеупомянутой задачи мы применим методы решения проблем с использованием программирования на MQL5. Это обсуждение рассчитано на трейдеров любого уровня подготовки, от новичков до экспертов, поскольку мы рассмотрим ключевые концепции, которые касаются каждого. Как вы знаете, MetaTrader 5 - это, по сути, обширное хранилище ценовых данных, аналитических инструментов и исторической информации. Например, ряды свечей представляют собой рассчитанные бары, отображающие цены открытия, максимума, минимума и закрытия, а популярные индикаторы, такие как скользящие средние, выводятся из этих значений. Представьте себе, что вам нужно вручную просмотреть 5000 японских свечей — этот процесс не только утомителен, но и подвержен ошибкам. Вот почему автоматизация определения уровней поддержки и сопротивления так полезна.
Хотя на рынке уже доступно несколько инструментов — как бесплатных, так и платных, — сегодня мы исследуем уникальный подход. В ходе этой сессии мы не только обсудим конечный продукт, но и поделимся навыками программирования на языке MQL5, необходимыми для создания собственного пользовательского решения. Ниже приводится краткое описание преимуществ разрабатываемого нами индикатора силы уровней поддержки и сопротивления (SRSI):
- Эффективная обработка данных: Анализирует обширные исторические данные японских свечей для точного определения ключевых уровней.
- Непрерывная автоматизация: Работает автоматически и непрерывно, сокращая количество ручных ошибок.
- Дифференцирование уровней: Определяет как слабые, так и сильные уровни поддержки и сопротивления.
- Четкие визуальные эффекты: Обеспечивает четкое визуальное представление этих критических уровней.
- Подробные уведомления: Предлагает уведомления пользователям через терминал и push-уведомления.
В следующих разделах мы начнем со сбора исторических данных о ценах с использованием графиков MetaTrader 5 и вручную определенных уровней поддержки и сопротивления. Этот первоначальный анализ предоставит доказательства, сравнивающие текущее поведение рынка с прошлыми показателями. Далее мы углубимся в процесс разработки, в ходе которого я поделюсь с вами кодом для нашего пользовательского индикатора и подробно объясню каждую строку, чтобы вы полностью понимали, как реализовать MQL5 и воплотить свои идеи в код.
Наконец, мы рассмотрим процесс тестирования и представим наши результаты. По итогу вы получите как улучшенные навыки программирования, так и работающее решение. Не торопитесь, следуйте инструкциям и наслаждайтесь путешествием в мир программирования.
Свидетельство современного характера рынка
Моя платформа MetaTrader 5 подключена к брокерскому ресурсу Deriv.com, что обеспечивает мне доступ к широкому спектру торговых пар. В зависимости от типа аккаунта я могу торговать волатильными парами, валютными парами, фондовыми парами и многим другим. На представленном изображении продемонстрирован широкий выбор дополнительных пар, доступных для торговли. Для настоящего исследования с целью проведения анализа нами выбраны несколько пар из этой коллекции.
Чтобы просмотреть предлагаемые вашим брокером пары и добавить их в свой список обзор рынка, просто нажмите CTRL + U на клавиатуре или щелкните по красному округлому значку (как показано на рисунке ниже), чтобы открыть окно "Символы» (Symbols). Затем дважды щелкните нужную пару, чтобы автоматически добавить ее в свой список.
DerivSVG Символы MetaTrader 5
Синтетические пары
Я начал свой анализ с синтетической пары в соответствии с индексами волатильности — индекса волатильности 75 (1s) — на недельном таймфрейме. Когда эта пара была представлена примерно в 2020 году, она изначально была дорогой, но вскоре пережила продолжительный обвал, сформировав сильный нисходящий тренд на несколько недель. Трейдеры, в этот период игравшие на понижение пары, вероятно, получили значительную прибыль. Однако основное внимание я уделяю структуре рынка, особенно за последние три года.
Устойчивый нисходящий тренд, вероятно, заставил трейдеров принять настрой следования за трендом, ожидая дальнейшего снижения. Однако, как показано на рисунке ниже, динамика рынка изменилась. На более высоком таймфрейме теперь наблюдается изменчивая диапазонная структура с аналогичными характеристиками, наблюдаемыми на более низких таймфреймах. Подобные условия затрудняют эффективную торговлю свинг-трейдерами.
В этих обстоятельствах ценовое движение, основанное на уровнях поддержки и сопротивления, становится решающим для определения ключевых торговых возможностей. Изображение ниже иллюстрирует такое поведение рынка, подчеркивая важность структурированного подхода к техническому анализу.
Индекс волатильности 75 (1s)
Фондовая пара
Я проанализировал недельный график US Tech, и очевидно, что рынок демонстрирует тенденцию к росту с периодическими коррекциями по ходу процесса. Эти коррекции часто приводят к фазам консолидации, когда движение цен замедляется, а затем тренд возобновляется. На восходящем рынке коррекции обычно формируют сильные зоны поддержки, усиливая бычий импульс.
На этом более высоком таймфрейме сложно определить точные паттерны, влияющие на движение цены на более низких таймфреймах. Однако, если копнуть глубже, мы увидим, что концепция поддержки и сопротивления остается применимой на разных таймфреймах, что позволяет нам более подробно наблюдать различные рыночные модели.
Индекс US Tech 100 Weekly
Валютная пара
Недельный график EUR/USD показывает небольшую фазу импульса, за которой последовал продолжительный период колебаний. Такое поведение очевидно на старшем таймфрейме и распространяется также на младшие таймфреймы. Ключевым моментом здесь является привязанное к диапазону движение цены, подчеркивающее, как рынок тратит значительную часть времени на консолидацию, а не на движение в тренде. Изображение ниже служит доказательством такого длительного поведения рынка в определенном диапазоне.
Еженедельный анализ EURUSD
В заключение следует отметить, что из вышеприведенного примера становится ясно, что, хотя рыночные цены демонстрируют тенденции к росту или падению, они в значительной степени зависят от предыдущих уровней цен для тестирования и проверки. Во время фаз консолидации эти горизонтальные уровни, в зависимости от выбранного таймфрейма, становятся ключевыми областями, где цена имеет тенденцию реагировать.
Однако не каждый уровень достаточно силен, чтобы спровоцировать значительное движение цены. Кроме того, даже хорошо устоявшиеся уровни поддержки или сопротивления не гарантируют реакцию цены, но они обеспечивают более высокую вероятность влияния на поведение рынка, если докажут свою силу.
В следующем разделе, прежде чем углубиться в разработку алгоритма, кратко рассмотрим основы поддержки и сопротивления.
Реализация на MQL5 для разработки SRSI
Определение уровней поддержки и сопротивления
Поддержка обычно определяется как зона спроса, где сходятся несколько уровней цен, что указывает на то, что покупатели склонны вмешаться и поднять цену. Эта область представляет собой «пол» рынка, где накопление покупательского интереса, как правило, предотвращает дальнейшее падение.
- На практике поддержка обычно представляет собой не отдельную ценовую точку, а зону, где предыдущие минимумы или множественные точки соприкосновения сформировали доверие покупателей.
Напротив, Сопротивление — это зона предложения, где сходится множество уровней цен, что предполагает вероятность вмешательства продавцов и снижения цены. Эта область действует как «потолок» для рынка, где давление продавцов превышает давление покупателей, что часто препятствует дальнейшему росту цен. Как и поддержка, сопротивление обычно рассматривается как диапазон, а не как точный уровень из-за наличия нескольких максимумов или точек взаимодействия, которые усиливают интерес к продажам.
Понимая это, работать с уровнями поддержки и сопротивления становится намного проще. В видео ниже я покажу вам, как я обычно рисую эти линии.
Разработка и реализация алгоритма
Нам нужна программа, которая будет копировать то, как я вручную определяю и отмечаю зоны поддержки и сопротивления. Посмотрев видео, резюмировал основные шаги:
- Определяем экстремальные поворотные моменты: Это значимые максимумы (сопротивление) или минимумы (поддержка), где цена меняет направление.
- Находим другие точки тестирования: Ищем дополнительные ценовые уровни, где цена равна или находится в пределах 5 пипсов от крайней точки разворота, подтверждая ее значимость.
- Формируем зоны отскока: Создаём прямоугольные зоны, охватывающие крайние поворотные точки и их контрольные точки, при этом зона расширяется вокруг этих точек касания.
- Настроим размеры зоны:
- Высота: Вертикальный размер прямоугольника зоны (в пипсах) должен быть регулируемым.
- Ширина: Горизонтальный размер зоны (в барах японских свечей справа) должен быть регулируемым.
Как правило, мы настраиваем нашу программу на сканирование определенного количества свечей, определяя условия, которые соответствуют нашим критериям, и рисуя соответствующие фигуры, линии и метки. Мы также предоставим возможности ввода для управления различными функциями программы. Для оповещений мы реализуем push-уведомления и оповещения на терминале, отправляя их периодически в течение настраиваемого 4-часового интервала. В отличие от других индикаторов, уровни поддержки и сопротивления не требуют постоянного мониторинга, поэтому такой подход обеспечивает своевременные уведомления без лишних оповещений. Ниже я пошагово объясню детали, приведя фрагменты кода.
При открытии MetaEditor и выборе создания нового пользовательского индикатора, вам предоставляется базовый шаблон для работы. Этот шаблон подобен чистому холсту, помогающему разработчикам начать работу, и именно на нем мы будем создавать наш индикатор SRSI. Вот как он выглядит:
//+------------------------------------------------------------------+ //| _SRSI.mq5 | //| Copyright 2025, Metaquotes Ltd | //| https://www.mql5.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Metaquotes Ltd" #property link "https://www.mql5.com/" #property version "1.00" #property indicator_chart_window //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int 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 int &spread[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Мы будем использовать это как основополагающее руководство, гарантируя надлежащую реализацию всех ключевых функций. На последующих этапах мы завершим работу над шаблоном, интегрируем новые функции и предоставим подробные объяснения их функциональности. Для полного понимания дочитайте текст статьи до конца.
Шаг 1: Пользовательская настройка свойств индикатора
Для начала настроим свойства индикатора, чтобы персонализировать его и соответствовать требованиям MetaTrader 5. Мы обновляем информацию об авторских правах и ссылках, чтобы она отражала нашу собственную информацию. Добавляем настройку для более строгой проверки ошибок, чтобы таким образом выявлять ошибки во время разработки. Индикатор настроен на отображение в главном окне графика. Поскольку для MetaTrader 5 требуется по крайней мере один буфер, определяем один скрытый «фиктивный» буфер, поскольку наш индикатор будет использовать пользовательские объекты (линии и прямоугольники), а не графически представленные данные буфера.
#property copyright "Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict // Enforces stricter error checking #property indicator_chart_window #property indicator_buffers 1 // MT5 requires at least one buffer #property indicator_plots 1 // Ties to the buffer (even if unused for plotting)
Шаг 2: Добавление пользовательских входных данных
Затем, чтобы сделать индикатор легко адаптируемым, добавляем настраиваемые пользователем входные данные. Включаем опцию настройки количества прошедших баров, которые анализирует индикатор, ценовой диапазон (например, по умолчанию 7 пипсов) для определения уровней тестирования, минимальное количество тестов, необходимое для того, чтобы уровень считался сильным, и переключатель для отображения или скрытия прямоугольных зон вокруг сильных уровней. Эти входные данные позволяют пользователям настраивать поведение индикатора без изменения кода.
input int InpLookBack = 1000; // Number of bars to analyze input double InpTestProximity = 0.0007; // Price range for tests (e.g., 7 pips) input int InpMinTests = 3; // Minimum tests for strong levels input bool InpShowRectangles = true; // Show zones as rectangles
Шаг 3: Создание фиктивного (думми) буфера
MetaTrader 5 требует, чтобы каждый индикатор имел хотя бы один буфер, даже если он не отображается. Мы создаем глобальный массив, который будет действовать как фиктивный буфер. Во время инициализации мы привязываем его к слоту буфера и скрываем из диаграммы. Это соответствует требованию MetaTrader 5 и позволяет нам сосредоточиться на построении пользовательских уровней поддержки и сопротивления.
double DummyBuffer[];
Его использование:
int OnInit() { SetIndexBuffer(0, DummyBuffer, INDICATOR_DATA); // Bind buffer to index 0 PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_NONE); // Hide it from the chart return(INIT_SUCCEEDED); }
Шаг 4: Определение структур данных
Чтобы упорядочить данные, мы используем перечисления и структуры. Мы определяем перечисление для классификации уровней (например, сильная поддержка, слабое сопротивление) для наглядности. Структура для уровней цен хранит цену каждого уровня, количество тестов, тип и время идентификации. Другая структура определяет зоны вокруг сильных уровней, удерживая их верхнюю и нижнюю цены, а также временной диапазон. Также настраиваем глобальные массивы для хранения сильных и слабых уровней и зон, а также переменную для отслеживания времени последнего оповещения.
enum ENUM_LEVEL_TYPE { LEVEL_STRONG_SUPPORT, // Strong support level LEVEL_STRONG_RESISTANCE, // Strong resistance level LEVEL_WEAK_SUPPORT, // Weak support level LEVEL_WEAK_RESISTANCE // Weak resistance level }; struct PriceLevel { double price; // Price value of the level int test_count; // Number of times price tested it ENUM_LEVEL_TYPE type; // Strong or weak, support or resistance datetime time; // Time the level was identified }; struct Zone { double top; // Top price of the zone double bottom; // Bottom price of the zone datetime start_time; // When the zone starts datetime end_time; // When the zone ends (current time) }; PriceLevel StrongLevels[]; // Array for strong levels PriceLevel WeakLevels[]; // Array for weak levels Zone Zones[]; // Array for strong level zones datetime LastAlertTime = 0; // Tracks the last alert time
Шаг 5: Обнаружение точек колебания
Уровни поддержки и сопротивления часто формируются на максимумах и минимумах колебаний. Мы создаем функцию для определения максимумов колебаний, проверяя, превышает ли максимум бара максимумы 5 баров до и после него, отмечаем пик. Аналогичным образом функция для минимумов колебания проверяет, находится ли минимум бара ниже минимумов окружающих 5 баров, указывая на впадину. Использование 5-барного окна с каждой стороны обеспечивает значимость этих точек.
bool IsSwingHigh(int index, const double &high[]) { int window = 5; // Check 5 bars on each side for (int i = 1; i <= window; i++) { if (index - i < 0 || index + i >= ArraySize(high)) return false; // Out of bounds if (high[index] <= high[index - i] || high[index] <= high[index + i]) return false; // Not a peak } return true; } bool IsSwingLow(int index, const double &low[]) { int window = 5; // Check 5 bars on each side for (int i = 1; i <= window; i++) { if (index - i < 0 || index + i >= ArraySize(low)) return false; // Out of bounds if (low[index] >= low[index - i] || low[index] >= low[index + i]) return false; // Not a trough } return true;
Шаг 6: Подсчет ценовых тестов
Сила уровня зависит от того, как часто цена его тестирует. Мы добавляем функцию для подсчета этих тестов путем проверки баров после точки колебания. Она проверяет, попадает ли максимум или минимум каждого бара в заданный ценовой диапазон уровня, увеличивая счетчик для каждого теста. Общее количество тестов определяет, является ли уровень сильным или слабым на основе минимального порогового значения пользователя.
int CountLevelTests(double price, int start_index, const double &high[], const double &low[]) { int tests = 0; for (int i = start_index + 1; i < ArraySize(high); i++) { if (MathAbs(high[i] - price) <= InpTestProximity || MathAbs(low[i] - price) <= InpTestProximity) { tests++; } } return tests;
Шаг 7: Уровни обработки
Мы обрабатываем каждую точку колебания в уровень, используя специальную функцию. Она регистрирует цену, количество тестов, время и тип (сильный/слабый, поддержка/сопротивление) в зависимости от того, является ли это колебанием максимума или минимума и соответствует ли оно пороговому значению теста. Для сильных уровней она также определяет зону с ценовым диапазоном вокруг уровня. Затем уровень сохраняется в соответствующем массиве (сильный или слабый) для дальнейшего использования.
void ProcessLevel(int index, double price, bool is_high, const double &high[], const double &low[], const datetime &time[]) { PriceLevel level; level.price = price; level.test_count = CountLevelTests(price, index, high, low); level.time = time[index]; if (is_high) { level.type = (level.test_count >= InpMinTests) ? LEVEL_STRONG_RESISTANCE : LEVEL_WEAK_RESISTANCE; } else { level.type = (level.test_count >= InpMinTests) ? LEVEL_STRONG_SUPPORT : LEVEL_WEAK_SUPPORT; } if (level.test_count >= InpMinTests) { ArrayResize(StrongLevels, ArraySize(StrongLevels) + 1); StrongLevels[ArraySize(StrongLevels) - 1] = level; Zone zone; zone.start_time = time[index]; zone.end_time = TimeCurrent(); zone.top = price + InpTestProximity; zone.bottom = price - InpTestProximity; ArrayResize(Zones, ArraySize(Zones) + 1); Zones[ArraySize(Zones) - 1] = zone; } else { ArrayResize(WeakLevels, ArraySize(WeakLevels) + 1); WeakLevels[ArraySize(WeakLevels) - 1] = level; }
Шаг 8: Нанесение на диаграмму
Для отображения уровней мы используем две функции отрисовки. Одна рисует сильные уровни серым прямоугольником (если включено) для зоны и сплошной линией — синей для поддержки, красной для сопротивления — плюс метка («SS» или «SR»). Другая отображает слабые уровни пунктирной линией — светло-голубой для поддержки, розовой для сопротивления — и меткой («WS» или «WR»). Каждому объекту присваивается уникальное имя в зависимости от его времени, что обеспечивает надлежащее управление на диаграмме.
void RenderZone(const Zone &zone, const PriceLevel &level) { string name = "Zone_" + TimeToString(zone.start_time); if (InpShowRectangles) { ObjectCreate(0, name, OBJ_RECTANGLE, 0, zone.start_time, zone.top, zone.end_time, zone.bottom); ObjectSetInteger(0, name, OBJPROP_COLOR, clrLightGray); ObjectSetInteger(0, name, OBJPROP_FILL, true); } string line_name = "Line_" + TimeToString(level.time); ObjectCreate(0, line_name, OBJ_HLINE, 0, 0, level.price); ObjectSetInteger(0, line_name, OBJPROP_COLOR, (level.type == LEVEL_STRONG_SUPPORT) ? clrBlue : clrRed); ObjectSetString(0, line_name, OBJPROP_TEXT, (level.type == LEVEL_STRONG_SUPPORT) ? "SS" : "SR"); } void RenderWeakLine(const PriceLevel &level) { string name = "WeakLine_" + TimeToString(level.time); ObjectCreate(0, name, OBJ_HLINE, 0, 0, level.price); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(0, name, OBJPROP_COLOR, (level.type == LEVEL_WEAK_SUPPORT) ? clrLightBlue : clrPink); ObjectSetString(0, name, OBJPROP_TEXT, (level.type == LEVEL_WEAK_SUPPORT) ? "WS" : "WR");
Шаг 9: Отправка оповещений
Включаем функцию отправки оповещений о высоких уровнях, не отправляя пользователю спам. Она проверяет, прошел ли час с момента последнего оповещения и существуют ли высокие уровни. Если это так, она создает сообщение с типом последнего сильного уровня, ценой и текущей ценой, а затем отображает его. Во избежание частых уведомлений время оповещения обновляется.
void SendPeriodicAlert(double current_price) { if (TimeCurrent() - LastAlertTime < 3600) return; // Wait 1 hour between alerts if (ArraySize(StrongLevels) == 0) return; // No strong levels, no alert PriceLevel latest = StrongLevels[ArraySize(StrongLevels) - 1]; string message = "SRZones Alert: Strong " + ((latest.type == LEVEL_STRONG_SUPPORT) ? "Support" : "Resistance") + " at " + DoubleToString(latest.price, 5) + ", Current Price: " + DoubleToString(current_price, 5); Alert(message); LastAlertTime = TimeCurrent(); }
Шаг 10: Очистка старых рисунков
Для поддержания чистоты диаграммы мы добавляем функцию удаления старых объектов. Она удаляет все ранее нарисованные зоны, линии сильных уровней и линии слабых уровней с помощью определенных префиксов имен. Это происходит перед каждым полным пересчетом, чтобы обновить отображение текущих уровней.
void ClearDisplayObjects() { ObjectsDeleteAll(0, "Zone_"); // Delete all zones ObjectsDeleteAll(0, "Line_"); // Delete strong lines ObjectsDeleteAll(0, "WeakLine_"); // Delete weak lines }
Шаг 11: Запуск логики в OnCalculate
Наконец, мы собираем все воедино в основной расчетной функции. При запуске или формировании нового бара она удаляет старые объекты и сбрасывает массивы. Она определяет начальную точку на основе заданного пользователем периода ретроспективного анализа, обеспечивая достаточно данных для обнаружения колебаний. Она циклически перебирает бары, определяет максимумы и минимумы колебаний, преобразует их в уровни и сохраняет их. Затем отображает все сильные и слабые уровни и проверяет наличие оповещений. Функция возвращает количество обработанных баров в MetaTrader 5.
int OnCalculate(const int rates_total, const int 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 int &spread[]) { if (prev_calculated == 0 || rates_total > prev_calculated) { // Full recalc on start or new bar ClearDisplayObjects(); ArrayResize(StrongLevels, 0); ArrayResize(WeakLevels, 0); ArrayResize(Zones, 0); int start = MathMax(5, rates_total - InpLookBack); // Start within lookback period for (int i = start; i < rates_total - 5; i++) { // Leave room for swing checks if (IsSwingHigh(i, high)) ProcessLevel(i, high[i], true, high, low, time); if (IsSwingLow(i, low)) ProcessLevel(i, low[i], false, high, low, time); } for (int i = 0; i < ArraySize(StrongLevels); i++) { RenderZone(Zones[i], StrongLevels[i]); } for (int i = 0; i < ArraySize(WeakLevels); i++) { RenderWeakLine(WeakLevels[i]); } SendPeriodicAlert(close[rates_total - 1]); } return(rates_total); // Tell MT5 how many bars were processed }
Собрав все части и решив различные проблемы, мы успешно собрали наш конечный продукт, который прилагается в конце данного обсуждения. В следующем разделе мы поделимся нашим опытом тестирования и в заключении статьи укажем выводы.
Тестирование и результаты
Первым шагом было запустить индикатор и добавить его на диаграмму с настройками по умолчанию, используя EURUSD в качестве референса. Для корректного отображения индикатора на других валютных парах могут потребоваться первоначальные настройки, в частности, значение пипса. Например, при тестировании индекса волатильности 75 (1s) никаких зон не появлялось, пока я не настроил значение пипса на 70.
Изначально, как показано на рисунке ниже, ширина прямоугольника была относительно небольшой и требовала пользовательской настройки для увеличения его размера, который мы и скорректировали на следующем рисунке. Все настройки отреагировали хорошо, на диаграмме произошли заметные изменения. Кроме того, все метки четко отображаются, и при необходимости их можно скрыть.
Добавление индикатора силы уровней поддержки и сопротивления (SRSI) на диаграмму.
Пользовательская настройка параметров SRSI
При первоначальном запуске индикатор отправляет оповещение, отображающее преобладающий уровень поддержки или сопротивления вместе с текущей ценой. Это помогает пользователям прогнозировать потенциальные зоны спроса и предложения. Ниже представлен экспертный лог, содержащий подробную информацию об оповещении.
2025.03.10 07:44:42.548 _SRSI (EURUSD,M15) Alert: Key Level: SR at 1.08715 | Current Price: 1.09021 2025.03.10 07:54:04.239 _SRSI (EURUSD,M15) Alert: Key Level: SR at 1.08715 | Current Price: 1.09033 2025.03.10 07:55:04.965 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09044 2025.03.10 09:25:13.506 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09210 2025.03.10 11:26:46.761 _SRSI (EURUSD,M5) Alert: Key Level: SR at 1.09013 | Current Price: 1.09192
Кроме того, в настройках есть опция push-уведомлений, а уведомления терминала включены по умолчанию. При срабатывании оповещения на экране терминала автоматически появится окно оповещения.
Окно оповещений терминала: работа индикатора SRSI
Заключение
Цель нашего обсуждения успешно достигнута благодаря разработке безошибочного индикатора. В результате наших тестов цели проекта были достигнуты, а ожидаемая функциональность реализована. Теперь я могу без труда нарисовать линии поддержки и сопротивления всего за несколько щелчков мыши, а алгоритм автоматически проверит их на надежность. Как вы могли заметить в видео, ручной процесс может быть довольно медленным, но с помощью алгоритма эти уровни рассчитываются мгновенно с каждым тиком. В ходе этого процесса мы собрали ценную информацию о MQL5 для разработки индикатора, и хотя эффективность индикатора можно оценить с течением времени, существуют различные способы, с помощью которых опытные разработчики могут усовершенствовать и расширить его.
При этом подходе мы ввели структуры как средство написания более профессионального и организованного кода. Однако всегда есть возможности для совершенствования, и я думаю, у вас есть собственные идеи и предложения по улучшению этого инструмента. Вы можете изменять его и экспериментировать с ним, и не стесняйтесь делиться своими мыслями в комментариях ниже.
Надеюсь, эта дискуссия оказалась для вас содержательной. До новых встреч — счастливого программирования и успешной торговли, коллеги-разработчики!
Приложение (исходный файл SRSI)
Файл | Описание |
---|---|
_SRSI.mq5 | Индикатор силы уровней поддержки и сопротивления, который динамически рисует регулируемые прямоугольные зоны, четко обозначая сильную поддержку (SS) и сильное сопротивление (SR). Кроме того, он рисует пунктирные линии, указывающие на более слабые уровни поддержки (WS) и сопротивления (WR) для лучшей визуализации. |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/17450
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.





- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Мне очень понравилась ваша статья, я попробовал ее на FX парах, которые, кажется, хорошо работают... Как насчет индексов, таких как US30? Какие настройки вы рекомендуете? Я пробовал установить текстовую близость на 0.035 и результаты кажутся забавными.
Спасибо!
Спасибо!
Здравствуйте, друг
Я слежу за вашими статьями, и они очень информативны. Спасибо, что делитесь и распространяете знания.
Я попробовал 21-периодный ATR-мультипликатор, как показано ниже:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1)); // (n*getATR(index) заменен на ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1)); // (n*getATR(index) заменен на ...InpMinWeakDistance;
Это помогло мне получить SRZones для пар EURUSD и XAUUSD с довольно большой разницей в значениях 1.08000 - 3000.00.
Возможно, это будет полезно читателям вашей статьи при дальнейшей небольшой доработке. Тогда настройки индикатора можно будет сделать универсальными для большинства инструментов.
Здравствуй, друг
Я слежу за вашими статьями, и они очень информативны. Спасибо, что делитесь и распространяете знания.
Я попробовал 21-периодный ATR, как показано ниже:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1)); // (n*getATR(index) заменен на ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1))); // (n*getATR(index) заменен на ...InpMinWeakDistance;
Это помогло мне получить SRZones для пар EURUSD и XAUUSD с довольно большой разницей в значениях 1.08000 - 3000.00.
Возможно, это будет полезно читателям вашей статьи при дальнейшей небольшой доработке. Тогда настройки индикатора можно будет сделать универсальными для большинства инструментов.
Привет, мой хороший друг @Anil Varma.
Спасибо, что поделились этим уникальным подходом! Я обязательно попробую.
Здравствуй, друг
Я слежу за вашими статьями, и они очень информативны. Спасибо, что делитесь и распространяете знания.
Я попробовал 21-периодный ATR, как показано ниже:
gTestProximity = (MathMax((75/_Digits),0.10*getATR(rates_total - 1)); // (n*getATR(index) заменен на ...InpTextProximity;
gMinDistance = (MathMax((150/_Digits),0.20*getATR(rates_total - 1))); // (n*getATR(index) заменен на ...InpMinWeakDistance;
Это помогло мне получить SRZones для пар EURUSD и XAUUSD с довольно большой разницей в значениях 1.08000 - 3000.00.
Возможно, это будет полезно читателям вашей статьи при дальнейшей небольшой доработке. Тогда настройки индикатора можно будет сделать универсальными для большинства инструментов.
Не могли бы вы поделиться своей версией индикатора ATR?
Здравствуйте
Не могли бы вы поделиться своей версией индикатора ATR?
Здравствуйте @Evgeny Fedorenko
Во-первых, извините, что отвечаю слишком поздно, на самом деле я отвлекся на курс Quant Financial Modeling.
Во-вторых, я не создавал никакого индикатора для себя, просто попробовал код индикатора Клеменса Бенджамина с твиком, предложенным в моем посте.
Надеюсь, это вам поможет.