Какая из этих двух полос волатильности лучше подходит для торговли? Исследование Python.

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

Я только что опубликовал новую книгу после успеха Новые технические индикаторы в Python. Он содержит более полное описание и добавление сложных торговых стратегий со страницей Github, посвященной постоянно обновляемому коду. Если вы считаете, что это вас заинтересует, не стесняйтесь перейти по приведенной ниже ссылке или если вы предпочитаете купить версию в формате PDF, вы можете связаться со мной в Linkedin.



Каналы Келтнера

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

  • Полосы Боллинджера: простая скользящая средняя с полосами, основанными на историческом стандартном отклонении.
  • Канал Кельтнера: экспоненциальная скользящая средняя с полосами, основанными на среднем истинном диапазоне.

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

  • Высокая - Низкая
  • | High - Предыдущее закрытие |
  • | Предыдущее закрытие - минимум |

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

def atr(Data, lookback, high, low, close, where):
   # TR
   for i in range(len(Data)):
     try:
       Data[i, where] = max(Data[i, high] - Data[i, low],
                            abs(Data[i, high] - Data[i - 1, close]),
                           abs(Data[i, low] - Data[i - 1, close]))
        except ValueError:
            pass
    Data[0, where] = 0    
    # ATR
    Data = ma(Data, lookback, where, where + 1)
return Data
# The MA Function required for the ATR calculation
def ma(Data, lookback, what, where):
  for i in range(len(Data)):
     try:
       Data[i, where] = (Data[i - lookback + 1:i + 1, what].mean())
            except IndexError:
                pass
    return Data

Результат вышеуказанных функций для дневных значений пары EURUSD с периодом ATR 10 можно увидеть на графике ниже:

Теперь мы рассчитываем канал Кельтнера, используя экспоненциальную скользящую среднюю с ATR цены. Вот формула:

С кодом Python для вывода канала Кельтнера:

def ema(Data, alpha, lookback, what, where):
    
    # alpha is the smoothing factor
    # window is the lookback period
    # what is the column that needs to have its average calculated
    # where is where to put the exponential moving average
    
    alpha = alpha / (lookback + 1.0)
    beta  = 1 - alpha
    
    # First value is a simple SMA
    Data = ma(Data, lookback, what, where)
    
    # Calculating first EMA
    Data[lookback + 1, where] = (Data[lookback + 1, what] * alpha) + (Data[lookback, where] * beta)
    # Calculating the rest of EMA
    for i in range(lookback + 2, len(Data)):
            try:
                Data[i, where] = (Data[i, what] * alpha) + (Data[i - 1, where] * beta)
        
            except IndexError:
                pass
    return Data
def keltner_channel(Data, ma_lookback, atr_lookback, multiplier, what, where):
    
  Data = ema(Data, 2, ma_lookback, what, where)
    
  Data = atr(Data, atr_lookback, 2, 1, 3, where + 1)
    
  Data[:, where + 2] = Data[:, where] + (Data[:, where + 1] * multiplier)
  Data[:, where + 3] = Data[:, where] - (Data[:, where + 1] * multiplier)
return Data

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

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

Кривая выше показывает количество значений в пределах ряда стандартных отклонений. Например, область, заштрихованная красным, соответствует примерно 1,33-кратному стандартному отклонению от нулевого среднего значения. Мы знаем, что при нормальном распределении данных:

  • Около 68% данных находится в пределах 1 стандартного отклонения от среднего.
  • Около 95% данных находится в пределах 2 стандартных отклонений от среднего.
  • Около 99% данных находится в пределах 3 стандартных отклонений от среднего.

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

Если вас также интересуют другие технические индикаторы и использование Python для создания стратегий, то моя книга-бестселлер по техническим индикаторам может вас заинтересовать:



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

Для расчета двух полос мы используем следующие относительно простые формулы:

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

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

def BollingerBands(Data, boll_lookback, standard_distance, what, where):
       
    # Calculating mean
    ma(Data, boll_lookback, what, where)
    
    # Calculating volatility
    volatility(Data, boll_lookback, what, where + 1)
    
    # Calculating Bands
    Data[:, where + 2] = Data[:, where] + (standard_distance *      Data[:, where + 1])
    Data[:, where + 3] = Data[:, where] - (standard_distance * Data[:, where + 1])
        
    return Data

Сравнение стратегий

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

def signal(Data, what, upper_boll, lower_boll, buy, sell):
    
  for i in range(len(Data)):
    if Data[i, what] > Data[i, upper_boll] and Data[i - 1, what] < Data[i - 1, upper_boll]:
          Data[i, sell] = -1
            
    if Data[i, what] < Data[i, lower_boll] and Data[i - 1, what] > Data[i - 1, lower_boll]:
          Data[i, buy] = 1

В приведенном выше коде показана функция, которую можно использовать для инициирования торговли на основе полос волатильности. В основном он гласит, что если текущая рыночная цена равна или ниже нижней полосы, в то время как предыдущая рыночная цена равна или выше предыдущей нижней полосы, мы инициируем длинный ордер (Buy). Кроме того, если текущая рыночная цена равна или выше верхней полосы, в то время как предыдущая рыночная цена равна или ниже предыдущей верхней полосы, мы инициируем длинный ордер (Sell).

Мы можем использовать приведенный ниже код для построения диаграммы выше, предполагая, что у нас есть массив данных OHLC, для которого мы использовали функцию Кельтнера.

plt.plot(Data[-500:, 3], color = 'black', label = EURUSD)
plt.plot(Data[-500:, 5], color = 'green', label = 'Upper Keltner Channel')
plt.plot(Data[-500:, 6], color = 'red', label = 'Lower Keltner Channel')
plt.grid()
plt.legend()

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

Теперь давайте проверим обе стратегии и сравним их друг с другом.

Ясно, что легендарные полосы Боллинджера превосходят канал Кельтнера согласно приведенному выше бэк-тесту. Условия, проверенные выше, относятся к почасовым данным с 2010 года с управлением рисками на основе ATR, где цель - 1x ATR, а стоп - 4x ATR. Этот метод управления рисками не оптимален, но, как я всегда упоминаю в своих статьях, я хотел бы дать алгоритмам немного времени, чтобы продемонстрировать свою силу. Вот почему иногда бывает высокий коэффициент попадания, но стратегия не приносит прибыли. Ниже представлен тот же бэк-тест еще на 10 основных валютных парах.

Заключение

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

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