Как устроены индикаторы. Часть 4: DEMA, TEMA и полосы Боллинджера

В этой части давайте поговорим об индикаторах DEMA, TEMA и полосах Боллинджера.

Скользящие.

Уже сколько придумано скользящих, а человеческий мозг никак не успокоится, и придумывает все более изощренные способы что-либо улучшить. Я думаю, это происходит так: какой то умный трейдер торгует на основе того, чему его научили, потом понимает что этого недостаточно, начинает свои привычные индикаторы считать на непривычных данных, что бы выйти за грань «обычных трейдеров».

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

Далее трейдер идет еще дальше, и начинает думать – а ведь мой проверенный индикатор MACD работает на EMA!! А что если ему дать SMMA? А что если взять EMA, сложить с SMMA, взять корень, округлить, возвести в квадрат… Вот так и появляются новые скользящие и новые индикаторы.

DEMA

Так вот, есть такая скользящая  - D2, DEMA, Double exponential moving average, двойное (двукратное) экспоненциальное скользящее среднее. (HINT: выучите все эти термины и сможете выступать на конференциях :) ).

Фактически, берется EMA, EMA от EMA, EMA умноженная на два и их разность. Вот так:

DEMA = 2 *EMA – EMA(EMA)

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

def D2(data, period):
    ema = EMA(data, period)
    ema_ema = EMA(ema, period)
    e2 = list(map(lambda x: x*2, ema))
    
    result = []
    
    for i in range(len(data)):
        result.append(e2[i] - ema_ema[i])
    return result

Можно было бы конечно сделать компактнее, чуть ли не в одну строчку, но порой читабельность важнее выпендрёжа :)

TEMA

Вы, наверное уже догадались, что это из той же серии. Только будем брать не два массива данных а три! Больше скользящих богу скользящих!

Вот формула: TEMA = 3*EMA – 3*EMA(EMA) + EMA(EMA(EMA))

Вот код:

def T3(data, period):
    e1 = EMA(data, period)
    e2 = EMA(e1, period)

Реклама:


e3 = EMA(e2, period) e1 = list(map(lambda x: x*3, e1)) e2 = list(map(lambda x: x*3, e2)) result = [] for i in range(len(data)): result.append(e1[i] - e2[i] + e3[i]) return result

Общий смысл DEMA и TEMA – еще более увеличить вес текущего состояния, сделать скользящую более точной, убрать лаги… Как всегда, в чем эти расчеты лучше, в чем то хуже, попробуйте поработать с ними, смотрите сами.

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

Почему-то я удивился, когда узнал, что Боллинджера можно найти в Твиттере :) Я думал это что из довоенной школы, формулы от профессора университета Лиги Плюща, и всякое такое. Так вот, полосы Боллинджера строятся вокруг… Обычной средней скользящей SMA! Берется SMA с определенным периодом (обычно 20), берется стандартное отклонение (это математический термин), отклонение умножается на параметр (обычно 2), и применяется к каждой точке SMA. Прибавляется, что бы линия была выше, или вычитается, для нижней линии.

Формула записывается так:

  Middle Band = 20-day simple moving average (SMA)

  Upper Band = 20-day SMA + (20-day standard deviation of price x 2)

  Lower Band = 20-day SMA - (20-day standard deviation of price x 2)

А код выглядит так:

def BBANDS(data, ma=SMA, ma_period=20, dev_val=2):
    middle = ma(data, ma_period)

    # calculating stddev. We won't count NaN values. Also NaNs are reasons not to use statistics.stddev, numpy, etc.
    stddevs = []
    real_data_cnt = 0
    
    for i in range(len(data)):
        if math.isnan(middle[i]):
            stddevs.append(0)
            real_data_cnt += 1
            continue

        if i-real_data_cnt >= ma_period:
            avg = sum(middle[i-ma_period+1:i+1])/ma_period
            s = sum(map(lambda x: math.pow(x - avg,2), middle[i-ma_period+1:i+1]))
            stddev_avg = s/ma_period
            stddev = math.sqrt(stddev_avg)
            stddevs.append(stddev)
        else:
           stddevs.append(0) 

    upper = []
    lower = []
    for i in range(len(middle)):
        if not math.isnan(middle[i]):
            upper.append(middle[i]+stddevs[i]*dev_val)
            lower.append(middle[i]-stddevs[i]*dev_val)
        else:
            upper.append(math.nan)
            lower.append(math.nan)
    return upper, middle, lower    

Считается, что 95% свечей должны быть внутри коридора из верхней и нижней линии. Считается, что пробитие свечой верхнего или нижнего пояса предвещает разворот тренда. При пробитии верхней линии цена пойдет вниз, при пробитии нижней - вверх. Так же обращают внимание на общий тренд, и на сужение/расширение полос. Разумеется, есть еще куча примет, наблюдений и суеверий, связанных с этим индикатором, но это не ко мне.

Заключение

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

Код вы можете взять на GitHub, там все индикаторы цикла и примеры их использования. Забирайте, лайкайте, форкайте, делайте что хотите :)

Удачи вам и вашим роботам! :)

Тэги: