Как устроены технические индикаторы на фондовых рынках

Любой кто когда-нибудь интересовался фондовыми или криптовалютными рынками видел эти дополнительные линии. И вы наверно слышали мнения от матерых трейдеров о том, что они не работают и как они не используют ничего. Но многим они очень помогают и мой торговый терминал, в который я лениво смотрю раз в день, выглядит примерно как на картинке ниже.

Как же все таки они устроены? И кому это может быть полезно? Вам определенно с этим следует ознакомиться, если:

  1. Вы ими пользуетесь в своей торговле
  2. Вы планируете написать торгового робота
  3. Вы хотите реализовать торговую стратегию сами

технические индикаторы

Технический индикатор, это чаще всего оконная, весовая или рекуррентная функция от цен и объемов, которые приходят с биржи в формате массива свеч TOHLCV (unix time, open, high, low, close, volume). Так же могут использоваться различные фильтрации, максимумы-минимумы или другие индикаторы как основа для последующих вычислений.

Скользящая средняя (SMA)

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

function sma($close, window) {
  return rolling(x => mean(x), window, $close);
}

где функция mean() это среднее значение, параметр window — размер окна, а rolling() это комбинация оконной функции, которая для каждой текущей ячейки массива выдает массив из последних n элементов, и операции, которая сворачивает окно в число.

function rolling(operation, window, array) {
  let result = [];
  for (let i = 0; i < array.length; i++) {
    if (i + 1 < window) {
      result.push(NaN);
    } else {
      result.push(operation(array.slice(i + 1 - window, i + 1)));
    }
  }
  return result;
}

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

Скользящая средняя (SMA)

Обычно рассматривают пару индикаторов и точка, когда индикатор с коротким окном пересекает индикатор с длинным окном снизу рассматривается как потенциальная точка входа, и сверху — выхода. На практике чаще используют экспоненциально взвешенную скользящую среднюю, применяя весовую оконную функцию, что бы уменьшить эффект запаздывания.

Среднеквадратичное отклонение (STDEV)

Если мы заменим в предыдущем варианте функцию mean() на корень из дисперсии sd(), то получим уже скользящее среднеквадратичное отклонение.

function stdev($close, window) {
  return rolling(x => sd(x), window, $close);
}

Дисперсия считается обычным всем известным способом, чаще всего без коррекции Бесселя. Так же используется именно корень из дисперсии, так как сама дисперсия измеряется в квадратных рублях/долларах.

Полосы Боллинджера (BB)

Таким образом мы уже получили два базовых индикатора, которые уже можно комбинировать и получать новые. Например, если поточечно сложить скользящую среднюю и среднеквадратичное отклонение, при этом домножив на 2, то мы получим верхнюю часть полосы Боллинджера, а если вычесть — нижнюю.

Полосы Боллинджера (BB)

В коде это будет выглядеть так

function bb($close, window, mult) {
  let middle = sma($close, window);
  let upper = pointwise((a, b) => a + b * mult, middle, stdev($close, window));
  let lower = pointwise((a, b) => a - b * mult, middle, stdev($close, window));
  return { lower : lower, upper : upper};
}

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

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

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


Экспоненциально взвешенная скользящая средняя (EMA)

Как можно уменьшить запаздывание скользящей средней? Так как при ее вычислении складывается n последних цен закрытия, можно понять что складывать можно с каким то весом, уменьшая вклад старых цен. Таким образом мы приходим к формуле взвешенной оконной функции.

$\bar x = \frac{\sum x_i}{N} = \frac{\sum 1 \cdot x_i}{\sum 1} \quad \Rightarrow \quad \widetilde{x} = \frac{\sum x_i w_i}{\sum w_i}$


если $w_i=q^i$ и выбрать какую то константу $q$ меньше единицы, то мы получим бесконечно убывающий вес, если при этом складывать цены начиная с самой новой.

весовые функции

Можно значительно упростить вычисления, если не учитывать вклад хвостов. Расширив размер окна на всю длину можно получить рекурсивное определение.

$ 1+q+q^2+...+q^n \underset{n\to \infty}{\underset{q < 0}{=}} \frac{1}{1-q}\\ \mathrm{EMA}_{curr} = \frac{\sum x_i q^i}{\sum q^i} = (1-q) \sum x_i q^i\\ \mathrm{EMA}_{next} = \frac{x_{next} +q \cdot \sum x_i q^i}{1 + q \cdot \sum q^i} = (1-q) \cdot \left[x_{next}+q \cdot \sum x_i q^i\right]\\ \mathrm{EMA}_{next} = (1-q) \cdot x_{next} + q) \cdot \mathrm{EMA}_{curr}$


В итоге нам нужно выбрать какое то значение $\alpha=1-q$ как константу сглаживания. Можно показать, что если взять $\alpha = 2 / (N+ 1)$ центр масс у весовых графиков EMA и SMA выше становится одинаковым. В коде все это выглядит намного проще.

function ema($close, window, weight = null) {
  weight = weight ? weight : 2 / (window + 1);
  let ema = [ mean($close.slice(0, window)) ];
  for (let i = 1; i < $close.length; i++) {
    ema.push($close[i] * weight + ema[i - 1] * (1 - weight));
  };
  return ema;
}

В целом эта та же скользящая средняя, но более чувствительная.

Экспоненциально взвешенная скользящая средняя (EMA)

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

Cхождение/расхождение скользящих средних (MACD)

Джеральд Аппель в 1979 году придумал один из самых простых и в то же время эффективных осцилляторов ценовых моментов. Он преобразует два трендовых индикатора EMA в индикатор моментов, беря из двух миров лучшее. То есть он, грубо говоря, находит производную. Рисуется он в отдельном окне двумя линиями и гистограммой, а не наложением, как предыдущие. На самом деле индикаторов которые рисуются в отдельном окне значительно больше, но об этом может быть как нибудь в другой раз.

Cхождение/расхождение скользящих средних (MACD)

Формула расчета довольно простая, берутся две ema с динным и коротким окном, например в 26 и 12 единицы, и вычитаются, полученная линия и будет искомым индикатором. Взяв от этой разности еще одну ema c шагом в 3 единицы получим сигнальную линию. Гистограмма, которую Джеральд добавил позже высчитывается разницей между двумя предыдущими результатами и по сути является средневзвешенной производной.

function macd($close, wshort, wlong, wsig) {
  let line = pointwise((a, b) => a - b, ema($close, wshort), ema($close, wlong));
  let signal = ema(line, wsig);
  let hist = pointwise((a, b) => a - b, line, signal);
  return { line : line, signal : signal, hist : hist };
}

Тестирование индикаторов, нормированная среднеквадратичная ошибка

Имея точные таблицы со значением индикаторов, можно качественно протестировать ваш расчет. Существуют различные способы определения меры ошибки между двумя функциями, но практика показала что нормированная среднеквадратичная ошибка, которая считается как

$\mathrm{NRMSE} = \left. \sqrt{\frac{\sum(\hat x_i - x_i)^2} {N}} \middle/ (\max{x_i} - \min{x_i}) \right.$


лучше всего работает, как при малых величинах, так и при больших. Например биткоин в долларах может стоить 20000$ и разница в 10$ не критична, в то же время один альткоин может исчисляться несколькими сатошами.

function nrmse(f, g) {
  let sqrDiff = pointwise((a, b) => (a - b) * (a - b), f, g);
  return Math.sqrt(mean(sqrDiff)) / (Math.max(...f) - Math.min(...f));
}

Заключение

Так в несколько строчек можно выразить базовые индикаторы, если вы планируете выполнять их анализ машинным обучением, то для определения идеальных точек входа советую обратить внимания на индикатор ZigZag, который не является полезным для торговли, но исключительно полезен в качестве учителя. Следует так же учитывать, что вам для торговли нужно выбирать максимально не похожие друг на друга идикаторы и пробовать изменять их входные параметры. Можно попробовать автоматически изменять их во времени, так как максимально эффективным параметрам свойственно изменятся.

Используемые источники

1. StockCharts — cписок алгоритмов с проверочными данными в таблицах
2. Cryptowatch — хорошо настроенные параметры индикаторов
3. Github — исходный код
Share post

Comments 29

    –7
    Тут проскакивала в комментах идея о запрете статей, в названии которых есть «крипто», годная идея: крипта перестала быть гиковской забавой и превратилась в лохотрон предмет интереса всякого рода мошенников. Туда же, где статьи про биржи, форекс, 1хбет, гомеопатию и жития святых. А машинное обучение в микроторговле на бирже вообще за гранью добра и зла, просто рулетка с соответствующими последствиями, хотя как игра для ума это все весело, наверное.
      +6
      В названии нет «крипто». Статья к крипто имеет отдаленное отношение, она про вычисление различных индикаторов для технического анализа. Нормальная вводная статья, кстати.
        +5
        Да, совершенно верно, статья больше о вычислениях. Стоит хаб «криптовалюты», так как ей тоже торгуют как и акциями.
          0

          По такой логике почти к каждой статье (например, про игры, процессоры и телескопы) можно добавлять тег "криптовалюты", поскольку ими тоже торгуют.

            +2
            Торгуют телескопами, тоже используя теханализ?)
        0
        превратилась в лохотрон предмет интереса всякого рода мошенников

        Какое невежество и глупости. Лохотроны были задолго до крипты. Интерес мошенников, и не только, всегда сфокусирован на том, что в тренде и о чем люди мало осведомлены.
        Достаточно почитать твиттер, посмотреть новости чтобы понять когда растет, а когда падает. И все.

          0
          Невежество? У меня есть битки и эфир, и я в курсе, как оно работает и как работают роботы на бирже. Просто это все такую оскомину набило. А мошенники активно поперли в крипту, и теперь вся движуха с ней воспринимается как бинарные опционы и скам. Вот и накипело. Простите, если ранил Ваши крипточувства.
            0

            Тогда зачем ахинею писать? Если уж накипело — валокоринчик или чего потяжелее.

        0
        Картинки проверяли все на нормальную вставку и отображение?
        А то четыре картинки просто надпись: image с иконкой картинки.
          0
          У меня отображаются. Использовал хостинг картинок radikal, так как imgur отключился что-то, а харб сам их не хранит.
        0

        Чего-то в разделе про EMA и ниже формулы сломались. Или это новый бета интерфейс хабра глючит?

          0
          Скорее всего да, в предпросмотре ломались, а так кажет.
          +1
          Сюрприз сюрприз, но в TradingView на индикаторе MACD signal line высчитывается по
          let signal = sma(line, wsig);

          а не
          let signal = ema(line, wsig);
            0
            В StockCharts и Investopedia ema.
            +7
            А никого не смущают фразы
            Полосы Боллинджера помогают определить затишье перед большим движением цены,
            или
            Эффективность использования [EMA] зависит от вашего опыта и используемых настроек.
            на рессурсе, где большинство читателей имеют хотя бы начальный уровень понимания программирования?

            Какое отношение имеет опыт к эффективности индикатора? Почему настройки преподносятся, как некая магия? По сути, сигнал любого индикатора теханализа — это лишь условие, при котором ожидаемое распределение вероятностей приращений движения цены имеет некоторые характеристики (к примеру, его матожидание > 0, что интерпретируется, как ожидание роста, или дисперсия превышает среднюю за некоторый период, что интерпретируется, как ожидание большого движения). И это все проверяемо на истории конкретного рынка, и программируемо (к слову, некоторые товарищи серьезно брались за такую проверку, и сильно разочаровывались, хотя к статье это никак не относится).
              –1
              К алготрейдингу.
                +1
                ИМХО, вообще абсолютно всё равно чему равен какой-либо индикатор и какие у него настройки. Вся их суть в том, что они работают только из-за того, что люди, пользуищися конкретным индикатором, договорились между собой, что если у индикатора X, с настройками Z, будет значение Y, то скорее всего цена финансового инструмента пойдет туда-то.
                  0
                  и не «скорее всего», а строго «50 на 50»
                    0

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

                  –1

                  Опыт имеет отношение к "эффективности использования" индикатора трейдером, так что не вижу противоречий. И да, теханализ это такая же "наука" как и астрология, тут все решает опыт шамана-астролога ;)

                  0
                  Часто возникает вопрос, а где же брать данные для построения индикаторов? Сервисы просят тысячи долларов за данные торгов одной биржи и одного инструмента, неважно крипто это или акции какой-то компании.
                    0
                    Да, исторические данные со стаканом действительно не просто достать, но все остальное обычно биржа отдает по API, причем время можно отматывать.
                      0

                      С криптой хорошо сейчас. Подключился по вебсокету (как правило, даже аккаунт биржи не нужен), и сразу нормальный поток реалтайм получаешь. На традиционных биржах это от сотен долларов до десятков тысяч долларов стоит в месяц (а иногда еще и неадекватных требований "только для членов биржи").

                        0
                        с историческими данными сложнее, нужно собрать с рейтлимитами по разным диким API через REST и где-то их хранить.
                        cassandra, hadoop, timescaledb…
                    +1
                    Красиво и просто, спасибо!
                      0
                      Пожалуйста, можете смотреть подробности в репозитории, я добавил еще парочку индикаторов недавно.
                      0
                      Спасибо, отличный вводный материал

                      Only users with full accounts can post comments. Log in, please.