Выжимая лучшее из Преобразования Фишера.

Невероятное преобразование Фишера также можно «преобразовать», чтобы усилить его сигналы. В этой статье мы обсудим преобразование Фишера, а затем на его основе создадим агрегированный индекс Фишера, противоположный технический индикатор, используемый для обнаружения колебаний рынка.

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



Преобразование Фишера

Одним из столпов описательной статистики является кривая нормального распределения. Он описывает, как случайные переменные распределяются и сосредоточены вокруг центрального значения. Часто напоминает колокольчик. Говорят, что некоторые данные в мире распространяются нормально. Это означает, что их распределение симметрично: 50% данных лежат слева от среднего, а 50% данных - справа от среднего. Его среднее значение, медиана и мода также равны, как показано на кривой ниже.

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

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

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

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

Индикатор, созданный Джоном Ф. Элерсом, стремится преобразовать цену в нормальное гауссовское (нормальное) распределение. Это очень помогает в обнаружении разворотов, о чем и идет речь в статье. Шаги по созданию модифицированного преобразования Фишера в чем-то похожи на исходное преобразование Фишера. Вот как мы это делаем:

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

  • Захватите значения из первого шага между -1 и +1, используя следующую формулу нормализации:

  • Создайте условие, которое исключает -1,00 и +1,00 и преобразует их в -0,999 и + 0,999, чтобы мы не получали бесконечные значения. Это также служит для ограничения индикатора между двумя уровнями, которые мы увидим позже.
  • Примените следующую формулу к результатам последнего шага:

Теперь, когда у нас есть модифицированный индикатор преобразования Фишера, мы можем приступить к написанию кода на Python перед запуском бэк-тестов. На графике ниже показано 5-периодное модифицированное преобразование Фишера с субъективными границами -2,00 и +2,00.

def stochastic(Data, lookback, what, where):
        
    for i in range(len(Data)):
        
        try:
            Data[i, where] = (Data[i, what] - min(Data[i - lookback + 1:i + 1, 2])) / (max(Data[i - lookback + 1:i + 1, 1]) - min(Data[i - lookback + 1:i + 1, 2]))
        
        except ValueError:
            pass
    Data[:, where] = Data[:, where] * 100  
    return Data
def modified_fisher_transform(Data, lookback, what, where):
    
   Data = stochastic(Data, lookback, what, where)
   Data[:, where] = Data[:, where] / 100
   Data[:, where] = (2 * Data[:, where]) - 1
   
   for i in range(len(Data)):
       if Data[i, where] == 1:
           Data[i, where] = 0.999
       if Data[i, where] == -1:
           Data[i, where] = -0.999
           
   for i in range(len(Data)):
       
      Data[i, where + 1] = 0.5 * (np.log((1 + Data[i, where]) / (1 - Data[i, where])))  
   
   return Data
# Using the Transformation on an OHLC array with a few extra columns
my_ohlc_data = modified_fisher_transform(my_ohlc_data, 5, 3, 4)

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

Давайте сначала определим некоторые основные функции, которые упрощают манипулирование данными:

# The function to add a certain number of columns
def adder(Data, times):
    
    for i in range(1, times + 1):
    
        z = np.zeros((len(Data), 1), dtype = float)
        Data = np.append(Data, z, axis = 1)                   
    return Data
# The function to deleter a certain number of columns
def deleter(Data, index, times):
    
    for i in range(1, times + 1):
    
        Data = np.delete(Data, index, axis = 1)               
    return Data
# The function to delete a certain number of rows from the beginning
def jump(Data, jump):
    
    Data = Data[jump:, ]
    
    return Data

Агрегатный индекс Фишера

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

Мы можем попробовать диапазон между 3-периодным Фишером и 29-периодным Фишером. Это можно закодировать следующим образом:

where = 4
for i in range(3, 30):
    
    my_data = fisher_transform(my_data, i, 3, where)
    where = where + 1
my_data= adder(my_data, 1)
for i in range(len(my_data)):
    my_data[i, -1] = np.sum(my_data[i, 4:4+ 30 - 3])
    my_data[i, -1] = my_data[i, - 1] / (30 - 3)
my_data = deleter(my_data, 4, 27)  

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

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

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

upper_barrier = 2.24
lower_barrier = -2.24
def signal(Data, what, buy, sell):
    
    for i in range(len(Data)):
            
        if Data[i, what] < lower_barrier and Data[i - 1, what] > lower_barrier and Data[i - 2, what] > lower_barrier :
            Data[i, buy] = 1
            
        if Data[i, what] > upper_barrier and Data[i - 1, what] < upper_barrier and Data[i - 2, what] < upper_barrier :
            Data[i, sell] = -1    
            
    return Data

Выбор барьеров заключался в создании зоны около графического уровня 2,00. 2,24 равно сумме золотого сечения и его обратной величины. Ниже представлен результат тестирования пары EURUSD с использованием почасовых данных с 2015 года со спредом 0,5 и теоретическим соотношением риска и прибыли 0,20.

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



Заключение

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

Рыночную цену невозможно предсказать или ее очень трудно предсказать более чем в 50% случаев. Но реакцию рынка можно предсказать.

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

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