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

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

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

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



Сигналы моментума: индекс относительной силы

Первая часть стратегии будет иметь дело с импульсом и представлена ​​известным индексом относительной силы. Сигналы сначала генерируются этим индикатором.

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

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

RSI рассчитывается довольно простым способом. Сначала мы берем разницу в ценах за один период. Это означает, что мы должны вычесть каждую цену закрытия из предыдущей. Затем мы вычислим сглаженное среднее положительных разностей и разделим его на сглаженное среднее отрицательных разностей. Последний расчет дает нам относительную силу, которая затем используется в формуле RSI для преобразования в меру от 0 до 100.

Сигналы волатильности: индекс относительной волатильности

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

Первая часть создания RVI - это расчет стандартного отклонения за определенный период. Для этого мы можем использовать приведенный ниже код в массиве данных OHLC:

my_ohlc_array = volatility(my_ohlc_array, 14, 3, 4)
# We are saying that we want to apply the volatility function seen above onto our OHLC array using a lookback period of 14 and applying the calculation on the closing price (hence, the fourth column which is indexed at 3). Then, we want to output the result in the fifth empty column which is indexed at 4

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

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

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

for i in range(len(my_ohlc_array)):
        
   if my_ohlc_array[i, std_col] > my_ohlc_array[i - 1, std_col]:
            
        my_ohlc_array[i, positive_ch] = my_ohlc_array[i, std_col]
   else:
        my_ohlc_array[i, positive_ch] = 0
            
for i in range(len(my_ohlc_array)):
        
   if my_ohlc_array[i, std_col] < my_ohlc_array[i - 1, std_col]:
            
        my_ohlc_array[i, negative_ch] = my_ohlc_array[i, std_col]
  else:
        my_ohlc_array[i, negative_ch] = 0
# The variable std_col refers to the column where the Standard Deviation is stored
# The variable positive_ch refers to the Positive Change column that will be populated
# The variable negative_ch refers to the Negative Change column that will be populated

Затем мы можем рассчитать простую скользящую среднюю для столбцов «Положительное изменение» и «Отрицательное изменение». Мы также можем вычислить сглаженную скользящую среднюю вместо этого, если мы хотим точно соответствовать формуле RSI, но я предпочитаю, чтобы она время от времени оставалась простой. Вот как это сделать:

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
my_ohlc_array = ma(my_ohlc_array, lookback, positive_ch, up_ma)
my_ohlc_array = ma(my_ohlc_array, lookback, negative_ch, down_ma)
# The variable up_ma refers to where we want to store the averaged values of the positive change while the down_ma refers to where we want to store the averaged values of the negative change

Всю вышеуказанную работу можно объединить в одну функцию, определяющую индекс относительной волатильности:

def relative_volatility_index(Data, lookback, what, where):
 Data = volatility(Data, lookback, what, where)
    
    for i in range(len(Data)):
        
        if Data[i, where] > Data[i - 1, where]:
            
            Data[i, where + 1] = Data[i, where]
        else:
            Data[i, where + 1] = 0
            
    for i in range(len(Data)):
        
        if Data[i, where] < Data[i - 1, where]:
            
            Data[i, where + 2] = Data[i, where]
        else:
            Data[i, where + 2] = 0            
            
    Data = ma(Data, lookback, where + 1, where + 3)
    Data = ma(Data, lookback, where + 2, where + 4)# RVI
    
    for i in range(len(Data)):      
        Data[i, where + 5] = 100 * Data[i, where + 3] / (Data[i, where + 3] + Data[i, where + 4])
    
    return Data

Теперь мы увидим, как использовать RVI с RSI для создания торговой стратегии, основанной на сигналах от них обоих.

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



Создание и тестирование стратегии

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

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

Следовательно, наши условия в деталях будут:

  • Открывайте длинную позицию (покупайте), когда 2-периодный RSI достигает или пробивает 10, а 14-периодный RVI ниже своего нейтрального уровня 50%.
  • Открывайте короткую позицию (продавайте), когда 2-периодный RSI достигает или превышает 90, а 14-периодный RVI превышает свой уровень нейтральности 50%.
  • Используйте индикатор среднего истинного диапазона в качестве системы управления рисками.
def signal(Data, rvi_col, rsi_col, buy, sell):
    
    for i in range(len(Data)):
            
        if Data[i, rsi_col] < lower_barrier and Data[i - 1, rsi_col] > lower_barrier and Data[i - 2, rsi_col] > lower_barrier and \
            Data[i, rvi_col] < 50:
            Data[i, buy] = 1
            
        if Data[i, rsi_col] > upper_barrier and Data[i - 1, rsi_col] < upper_barrier and Data[i - 2, rsi_col] < upper_barrier and \
            Data[i, rvi_col] > 50:
            Data[i, sell] = -1

Давайте посмотрим на результаты по почасовым данным OHLC EURUSD и USDCHF с января 2010 года.

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

Заключение

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

  • Стоимость транзакции должна быть представлена ​​как можно точнее. Большинство стратегий чувствительно к транзакционным издержкам.
  • Тесты на истории должны относительно хорошо работать в разные периоды времени из-за свойства самоподобия финансовых рынков. Это также гарантирует, что вы протестируете его на исторических данных, используя различные затраты.
  • Стратегии не должны быть слишком чувствительны к изменениям своих переменных. Например, если вы используете для индикатора период ретроспективного анализа, равный 4, то использование периода ретроспективного анализа, равного 5, не должно кардинально изменить результаты.

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

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