English Deutsch 日本語
preview
Индикатор Sigma Score для MetaTrader 5: Простой детектор статистических аномалий

Индикатор Sigma Score для MetaTrader 5: Простой детектор статистических аномалий

MetaTrader 5Индикаторы |
105 0
TECHAURORA - FZCO
Dominic Michael Frehner

Введение

Многие трейдеры быстро понимают, что цена не движется плавно и предсказуемо. На рынках бывают "тихие" периоды, сменяющиеся внезапными всплесками, падениями и резкими движениями. Один из практических способов определить, является ли движение нормальным, то есть типичным для недавнего поведения рынка, или необычным, то есть редким по сравнению с недавним поведением рынка, – стандартизировать доходности и выразить их в сигма-единицах.

Именно это и делает индикатор Sigma Score. Он преобразует последнюю доходность в z-оценку, также называемую стандартной оценкой, и отображает ее в отдельном подокне. Проще говоря, Sigma Score отвечает на один вопрос:

"На сколько стандартных отклонений доходность текущего бара отличается от средней доходности последних N баров?"

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


Что такое Sigma Score и что он означает?

В статистике z-оценка показывает, насколько значение отклоняется от среднего значения в единицах стандартного отклонения. Стандартное определение:

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

Этот индикатор использует логарифмические доходности, определяемые как:

Это определение доходности широко используется в количественных финансах, поскольку логарифмические доходности аддитивны во времени, то есть суммируются за несколько периодов. Итак, в этом индикаторе:

  • – текущая логарифмическая доходность;
  • μ – средняя логарифмическая доходность за период, заданный параметром InpLookback;
  • σ – стандартное отклонение логарифмических доходностей за период, заданный параметром InpLookback.

Стандартное отклонение логарифмических доходностей также служит стандартным способом выражения исторической волатильности.


Почему пороги по умолчанию часто равны ±2,0

Если бы доходности имели идеальное нормальное распределение (реальные рынки таковыми не являются, но это все же полезное эмпирическое правило), то около 95% наблюдений попадали бы в диапазон ±2 стандартных отклонений от среднего значения.

Поэтому многие трейдеры используют:

  • Sigma Score > +2 как необычно сильную положительную доходность;
  • Sigma Score < -2 как необычно сильную отрицательную доходность.

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

Примечание: в данной реализации скользящее окно включает доходность текущего бара, j начинается с 0. Поэтому z-оценка вычисляется по выборке периода анализа, содержащей текущее наблюдение.


Разработка индикатора

Шаг 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);
}

Что было создано:

  1. Сопоставление буфера (и порядок серии)
    SetIndexBuffer(0, SigmaBuffer, INDICATOR_DATA). Связывает SigmaBuffer[] с графическим построением №0. После этого при каждом присваивании значения, например SigmaBuffer[i] = ..., MetaTrader отображает его как линию индикатора.
    ArraySetAsSeries(SigmaBuffer, true). Задает буферу поведение, аналогичное массивам цен. Индекс 0 – самый последний бар, индекс 1 – предыдущий бар и т.д. Это сохраняет согласованность индексации с close[0], close[1] и т.д.

  2. Горизонтальные ориентировочные уровни (с оформлением)
    IndicatorSetInteger(INDICATOR_LEVELS, 3). Создает три горизонтальные ориентировочные линии. Они устанавливаются на 0.0, верхний порог и нижний порог. Это визуально отделяет нормальные значения около нуля от необычно больших положительных или отрицательных значений.
    Кроме того, эти уровни оформляются для удобочитаемости. Нулевая линия задается серой и точечной, а пороги – красным и зеленым цветами со штриховым стилем, поэтому экстремумы сразу выделяются.

  3. Именование и форматирование
    Задается метка графического построения "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 Demonstration


Как использовать 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 может использоваться как индикатор рыночного стресса для принятия решений как на основе возврата к среднему, так и на основе моментума, а также как инструмент управления рисками для распознавания аномальных условий и корректировки размера позиции или расстояния до стопа. При наличии полного кода индикатор можно расширять, добавляя алерты, фильтры тренда или логику нескольких таймфреймов. При этом основная идея остается неизменной: это количественная мера того, насколько необычным было последнее движение по сравнению с недавней историей.


Список литературы

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/20728

Прикрепленные файлы |
Sigma_Score.mq5 (5.83 KB)
Мастер-класс по созданию пользовательских индикаторов (Часть 1): Разработка индикатора Supertrend на MQL5 Мастер-класс по созданию пользовательских индикаторов (Часть 1): Разработка индикатора Supertrend на MQL5
Создайте индикатор Supertrend без перерисовки на языке MQL5 для MetaTrader 5 с нуля. Используются хэндл iATR и CopyBuffer для получения волатильности, буферы привязываются через SetIndexBuffer, а графические построения (DRAWCOLORCANDLES и две полосы, отображаемые линиями) настраиваются через PlotIndexSetInteger. Логика обновляется только на закрытых барах и использует EMPTY_VALUE для скрытия неактивных полос, при этом используются входные параметры atrPeriod и atrMultiplier. Получается аккуратный индикатор, накладываемый поверх графика, готовый для использования в советниках, с документированными буферами для стратегий и сигналов.
Интеграция MQL5 с пакетами обработки данных (Часть 6): Объединение рыночной обратной связи и адаптации модели Интеграция MQL5 с пакетами обработки данных (Часть 6): Объединение рыночной обратной связи и адаптации модели
В этой части рассматривается объединение рыночной обратной связи в реальном времени – результатов текущих сделок, изменений волатильности и сдвигов ликвидности – с адаптивным обучением модели. Это сделает торговую систему отзывчивой и способной к постоянному самосовершенствованию.
Нейросети в трейдинге: Двухуровневая адаптация торговой политики (Объект верхнего уровня) Нейросети в трейдинге: Двухуровневая адаптация торговой политики (Объект верхнего уровня)
Продолжаем адаптацию фреймворка D2Skill и переходим к построению объекта верхнего уровня CD2Skill для двухуровневой коррекции торговой политики. Механизм интегрируется в архитектуру ORION и дополняет существующий Актёр банками Task Skills и Step Skills. Показаны принципы их инициализации, включения в прямой проход и обучения по псевдоостаткам. Особое внимание уделяется сохранению исходного вычислительного конвейера, причинного порядка и независимости Критика.
Кодирование свечных моделей (Часть 3): Частотный анализ односвечных структур Кодирование свечных моделей (Часть 3): Частотный анализ односвечных структур
В данной статье представлена схема частотного анализа закодированных свечных паттернов в MQL5. Преобразуя свечи в буквенные символы, можно анализировать историческое движение цен как статистическую последовательность, а не как визуальный график. Используя пару GBPUSD и золото на нескольких таймфреймах, в этом исследовании мы изучаем частоту появления отдельных типов свечей, выявляем доминирующие рыночные структуры и показываем симметрию между бычьими и медвежьими движениями цен. Результаты закладывают количественную основу для обнаружения паттернов и подготавливают почву для анализа многосвечных последовательностей и их прогностического потенциала в алгоритмических торговых системах.