Разработка инструментария для анализа Price Action (Часть 55): Индикатор CPI с мини-свечами для отображения внутрисвечного давления
Содержание
- Введение
- Концепция и теоретическая часть
- Устройство индикатора
- Алерты и логика событий
- Реализация на MQL5
- Тестирование
- Заключение
Введение
Большинство трейдеров учатся интерпретировать свечи по простому цветовому коду: зеленый означает покупки, а красный – продажи. На практике, однако, цена редко ведет себя так однозначно. Каждая свеча отражает непрерывное противоборство покупателей и продавцов, а цена закрытия показывает лишь то, где эта борьба завершилась, но не то, насколько сильно одна из сторон доминировала в течение бара. В результате две свечи могут выглядеть одинаково по цвету и размеру, но нести совершенно разную информацию: одна может уверенно закрыться у максимума, сигнализируя об устойчивом давлении покупателей, а другая – закрыться слабо, несмотря на зеленый цвет.
Хорошая аналогия – футбольный матч. Итоговый счет (например, 1–0) показывает, кто выиграл, но не передает, как именно проходил матч. Команда может проиграть в один мяч, при этом контролировать владение, проводить большую часть матча на половине соперника и создавать более опасные моменты. Со свечами все устроено похожим образом. Цвет свечи показывает, закрылась ли цена выше или ниже открытия, но часто скрывает, какая сторона контролировала большую часть внутрисвечного движения и насколько сильным было это доминирование.

В этой статье представлены мини-свечи CPI для MetaTrader 5 – компактное графическое наложение на основе Closing Location Value (CLV), которое раскрывает эту скрытую информацию. Индикатор измеряет положение закрытия в диапазоне каждого бара и визуализирует результат в виде мини-свечей, привязанных к его середине. И направление, и размер каждой мини-свечи отражают внутрисвечное давление, позволяя трейдерам видеть, кто доминировал (покупатели или продавцы) и насколько сильным было это преимущество. Свечи распределяются по нейтральной, умеренной и сильной зонам давления; при необходимости сильные бары выделяются стрелками, а алерты на основе событий сообщают о входе в сильную зону или об изменении направления CPI.
Добавляя еще один уровень информации, мини-свечи CPI помогают выявлять ситуации, в которых одного цвета свечи недостаточно, – например, когда свеча закрывается слегка ниже открытия, но оказывается у верхней границы диапазона ("красная, но бычья"), – а также различать свечи одного цвета, заметно отличающиеся по силе давления. Индикатор предназначен исключительно для анализа и не совершает сделки. Он только визуализирует поведение цены и не дает торговых рекомендаций.
В следующих разделах рассматриваются анатомия свечи, лежащая в основе CPI, формула на основе CLV, реализация визуализации и логики алертов на MQL5, а также практические примеры с воспроизводимыми процедурами тестирования, чтобы каждый мог оценить инструмент и адаптировать его под свой анализ Price Action.
Концепция и теоретическая часть
Прежде чем переходить к индексу давления свечи (CPI) и его расчету, полезно кратко вспомнить базовую структуру свечи. CPI напрямую опирается на анатомию свечи: он использует полный диапазон и положение закрытия, чтобы оценить, принял ли рынок цены ближе к максимуму, ближе к минимуму или где-то между ними.
Свеча в сжатом виде отражает всю торговую активность за фиксированный интервал времени. Цвет свечи показывает, закрылась ли цена выше или ниже открытия, но ее структура (диапазон, тело и тени) дает дополнительную информацию о том, куда доходила цена, где она была отвергнута рынком и где в итоге закрепилась. CPI фокусируется именно на этой внутренней структуре, а не только на цвете свечи.
Кратко об анатомии свечи
Свеча определяется четырьмя ключевыми ценовыми точками:
- Open – цена открытия свечи;
- High – цена максимума за интервал;
- Low – цена минимума за интервал;
- Close – цена закрытия свечи;

Из этих значений можно выделить три структурных компонента:
Диапазон
Диапазон – это полное расстояние между максимумом и минимумом:
- Range = High – Low
Он задает полный ценовой интервал, внутри которого покупатели и продавцы взаимодействовали в течение свечи.
Тело
Тело – это расстояние между ценами открытия и закрытия. Цвет свечи определяется этим соотношением:
- Close выше Open – бычья свеча (зеленая);
- Close ниже Open – медвежья свеча (красная).
Тело отражает итог свечи, но не показывает, где именно произошло закрытие внутри полного диапазона.
Тени
Верхняя и нижняя тени показывают, где цена была отвергнута:
- Верхняя тень отмечает уровни, которых цена достигала, но не удержала к закрытию.
- Нижняя тень отмечает уровни, которых цена достигала, но не удержала к закрытию.
Тени часто содержат важную информацию об отвержении и поглощении – детали, которых один лишь цвет свечи не показывает.
От структуры свечи к CPI
Индекс давления свечи (CPI) – это нормированное значение в диапазоне [-1, +1], которое показывает, где свеча закрывается внутри диапазона от максимума до минимума: близость к максимуму указывает на давление покупателей, а близость к минимуму – на давление продавцов. Хотя цвет свечи показывает, закрылась ли цена выше или ниже открытия, он не раскрывает, произошло ли закрытие у максимума, у минимума или где-то между ними. Индекс давления свечи (CPI) устраняет это ограничение, измеряя положение закрытия внутри диапазона свечи.
Положение закрытия в диапазоне
Схематично:
- Закрытие у максимума указывает на устойчивое давление покупателей.
- Закрытие у минимума указывает на устойчивое давление продавцов.
- Закрытие ближе к середине указывает на рыночное равновесие или поглощение.
Чтобы количественно выразить эту идею, CPI использует формулу Closing Location Value (CLV):

Диапазон значений CPI
Эта формула нормирует результат в пределах фиксированной шкалы:
- +1 – закрытие на максимуме (максимальное давление покупателей);
- 0 – закрытие в середине диапазона (сбалансированное давление);
- -1 – закрытие на минимуме (максимальное давление продавцов).
Нормирование обеспечивает сопоставимость значений CPI на разных инструментах и таймфреймах.
- Особый случай: High = Low
Когда максимум равен минимуму, у свечи нет диапазона. В таких случаях CPI не определен и считается нейтральным (0). Это предотвращает деление на ноль и корректно отражает отсутствие направленного давления.
Практическая интерпретация (сценарии)
CPI становится особенно информативным при применении к реальному поведению свечей. Следующие сценарии показывают, какую дополнительную информацию дает CPI по сравнению с одним лишь цветом свечи.
Красная свеча с сильным бычьим CPI ("красная, но бычья")
Свеча может закрыться немного ниже открытия (красная), но при этом завершиться у верхней границы своего диапазона. Это означает, что хотя по итоговому результату свечу выиграли продавцы, большую часть внутрисвечного движения контролировали покупатели. CPI отражает это, показывая положительное и нередко высокое значение, несмотря на красную свечу.
Зеленая свеча с медвежьим CPI ("зеленая, но слабая")
Свеча может закрыться выше открытия (зеленая), но при этом завершиться у нижней части своего диапазона. Это говорит о том, что хотя формально закрытие осталось за покупателями, продавцы оказывали давление на протяжении всего бара. CPI отражает эту слабость низким или даже отрицательным значением, несмотря на зеленую свечу.
Пример нейтрального CPI
Когда цена закрывается близко к середине диапазона, CPI приближается к нулю. Это отражает сбалансированное участие, при котором ни покупатели, ни продавцы не оказывали доминирующего давления независимо от цвета свечи.
Почему это важно
- Традиционный свечной анализ делает акцент на результате.
- CPI делает акцент на давлении и доминировании.
Объединяя анатомию свечи с положением закрытия, CPI позволяет оценить:
- направление – кто контролировал движение в пределах бара;
- сила – насколько велико было это доминирование.
Устройство индикатора
Индикатор дает компактную визуализацию CPI на основном графике, не изменяя исходные свечи. CPI отображается на каждом баре в виде небольшого маркера в форме свечи, с опциональными стрелками сильных зон и цветовой индикацией для быстрого восприятия.
Правила визуализации
- Только закрытые свечи – CPI рассчитывается только для баров, где i ≥ 1. Бар 0 (текущий формирующийся бар) исключается, чтобы избежать нестабильных значений и повторных условий срабатывания алертов.
- Привязка к середине – каждый маркер центрируется в середине бара.

Такое расположение гарантирует, что маркер остается визуально независимым от максимума и минимума бара.
- Высота пропорциональна |CPI| (с ограничением): Высота маркера увеличивается вместе с абсолютным значением CPI и ограничивается диапазоном от MinMarkerPoints до MaxMarkerPoints пунктов, что обеспечивает читаемость на разных инструментах и при разных режимах волатильности.
Зоны и цвета
Два пороговых значения определяют пять зон CPI:
- StrongThreshold (например, 0,60);
- MildThreshold (например, 0,20).
Выделяются следующие зоны:
- сильная покупка – CPI ≥ +StrongThreshold;
- умеренная покупка – +MildThreshold ≤ CPI < +StrongThreshold;
- нейтрально – -MildThreshold < CPI < +MildThreshold;
- умеренная продажа – -StrongThreshold < CPI ≤ -MildThreshold;
- сильная продажа – CPI ≤ -StrongThreshold.
Каждой зоне присваивается свой цвет для быстрого и интуитивного распознавания.
Стрелки сильных зон (опционально)
При включении стрелки рисуются только для свечей, попадающих в сильные зоны:
Стрелка сильной покупки рисуется ниже минимума.
- Low - OffsetPoints × Point
Стрелка сильной продажи рисуется выше максимума.
- High + OffsetPoints × Point
Значение OffsetPoints гарантирует, что стрелка не будет перекрывать ценовую свечу или мини-маркер.
На рисунке ниже показана визуализация мини-свечи CPI.

Значения CPI отображаются на каждом закрытом баре в виде компактных мини-свечей, привязанных к его середине. Направление маркера указывает на давление покупателей или продавцов, его высота отражает силу давления, а стрелки выделяют сильные зоны CPI. Цвет свечи и давление CPI могут не совпадать, раскрывая внутрисвечную динамику, которую не видно по одной лишь цене.
Алерты и логика событий
Система алертов основана на простом принципе: уведомлять об изменении, а не о сохранении состояния. Значения CPI могут оставаться в одной и той же зоне давления в течение нескольких баров подряд, и повторная отправка алертов на каждой свече лишь создает шум, не принося практической пользы. По этой причине алерты генерируются только при переходе CPI между заданными состояниями и только на закрытых барах. Каждому закрытому бару присваивается дискретное состояние CPI на основе заданных порогов: сильная покупка, умеренная покупка, нейтральное состояние, умеренная продажа и сильная продажа. Вместо реакции на исходные значения CPI логика алертов сравнивает текущее состояние с предыдущим и срабатывает только при значимом переходе.
Основное событие для алертов – вход в зону сильного давления, то есть в зону сильной покупки или сильной продажи. Это происходит, когда CPI переходит из нейтрального или умеренного состояния в сильную покупку или сильную продажу. Поскольку это отражает явное изменение давления, оцениваемого по положению цены закрытия, такой алерт наиболее избирателен и обычно наиболее информативен. Также доступны опциональные алерты для выходов из сильной зоны и для смены знака CPI. Выход из сильной зоны указывает на ослабление направленного давления, а смена знака фиксирует изменение направленного смещения, которое может происходить и в умеренных, и в нейтральных зонах. Поскольку смена знака может происходить чаще, такие сигналы отделены от алертов сильной зоны и при необходимости могут быть отключены.
Чтобы избежать дублирования, все события проверяются один раз на каждом новом закрытом баре, и на один бар приходится не более одного алерта. Одна и та же логика событий используется во всех каналах уведомлений, поэтому поведение системы не зависит от способа доставки.
Реализация на MQL5
В этом разделе описано, как концепция мини-свечей CPI реализована в MetaTrader 5, с акцентом на отрисовку, логику расчетов и обработку алертов. Особое внимание уделяется детерминированному поведению, логике без перерисовки и визуальной наглядности.
Подход к отрисовке (графические построения и буферы)
Индикатор отрисовывается прямо в основном окне графика и использует три графических построения, каждое со своей визуальной функцией. CPI отображается с помощью компактных мини-свечей, которые накладываются поверх цены, не изменяя исходные свечи. Такой подход сохраняет привычную картину ценового движения, дополняя ее информацией о внутрисвечном давлении.
За основную визуализацию отвечает первое графическое построение, которое использует режим отрисовки DRAW_COLOR_CANDLES для вывода мини-свечей CPI. Поскольку этот режим требует данных в формате свечей, графическое построение опирается на пять буферов: синтетические значения Open, High, Low и Close, задающие геометрию каждого маркера CPI, и буфер индекса цвета, который выбирает один из пяти цветов заранее заданной палитры. Эти синтетические значения OHLC не берутся из фактических рыночных данных; они строятся на основе расчета CPI: маркер центрируется по середине свечи, а его высота масштабируется в зависимости от силы давления. Буфер цветового индекса сопоставляет каждый маркер с одной из зон – сильная покупка, умеренная покупка, нейтральное состояние, умеренная продажа или сильная продажа, – что позволяет визуально передавать и направление, и силу давления.
Для отображения сильных событий CPI без загромождения слоя мини-свечей используются еще два графических построения. Второе графическое построение DRAW_ARROW предназначено для баров с сильной покупкой по CPI, а третье – отдельное DRAW_ARROW для баров с сильной продажей по CPI. Разделение стрелок покупки и продажи по разным графическим построениям позволяет настраивать их независимо и гарантирует, что на каждом баре будет появляться только нужная стрелка. Благодаря разделению непрерывной визуализации давления (мини-свечи) и дискретных маркеров событий (стрелки) логика отрисовки остается ясной, детерминированной и визуально сбалансированной.
#property indicator_chart_window #property indicator_plots 3 #property indicator_buffers 7 #property indicator_label1 "CPI MiniCandles" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrForestGreen, clrSeaGreen, clrSilver, clrTomato, clrFireBrick #property indicator_width1 2 #property indicator_label2 "CPI Strong Buy" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrForestGreen #property indicator_label3 "CPI Strong Sell" #property indicator_type3 DRAW_ARROW #property indicator_color3 clrFireBrick double BufOpen[], BufHigh[], BufLow[], BufClose[], BufColorIndex[]; double BufBuyArrow[], BufSellArrow[];
Входные параметры (визуальные размеры, зоны, стрелки, алерты)
Входные параметры сгруппированы по функциональным категориям, чтобы интерфейс настройки оставался интуитивным, а визуальные аспекты были отделены от аналитической логики. Визуальные параметры управляют масштабированием и ограничением размера мини-свечей CPI (в пунктах), благодаря чему маркеры остаются читаемыми на разных инструментах и при разной волатильности. Фильтр шума по диапазону (InpMinRangePoints) подавляет расчет CPI на свечах с минимальным диапазоном, где внутрисвечное давление менее информативно. Это помогает сократить число ложных срабатываний и сигналов низкого качества.
Пороговые значения зон определяют, как значения CPI классифицируются по состояниям умеренного и сильного давления, и служат основой и для назначения цветов, и для генерации алертов. Маркеры стрелок и алерты реализованы как опциональные функции. Каждую из этих функций можно включать и отключать независимо, что позволяет настраивать визуальный вывод индикатора и поведение уведомлений без изменения базового расчета CPI.
input double InpMarkerScale = 0.25; input int InpMinMarkerPoints = 2; input int InpMaxMarkerPoints = 200; input int InpMinRangePoints = 5; input bool InpHideNeutralMarkers = false; input bool InpShowLatestInfo = true; input double InpStrongThreshold = 0.60; input double InpMildThreshold = 0.20; input bool InpShowStrongArrows = true; input int InpArrowOffsetPoints = 10; input int InpArrowCodeBuy = 233; input int InpArrowCodeSell = 234; input bool InpEnableAlerts = true; input bool InpAlertOnExit = false; input bool InpAlertOnSignFlip = true; input bool InpPopupAlert = true; input bool InpSoundAlert = false; input string InpSoundFile = "alert.wav"; input bool InpPushAlert = false; input bool InpEmailAlert = false;
Формула CPI и вспомогательные функции
CPI рассчитывается с использованием нормирования по типу Closing Location Value (CLV), которое измеряет положение цены закрытия относительно полного диапазона свечи. Это дает ограниченное значение в интервале [-1, +1] для всех свечей с ненулевым диапазоном и обеспечивает сопоставимость силы давления между разными инструментами и таймфреймами. Если свеча не имеет диапазона, то есть High равен Low, значение CPI считается нейтральным (0.0). Это одновременно предотвращает деление на ноль и корректно отражает отсутствие направленного давления.
Помимо расчета CPI, при отрисовке используется небольшая вспомогательная функция ограничения значений, которая удерживает высоту мини-свечей CPI в пределах заданных пользователем минимального и максимального уровней. Это гарантирует, что маркеры останутся заметными, но не начнут визуально доминировать, сохраняя ясность графика при разной волатильности.
double ClampVal(const double v, const double lo, const double hi) { if(v < lo) return lo; if(v > hi) return hi; return v; } double CalcCPI(const double high, const double low, const double close) { double range = high - low; if(range <= 0.0) return 0.0; return (2.0*close - high - low) / range; }
Классификация зон и цветовая индикация
Мини-свечи CPI распределяются по пяти дискретным визуальным зонам, что упрощает интерпретацию и при этом сохраняет и направление, и силу внутрисвечного давления. Эти зоны реализованы через перечисление, числовой порядок элементов которого намеренно согласован с порядком цветов, заданных в indicator_color1. Это согласование критично, потому что DRAW_COLOR_CANDLES выбирает цвета по индексу, а не по имени. Вспомогательная функция ColorFromCPI() сопоставляет каждое вычисленное значение CPI с нужным индексом палитры на основе заданных умеренного и сильного порогов. Это гарантирует, что каждая мини-свеча будет отображаться в правильном цвете.
Одновременно с этим функция ZoneNameFromCPI() преобразует то же значение CPI в понятную текстовую метку, которая используется в информационном выводе – например, в тексте состояния на графике или во всплывающих подсказках. Поскольку и визуальная окраска, и текстовая классификация выводятся из одной и той же логики, реализация гарантирует согласованность между тем, что показано на графике, и тем, что сообщается пользователю.
enum CPIColorIndex { IDX_STRONG_BUY = 0, IDX_MILD_BUY = 1, IDX_NEUTRAL = 2, IDX_MILD_SELL = 3, IDX_STRONG_SELL= 4 }; int ColorFromCPI(const double cpi) { double a = MathAbs(cpi); if(a < InpMildThreshold) return IDX_NEUTRAL; if(cpi >= 0.0) { if(a >= InpStrongThreshold) return IDX_STRONG_BUY; return IDX_MILD_BUY; } else { if(a >= InpStrongThreshold) return IDX_STRONG_SELL; return IDX_MILD_SELL; } } string ZoneNameFromCPI(const double cpi) { double a = MathAbs(cpi); if(a < InpMildThreshold) return "NEUTRAL"; if(cpi >= 0.0) { if(a >= InpStrongThreshold) return "STRONG BUY"; return "MILD BUY"; } else { if(a >= InpStrongThreshold) return "STRONG SELL"; return "MILD SELL"; } }
Выделение сильного состояния (для алертов на основе переходов)
Для обработки алертов значения CPI дополнительно сводятся к упрощенному представлению сильного состояния. Вместо полной пятизонной классификации код сводит CPI к трем дискретным состояниям:
- +1 – сильное давление покупателей;
- -1 – сильное давление продавцов;
- 0 – все состояния вне сильной зоны (умеренные или нейтральные).
Эта абстракция позволяет сосредоточить логику алертов только на значимых переходах доминирования, игнорируя мелкие колебания, которые не требуют уведомления. Сравнивая текущее сильное состояние с предыдущим, система может обнаруживать входы в сильную зону и выходы из нее с минимальным числом ветвлений. Этот подход также предотвращает повторные алерты, пока CPI остается в одном и том же сильном состоянии на последовательных свечах, так что уведомления срабатывают только при реальном переходе.
int StrongStateFromCPI(const double cpi) { if(cpi >= InpStrongThreshold) return +1; if(cpi <= -InpStrongThreshold) return -1; return 0; }
Маршрутизация алертов (каналы доставки)
Все события алертов – включая входы в сильную зону, выходы из сильной зоны и смены знака CPI – проходят через централизованную функцию обработки алертов. Такой подход обеспечивает единое поведение во всех поддерживаемых каналах уведомлений, включая всплывающие окна терминала, звуковые алерты, push-уведомления и электронную почту. Каждый способ доставки управляется собственным входным параметром, поэтому пользователь может включать и отключать отдельные каналы, не меняя базовую логику алертов. Такое разделение сохраняет детерминированность логики алертов и одновременно делает настройки уведомлений гибкими.
void FireAlert(const string msg) { if(!InpEnableAlerts) return; if(InpPopupAlert) Alert(msg); if(InpSoundAlert) PlaySound(InpSoundFile); if(InpPushAlert) SendNotification(msg); if(InpEmailAlert) SendMail("CPI Alert", msg); }
Инициализация (OnInit): привязка буферов, стрелки, режим серий
Во время инициализации функция OnInit() привязывает все буферы индикатора к соответствующим графическим построениям в требуемом порядке. Сюда входит привязка синтетических буферов Open, High, Low, Close и индекса цвета к графическому построению DRAW_COLOR_CANDLES, а также привязка буферов стрелок к соответствующим графическим построениям DRAW_ARROW. На этом этапе также задаются коды стрелок Wingdings и настраиваются пустые значения, чтобы стрелки оставались скрытыми там, где они не нужны. Все буферы явно переводятся в режим серий, благодаря чему индекс 0 соответствует последнему бару и корректно согласуется с массивами цен, передаваемыми в OnCalculate.
int OnInit() { SetIndexBuffer(0, BufOpen, INDICATOR_DATA); SetIndexBuffer(1, BufHigh, INDICATOR_DATA); SetIndexBuffer(2, BufLow, INDICATOR_DATA); SetIndexBuffer(3, BufClose, INDICATOR_DATA); SetIndexBuffer(4, BufColorIndex, INDICATOR_COLOR_INDEX); PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 5); SetIndexBuffer(5, BufBuyArrow, INDICATOR_DATA); PlotIndexSetInteger(1, PLOT_ARROW, InpArrowCodeBuy); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE); SetIndexBuffer(6, BufSellArrow, INDICATOR_DATA); PlotIndexSetInteger(2, PLOT_ARROW, InpArrowCodeSell); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE); IndicatorSetString(INDICATOR_SHORTNAME, "CPI MiniCandles (CLV) + Strong Arrows"); ArraySetAsSeries(BufOpen, true); ArraySetAsSeries(BufHigh, true); ArraySetAsSeries(BufLow, true); ArraySetAsSeries(BufClose, true); ArraySetAsSeries(BufColorIndex, true); ArraySetAsSeries(BufBuyArrow, true); ArraySetAsSeries(BufSellArrow, true); return INIT_SUCCEEDED; }
Основной расчет (OnCalculate): закрытые бары, фильтр шума, построение маркеров
Основной расчетный цикл работает только с закрытыми свечами, обрабатывая бары с индексом i ≥ 1. Формирующаяся свеча (индекс 0) исключается, чтобы избежать нестабильных значений и перерисовки. Для каждого обрабатываемого бара сначала очищаются все соответствующие буферы, чтобы избежать остаточных данных от предыдущих расчетов.
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); double minMarker= InpMinMarkerPoints * point; double maxMarker= InpMaxMarkerPoints * point; double minRange = InpMinRangePoints * point; for(int i = rates_total - 1; i >= 1; --i) { BufOpen[i] = BufHigh[i] = BufLow[i] = BufClose[i] = EMPTY_VALUE; BufColorIndex[i] = EMPTY_VALUE; BufBuyArrow[i] = EMPTY_VALUE; BufSellArrow[i] = EMPTY_VALUE; double range = high[i] - low[i]; double cpi = 0.0; if(range > 0.0 && range >= minRange) cpi = CalcCPI(high[i], low[i], close[i]); int colorIdx = ColorFromCPI(cpi); if(!(InpHideNeutralMarkers && colorIdx == IDX_NEUTRAL)) { double mid = 0.5 * (high[i] + low[i]); double height = range * InpMarkerScale * MathAbs(cpi); height = ClampVal(height, minMarker, maxMarker); double o = mid; double c = (cpi >= 0.0 ? mid + height : mid - height); BufOpen[i] = o; BufClose[i] = c; BufHigh[i] = MathMax(o, c); BufLow[i] = MathMin(o, c); BufColorIndex[i] = (double)colorIdx; } }
CPI рассчитывается только в том случае, если общий диапазон свечи превышает заданный фильтр шума; в противном случае бар считается нейтральным. Если значение CPI допустимо, маркер мини-свечи располагается посередине основной свечи. Его высота определяется диапазоном свечи, масштабированным по абсолютному значению CPI и заданному пользователем коэффициенту. Затем эта высота ограничивается минимальным и максимальным размером маркера, чтобы визуальное масштабирование оставалось согласованным. При соответствующей настройке нейтральные маркеры можно скрывать полностью, чтобы не загромождать график.
Сильные стрелки (опциональное наложение)
Сильные стрелки рисуются только при включенной функции и только для свечей, прошедших фильтр шума. Это не позволяет стрелкам появляться на свечах малого диапазона, где CPI принудительно считается нейтральным. Сильные бычьи события отмечаются стрелками, нанесенными ниже минимума свечи, а сильные медвежьи события – стрелками, нанесенными выше максимума свечи. Чтобы избежать визуального наложения на ценовую свечу или мини-маркер CPI, применяется отступ в пунктах.
double arrowOff = InpArrowOffsetPoints * point; if(InpShowStrongArrows && range >= minRange) { if(cpi >= InpStrongThreshold) BufBuyArrow[i] = low[i] - arrowOff; else if(cpi <= -InpStrongThreshold) BufSellArrow[i] = high[i] + arrowOff; }
Скрытие бара 0 (формирующейся свечи)
Чтобы гарантировать стабильный вывод без перерисовки, формирующаяся свеча (индекс 0) явно скрывается и для мини-свечей CPI, и для стрелочных графических построений. Это решение гарантирует, что визуальный вывод будет точно соответствовать логике алертов, которая тоже работает только по закрытым барам. В результате и визуализация, и алерты отражают только окончательно сформированные данные.
BufOpen[0] = BufHigh[0] = BufLow[0] = BufClose[0] = EMPTY_VALUE; BufColorIndex[0] = EMPTY_VALUE; BufBuyArrow[0] = EMPTY_VALUE; BufSellArrow[0] = EMPTY_VALUE;
Информационная панель по последнему бару (опционально)
При включении индикатор показывает компактную информационную панель на графике со значением CPI для последней закрытой свечи (бар 1), соответствующей меткой зоны и текущей настройкой фильтра шума. Эта панель предназначена прежде всего для тестирования и проверки: она позволяет убедиться в поведении CPI без просмотра внутренних буферов. Она не влияет ни на отрисовку, ни на логику алертов, ни на производительность.
if(InpShowLatestInfo) { double cpi1 = 0.0; double range1 = high[1] - low[1]; if(range1 > 0.0 && range1 >= minRange) cpi1 = CalcCPI(high[1], low[1], close[1]); Comment(StringFormat("CPI (closed bar): %.3f | %s | MinRange=%d pts", cpi1, ZoneNameFromCPI(cpi1), InpMinRangePoints)); } else { Comment(""); }
Алерты: фильтр нового бара, сильные переходы, опциональный выход и смена знака
Алерты проверяются один раз на каждом новом закрытом баре с использованием сохраненной временной метки (lastAlertBarTime), чтобы предотвратить дублирование. Алерт входа в сильную зону срабатывает, когда текущее сильное состояние не равно нулю и отличается от ранее сохраненного сильного состояния. Опциональные алерты выхода срабатывают, когда предыдущее состояние было сильным, а текущее перешло в несильное.
datetime lastAlertBarTime = 0; int lastStrongState = 0; if(InpEnableAlerts) { datetime barTime = time[1]; if(barTime != lastAlertBarTime) { double cpi1 = 0.0, cpi2 = 0.0; double r1 = high[1] - low[1]; double r2 = high[2] - low[2]; if(r1 > 0.0 && r1 >= minRange) cpi1 = CalcCPI(high[1], low[1], close[1]); if(r2 > 0.0 && r2 >= minRange) cpi2 = CalcCPI(high[2], low[2], close[2]); int strongState = StrongStateFromCPI(cpi1); if(strongState != 0 && strongState != lastStrongState) { string side = (strongState > 0 ? "STRONG BUY" : "STRONG SELL"); FireAlert(StringFormat("%s %s | CPI=%.3f | TF=%s | %s", _Symbol, side, cpi1, EnumToString((ENUM_TIMEFRAMES)_Period), TimeToString(barTime, TIME_DATE|TIME_MINUTES))); } else if(InpAlertOnExit && lastStrongState != 0 && strongState == 0) { FireAlert(StringFormat("%s EXIT STRONG | CPI=%.3f | TF=%s | %s", _Symbol, cpi1, EnumToString((ENUM_TIMEFRAMES)_Period), TimeToString(barTime, TIME_DATE|TIME_MINUTES))); } if(InpAlertOnSignFlip) { if(r1 >= minRange && r2 >= minRange) { if((cpi2 < 0.0 && cpi1 > 0.0) || (cpi2 > 0.0 && cpi1 < 0.0)) FireAlert(StringFormat("%s CPI SIGN FLIP | prev=%.3f now=%.3f | TF=%s | %s", _Symbol, cpi2, cpi1, EnumToString((ENUM_TIMEFRAMES)_Period), TimeToString(barTime, TIME_DATE|TIME_MINUTES))); } } lastStrongState = strongState; lastAlertBarTime = barTime; } }
Опциональные алерты смены знака генерируются, когда значение CPI пересекает ноль, но только если и текущая, и предыдущая свечи проходят фильтр шума. Это условие отсекает ложные сигналы, вызванные свечами с малым диапазоном, которые иначе могли бы исказить интерпретацию направления.
Примечание о производительности (prev_calculated)
Для простоты и во избежание артефактов из-за устаревших значений в буферах текущая реализация пересчитывает все закрытые бары на каждом тике. Поскольку вычисления по каждому бару здесь легковесны, такой подход приемлем для большинства практических сценариев и повышает надежность во время разработки и тестирования.
// current approach (simple, stable): for(int i = rates_total - 1; i >= 1; --i) { /* ... */ } // optimized approach (conceptual): // if(prev_calculated == 0) start = rates_total - 1; else start = 2; // for(int i = start; i >= 1; --i) { /* ... */ }
Если потребуется оптимизация производительности, цикл вычислений можно доработать с помощью параметра prev_calculated, чтобы обрабатывать только последние закрытые бары. Но любая такая оптимизация все равно должна соблюдать базовые правила: очистку слотов буфера для пересчитываемых баров, применение шумового фильтра и исключение формирующейся свечи.
Тестирование
Чтобы обеспечить надежную и стабильную работу, все тесты следует проводить в разных торговых условиях. В частности, индикатор следует проверять как минимум на двух разных типах инструментов – например, на основной валютной паре и на инструменте, не относящемся к Forex (например на индексе или товаре), – а также на нескольких таймфреймах (например, M5, M15, H1). Тестирование на разных рыночных структурах и таймфреймах необходимо, чтобы убедиться, что масштабирование в пунктах, шумовой фильтр по диапазону и логика порогов CPI надежно работают на инструментах с разной волатильностью, ценовым масштабом и числом знаков после запятой.
Я протестировал индикатор на реальном графике MetaTrader 5, чтобы убедиться, что визуальный слой, информационная панель и система алертов согласованно работают по закрытым барам. На рисунке ниже показан индикатор на графике EURUSD, H1, со стандартной настройкой шумового фильтра (MinRange = 5 pts).

Информационная панель на графике подтверждает корректную работу сразу по трем аспектам:
CPI (closed bar): 0.767 | STRONG BUY | MinRange = 5 pts
Этот вывод подтверждает следующее:
- CPI рассчитывается по бару 1 (последней закрытой свече);
- классификация зон работает корректно: значение CPI 0.767 отнесено к зоне STRONG BUY;
- настройка шумового фильтра активна и отображается корректно, то есть вычисления выполняются с учетом диапазона свечи.
На вкладке "Журнал" видно, что алерты срабатывают в соответствии с заданными правилами переходов. В этом тесте в журнале фиксируются и алерт STRONG BUY, и алерт CPI SIGN FLIP с одной и той же меткой времени закрытия бара. Это ожидаемое поведение, когда CPI одновременно:
- входит в сильно положительную зону; и
- переходит из отрицательной области в положительную между предыдущим и текущим закрытыми барами.
Эти результаты показывают, что система алертов индикатора основана на переходах, и алерты проверяются один раз на каждом новом закрытом баре, а не реагируют непрерывно на каждый тик. Визуальный вывод и алерты полностью согласованы, что обеспечивает детерминированное поведение без перерисовки. Ниже приведен дополнительный тест на Step Index (H4), где показаны мини-свечи CPI с чередующимися состояниями внутрисвечного давления. Для последнего закрытого бара информационная панель на графике показывает зону умеренной продажи по CPI, а стрелки сильных зон выделяют периоды доминирующего давления при тех же порогах и настройках шумового фильтра.

Заключение
Индекс давления свечи (CPI) – это инструмент анализа Price Action, который визуализирует внутрисвечное давление покупателей и продавцов с помощью нормированной модели положения цены закрытия. Объединяя структурированную классификацию зон, цветовое отображение и алерты на основе переходов, он дает визуализацию рыночного давления без перерисовки и тем самым раскрывает динамику, которую нельзя увидеть только по цвету свечи.
В реализации для MetaTrader 5 акцент сделан на детерминированном поведении: строгая работа по закрытым барам, явное управление буферами и четкое разделение визуализации и логики алертов. Индикатор можно настроить так, чтобы он работал последовательно на разных инструментах и таймфреймах. Благодаря этим решениям CPI становится надежным инструментом и для технического анализа, и для наглядного объяснения концепции внутрисвечного давления.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/20949
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Категориальная скрытая марковская модель на языке MQL5
Создание торговой системы (Часть 5): Управление прибылью с помощью структурированного выхода из позиций
Разработка инструментария для анализа Price Action (Часть 53): Тепловая карта плотности паттернов для выявления зон поддержки и сопротивления
Разработка инструментария для анализа Price Action (Часть 52): Визуальный анализ структуры рынка на нескольких таймфреймах
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Ознакомьтесь с новой статьей: Price Action Analysis Toolkit (Part 55): Проектирование наложения мини-свечей CPI для внутрибарного давления.
Автор: Кристиан Бенджамин
Строятся ли стрелки на открытой свече?