Индикатор Sigma Score для MetaTrader 5: Простой детектор статистических аномалий
Введение
Многие трейдеры быстро понимают, что цена не движется плавно и предсказуемо. На рынках бывают "тихие" периоды, сменяющиеся внезапными всплесками, падениями и резкими движениями. Один из практических способов определить, является ли движение нормальным, то есть типичным для недавнего поведения рынка, или необычным, то есть редким по сравнению с недавним поведением рынка, – стандартизировать доходности и выразить их в сигма-единицах.
Именно это и делает индикатор Sigma Score. Он преобразует последнюю доходность в z-оценку, также называемую стандартной оценкой, и отображает ее в отдельном подокне. Проще говоря, Sigma Score отвечает на один вопрос:
"На сколько стандартных отклонений доходность текущего бара отличается от средней доходности последних N баров?"
Это делает индикатор полезным для начинающих: для его интерпретации не требуется сложная торговая теория. Достаточно понимать, что значение около 0 считается нормальным, тогда как большие положительные или отрицательные значения указывают на необычно сильные движения.
Что такое Sigma Score и что он означает?
В статистике z-оценка показывает, насколько значение отклоняется от среднего значения в единицах стандартного отклонения. Стандартное определение:

где x – текущее значение, μ – математическое ожидание (среднее значение), а σ – стандартное отклонение. В финансах эта же идея часто применяется к доходности.
Этот индикатор использует логарифмические доходности, определяемые как:

Это определение доходности широко используется в количественных финансах, поскольку логарифмические доходности аддитивны во времени, то есть суммируются за несколько периодов. Итак, в этом индикаторе:
- x – текущая логарифмическая доходность;
- μ – средняя логарифмическая доходность за период, заданный параметром InpLookback;
- σ – стандартное отклонение логарифмических доходностей за период, заданный параметром InpLookback.
Стандартное отклонение логарифмических доходностей также служит стандартным способом выражения исторической волатильности.
Почему пороги по умолчанию часто равны ±2,0
Если бы доходности имели идеальное нормальное распределение (реальные рынки таковыми не являются, но это все же полезное эмпирическое правило), то около 95% наблюдений попадали бы в диапазон ±2 стандартных отклонений от среднего значения.
Поэтому многие трейдеры используют:
- Sigma Score > +2 как необычно сильную положительную доходность;
- Sigma Score < -2 как необычно сильную отрицательную доходность.
Важное замечание для реальной торговли: финансовые доходности часто имеют толстые хвосты, то есть экстремальные движения происходят чаще, чем предполагает идеальное нормальное распределение. Поэтому пороги лучше рассматривать как практические зоны стресса и аномалий, а не как гарантированные вероятности.
Разработка индикатора
Шаг 1. Создание каркаса индикатора – свойства и построение
При создании нового файла индикатора в MetaEditor первым важным разделом является блок #property. В этом блоке задается, как индикатор будет отображаться в MetaTrader 5.
#property indicator_separate_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_type1 DRAW_LINE #property indicator_color1 clrBlue #property indicator_width1 2 #property indicator_label1 "Sigma Score"
Что здесь задано:
- indicator_separate_window – индикатор отображается ниже основного графика;
- один буфер и одно графическое построение – требуется только одна линия (Sigma Score);
- DRAW_LINE – MetaTrader 5 строит линию по заданным значениям;
- цвет/метка – линия Sigma Score будет отображаться синим цветом.
Шаг 2. Входные параметры, обеспечивающие возможность настройки индикатора
Входные параметры – это настройки, которые пользователь может изменить в MetaTrader 5:
input int InpLookback = 20; input double InpUpperThreshold = 2.0; input double InpLowerThreshold = -2.0;
Что это означает на практике:
- Период анализа – число баров, определяющих недавнюю историю для расчета среднего значения и волатильности;
- Верхний и нижний пороги – ориентировочные линии, часто ±2 как зона большого движения.
Шаг 3. Буферы и переменные
Индикаторы отрисовываются путем заполнения массивов (буферов). Данный индикатор имеет один выходной буфер:
double SigmaBuffer[];
Требуется только один буфер индикатора, поскольку строится одна серия – Sigma Score. Шаг 4. Инициализация
OnInit() выполняется один раз при добавлении индикатора на график. Функция подготавливает все необходимое для построения индикатора на графике в MetaTrader 5.
int OnInit() { // Indicator buffers mapping SetIndexBuffer(0, SigmaBuffer, INDICATOR_DATA); ArraySetAsSeries(SigmaBuffer, true); // Set horizontal levels IndicatorSetInteger(INDICATOR_LEVELS, 3); IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, 0.0); IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, InpUpperThreshold); IndicatorSetDouble(INDICATOR_LEVELVALUE, 2, InpLowerThreshold); IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, clrGray); IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, clrRed); IndicatorSetInteger(INDICATOR_LEVELCOLOR, 2, clrGreen); IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, STYLE_DOT); IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, STYLE_DASH); IndicatorSetInteger(INDICATOR_LEVELSTYLE, 2, STYLE_DASH); // Set indicator labels PlotIndexSetString(0, PLOT_LABEL, "Sigma Score"); IndicatorSetString(INDICATOR_SHORTNAME, "Sigma Score (" + IntegerToString(InpLookback) + ")"); IndicatorSetInteger(INDICATOR_DIGITS, 2); return(INIT_SUCCEEDED); }
Что было создано:
-
Сопоставление буфера (и порядок серии)
SetIndexBuffer(0, SigmaBuffer, INDICATOR_DATA). Связывает SigmaBuffer[] с графическим построением №0. После этого при каждом присваивании значения, например SigmaBuffer[i] = ..., MetaTrader отображает его как линию индикатора.
ArraySetAsSeries(SigmaBuffer, true). Задает буферу поведение, аналогичное массивам цен. Индекс 0 – самый последний бар, индекс 1 – предыдущий бар и т.д. Это сохраняет согласованность индексации с close[0], close[1] и т.д. -
Горизонтальные ориентировочные уровни (с оформлением)
IndicatorSetInteger(INDICATOR_LEVELS, 3). Создает три горизонтальные ориентировочные линии. Они устанавливаются на 0.0, верхний порог и нижний порог. Это визуально отделяет нормальные значения около нуля от необычно больших положительных или отрицательных значений.
Кроме того, эти уровни оформляются для удобочитаемости. Нулевая линия задается серой и точечной, а пороги – красным и зеленым цветами со штриховым стилем, поэтому экстремумы сразу выделяются. -
Именование и форматирование
Задается метка графического построения "Sigma Score" и короткое имя со значением периода анализа. "Sigma Score (20)", "Sigma Score (50)" и т.д. Это полезно при добавлении нескольких экземпляров индикатора с разными периодами анализа.
Наконец, IndicatorSetInteger(INDICATOR_DIGITS, 2). Функция форматирует вывод с точностью до двух десятичных знаков для аккуратного отображения.
Шаг 5. Расчет Sigma Score в OnCalculate()
OnCalculate() – это место, где MetaTrader 5 запрашивает: "Предоставь значения индикатора для баров". В данном случае для каждого бара вычисляется Sigma Score и записывается в SigmaBuffer[], чтобы MetaTrader мог построить линию. Сначала проверяется наличие минимально необходимого числа баров:
if(rates_total < InpLookback + 1) { return(0); }
Для построения скользящей статистики требуется как минимум InpLookback баров, а также один дополнительный бар, поскольку логарифмическая доходность использует close[i] и close[i+1]. Если истории недостаточно, функция завершается, а индикатор ничего не отображает. Далее задаем для входных массивов режим временных рядов:
ArraySetAsSeries(close, true); ArraySetAsSeries(time, true);
time[] задается как серия для согласованности, хотя эта версия не использует время напрямую. Это также обеспечивает согласованность индексации: close[0] – самый последний бар, close[1] – предыдущий и т.д. Это важно, поскольку циклы используют обращение к более старым барам через i + j и i + 1. Теперь определяется число баров, которые действительно требуется пересчитать. MetaTrader 5 многократно вызывает индикаторы, поэтому пересчет всего графика на каждом тике был бы медленным. Первый запуск отделяется от последующих обновлений:
int start; if(prev_calculated == 0) { start = rates_total - InpLookback - 1; ArrayInitialize(SigmaBuffer, EMPTY_VALUE); } else { start = rates_total - prev_calculated; }
При самом первом вызове, prev_calculated == 0, буфер инициализируется значением EMPTY_VALUE. Это важно. EMPTY_VALUE указывает MetaTrader 5 не строить линию здесь, поэтому в областях, где индикатор еще не может быть вычислен, не отображаются ложные линии. Также задается start, чтобы начать с самого старого бара, для которого доступен полный период анализа. При последующих вызовах вычисляются только вновь сформированные бары. Далее выполняется фактическое вычисление Sigma Score. Выполняется перебор баров, которые требуется обновить:
for(int i = start; i >= 0; i--) { if(i + InpLookback >= rates_total) { SigmaBuffer[i] = EMPTY_VALUE; continue; } double sum_returns = 0; double sum_squared = 0; int valid_count = 0; for(int j = 0; j < InpLookback; j++) { int idx1 = i + j; int idx2 = i + j + 1; if(idx2 < rates_total && close[idx1] > 0 && close[idx2] > 0) { double log_return = MathLog(close[idx1] / close[idx2]); sum_returns += log_return; sum_squared += log_return * log_return; valid_count++; } } if(i + 1 < rates_total && close[i] > 0 && close[i + 1] > 0) { double current_return = MathLog(close[i] / close[i + 1]); if(valid_count >= InpLookback) { double mean = sum_returns / valid_count; double variance = (sum_squared / valid_count) - (mean * mean); if(variance < 0) variance = 0; double stdev = MathSqrt(variance); if(stdev > 0.0000001) SigmaBuffer[i] = (current_return - mean) / stdev; else SigmaBuffer[i] = 0; } else { SigmaBuffer[i] = EMPTY_VALUE; } } else { SigmaBuffer[i] = EMPTY_VALUE; } }
В этом разделе выполняются все необходимые расчеты с учетом граничных случаев:
Сначала пропускаются бары, для которых нельзя построить полный период анализа. Если i + InpLookback выходит за пределы доступной истории, присваиваем SigmaBuffer[i] = EMPTY_VALUE, после чего выполняется переход к следующему бару. Это предотвращает отображение в MetaTrader 5 значений, рассчитанных на основе неполных данных. Затем вычисляется статистика логарифмических доходностей за период анализа. Вместо сохранения доходностей в отдельном массиве они вычисляются непосредственно в цикле, после чего накапливаются две суммы:
- sum_returns – сумма логарифмических доходностей для расчета среднего значения;
- sum_squared – сумма квадратов логарифмических доходностей для расчета дисперсии.
В valid_count также подсчитывается число вычисленных допустимых значений доходности. Поскольку для логарифмических доходностей требуются положительные цены, используется условие close > 0. Если значение доходности недопустимо, оно просто пропускается. Далее вычисляется логарифмическая доходность текущего бара, то есть значение, которое требуется стандартизировать. Если значение допустимо и доступен полный период анализа (valid_count >= InpLookback), вычисляются:
- математическое ожидание (mean) – sum_returns / valid_count;
- дисперсия (variance) – (sum_squared / valid_count) - mean²;
- стандартное отклонение (standard deviation) – sqrt(variance).
Наконец, вычисляется Sigma Score (z-оценка):

В коде:
SigmaBuffer[i] = (current_return - mean) / stdev;
Также используется небольшой порог безопасности (stdev > 0.0000001), чтобы избежать деления на число, чрезвычайно близкое к нулю. Если волатильность фактически равна нулю, выводится 0, чтобы избежать нестабильных всплесков. В конце возвращается rates_total, чтобы MetaTrader 5 знал, что значения предоставлены до текущего бара:
return(rates_total);
Реализован полный механизм скользящей z-оценки, который:
- обеспечивает наличие достаточного количества баров (InpLookback + 1);
- вычисляет только необходимые значения на основе prev_calculated;
- скрывает области, для которых вычисление невозможно, с помощью EMPTY_VALUE;
- вычисляет логарифмические доходности, скользящее среднее и скользящее стандартное отклонение;
- безопасно (без артефактов деления на ноль) записывает окончательное значение Sigma Score в один буфер графического построения.

Как использовать Sigma Score в торговле
Индикатор Sigma Score сам по себе не является полноценной стратегией. Его лучше использовать как инструмент для определения контекста и выбора момента входа. При появлении экстремального значения можно решить какой подход выбрать: торговлю на возврат к среднему или торговлю по импульсу.
При торговле на возврате к среднему экстремальные значения Sigma Score рассматриваются как "растянутые движения" (движения с чрезмерным отклонением). Например, если Sigma Score ниже -2, рынок опустился необычно сильно по сравнению с последними 20 барами. На рынке с боковым движением трейдеры часто ищут паттерн стабилизации (например, цена перестает обновлять минимумы или появляется бычий свечной паттерн), а затем ожидают возврата к недавнему среднему уровню.
При торговле на моментуме экстремальные значения Sigma Score рассматриваются как сигналы продолжения шокового импульса. Например, если Sigma Score выше +2 и рынок находится в явном восходящем тренде, это может указывать на сильное импульсное движение, а не на немедленный откат. В таком случае Sigma Score можно использовать, чтобы избежать слишком раннего открытия коротких позиций или искать входы на откате, а не пытаться торговать против сильного движения.
В обоих случаях Sigma Score также полезен для управления рисками: Экстремальное значение Sigma Score часто означает, что рынок движется быстро, спреды могут расширяться, а стопы, возможно, придется ставить дальше. Даже если вы не совершаете сделку по сигналу, индикатор может помочь адаптировать размер позиции и ожидания.
Заключение
Мы начали с распространенной торговой проблемы. Трудно определить, является ли движение цены действительно экстремальным или просто нормальным шумом для текущего рыночного режима. Построив индикатор Sigma Score шаг за шагом, вы получаете простой объективный способ оценить это одним числом.
Реализован полный индикатор MetaTrader 5, который вычисляет логарифмические доходности, их скользящее среднее и стандартное отклонение за настраиваемый период анализа, а также преобразует последнюю доходность в z-оценку (Sigma Score). В результате движения рынка можно интерпретировать в сигма-единицах: значения около 0 указывают на нормальное поведение, тогда как значения за пределами заданных порогов, например ±2, выделяют необычно сильные бычьи или медвежьи импульсы по сравнению с недавними условиями.
Самое главное, мы также научились применять эти значения на практике. Sigma Score может использоваться как индикатор рыночного стресса для принятия решений как на основе возврата к среднему, так и на основе моментума, а также как инструмент управления рисками для распознавания аномальных условий и корректировки размера позиции или расстояния до стопа. При наличии полного кода индикатор можно расширять, добавляя алерты, фильтры тренда или логику нескольких таймфреймов. При этом основная идея остается неизменной: это количественная мера того, насколько необычным было последнее движение по сравнению с недавней историей.
Список литературы
- Campbell, J.Y., Lo, A.W. and MacKinlay, A.C. (1997) The Econometrics of Financial Markets. Принстон, Нью-Джерси: Издательство Принстонского университета. Доступно по адресу: https://press.princeton.edu/books/paperback/9780691043012/the-econometrics-of-financial-markets (по состоянию на 24 декабря 2025).
- Cont, R. (2001) ‘Empirical properties of asset returns: stylized facts and statistical issues’, Quantitative Finance, 1(2), стр. 223-236. Доступно по адресу: https://www.cfm.com/wp-content/uploads/2022/12/163-1997-herd-behavior-and-aggregate-fluctuations-in-financial-market.pdf (по состоянию на 24 декабря 2025).
- Cont, R. (2001) ‘Empirical properties of asset returns: stylized facts and statistical issues’, Quantitative Finance, 1(2), стр. 223-236. Доступно по адресу: https://rama.cont.perso.math.cnrs.fr/pdf/empirical.pdf (по состоянию на 24 декабря 2025). Дополнительная ссылка: https://www.tandfonline.com/doi/abs/10.1080/713665670 (по состоянию на 24 декабря 2025).
- Fan, J. and Yao, Q. (2017) The Elements of Financial Econometrics. Кембридж: Издательство Кембриджского университета. Отрывок "Asset Returns", определение логарифмических доходностей. Доступно по адресу: https://assets.cambridge.org/97811071/91174/excerpt/9781107191174_excerpt.pdf (по состоянию на 24 декабря 2025).
- Hull, J.C. (2002) Options, Futures, and Other Derivatives. 5-е изд. Аппер Сэддл Ривер, Нью-Джерси: Прентис Холл. Заметки к главе "Estimating Volatility from Historical Data" – оценка волатильности через стандартное отклонение непрерывно начисляемых доходностей. Доступно по адресу: https://mx.nthu.edu.tw/~jtyang/Teaching/Financial_Engineering/Notes/HullOFO5ed/CH12.pdf (по состоянию на 24 декабря 2025).
- Mandelbrot, B. (1963) "The Variation of Certain Speculative Prices", The Journal of Business, 36(4), стр. 394-419. Доступно по адресу: https://e-m-h.org/Mand63.pdf (по состоянию на 24 декабря 2025).
- Национальный институт стандартов и технологий (NIST) (2012) "ISO 13528 ZSCORE (LET) – standard definition of a z-score". NIST/SEMATECH e-Handbook / Dataplot Reference Manual. Доступно по адресу: https://www.itl.nist.gov/div898/software/dataplot/refman2/auxillar/zscore.htm (по состоянию на 24 декабря 2025).
- Zivot, E. (2014) "Return Calculations" (course notes). Вашингтонский университет. "Definition of continuously compounded (log) returns". Доступно по адресу: https://faculty.washington.edu/ezivot/econ424/returnCalculations.pdf (по состоянию на 24 декабря 2025).
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/20728
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Мастер-класс по созданию пользовательских индикаторов (Часть 1): Разработка индикатора Supertrend на MQL5
Интеграция MQL5 с пакетами обработки данных (Часть 6): Объединение рыночной обратной связи и адаптации модели
Нейросети в трейдинге: Двухуровневая адаптация торговой политики (Объект верхнего уровня)
Кодирование свечных моделей (Часть 3): Частотный анализ односвечных структур
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования