рекомендации

пятница, 11 июня 2021 г.

Творческое применение паттернов в технических индикаторах с помощью Python


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

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

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

Паттерн Astral

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

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

Вот условия применения паттерна Astral.

Триггер Buy (Go long):
  • Восемь последовательных закрытий, при которых текущее закрытие ниже, чем закрытие три бара назад, и одновременно текущий минимум ниже, чем минимум пять баров назад.
  • Если какое-либо из вышеуказанных условий в любой момент не выполняется, паттерн становится недействительным.
Триггер Sell (Go short):
  • Восемь последовательных закрытий, при которых текущее закрытие выше, чем закрытие три бара назад, в то время как одновременно текущий максимум выше, чем максимум пять баров назад.
  • Если какое-либо из вышеуказанных условий в любой момент не выполняется, паттерн становится недействительным.
Что делает его паттерном Фибоначчи? Это связано с тем, что он использует только упорядоченные числа Фибоначчи для выполнения своего условия (3, 5 и 8). И что делает его временным паттерном? Он зависит от времени, так как для его выполнения требуется восемь значений.


Подробности паттерна Astral на паре EURNZD (рисунок автора).

Ниже приведен пример функции, которая выполняет необходимые действия. Вам необходимо скормить ей массив OHLC.

def astral(Data, completion, step, step_two, what, high, low, where_long, where_short):

# Timing buy signal
counter = -1for i in range(len(Data)):
if Data[i, what] < Data[i - step, what] and Data[i, low] < Data[i - step_two, low]:
Data[i, where_long] = counter
counter += -1
if counter == -completion - 1:
counter = 0
else:
continue
elif Data[i, what] >= Data[i - step, what]:
counter = -1
Data[i, where_long] = 0

# Timing sell signal
counter = 1

for i in range(len(Data)):
if Data[i, what] > Data[i - step, what] and Data[i, high] > Data[i - step_two, high]:
Data[i, where_short] = counter
counter += 1
if counter == completion + 1:
counter = 0
else:
continue
elif Data[i, what] <= Data[i - step, what]:
counter = 1
Data[i, where_short] = 0

return Data# The completion variable refers to Astral's final count
# The step variable refers to Astral's first lookback
# The step_two variable refers to Astral's second lookback
# The what variable refers to the closing price
# The high variable refers to the high price
# The low variable refers to the low price
# The where_long variable refers to where to put the buy trigger
# The where_short variable refers to where to put the sell trigger

RSI

RSI был создан Дж. Уэллсом Уайлдером в 1978 году как индикатор моментума с оптимальным периодом в 14 баров. Его значение ограничено между 0 и 100, причем 30 и 70 являются согласованными зонами перепроданности и перекупленности соответственно. RSI можно использовать с помощью 4 известных методов:
  • Зоны перепроданности и перекупленности как индикаторы возможных краткосрочных коррекций или разворотов.
  • Расхождение с ценами как показатель истощения тренда.
  • Рисование нормальных поддержек/сопротивлений на индикаторе.
  • Пересечение уровня 50 как признак меняющейся динамики.
Мы создадим следующую функцию, которая вычисляет RSI для данных OHLC:


В приведенном ниже фрагменте кода показано, как рассчитать экспоненциальную скользящую среднюю и RSI. Я представил первую функцию, потому что она используется в формуле 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
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 rsi(Data, rsi_lookback, what1, what2):

rsi_lookback = (rsi_lookback * 2) - 1 # From exponential to smoothed

# Get the difference in price from previous step
delta = []

for i in range(len(Data)):
try:
diff = Data[i, what1] - Data[i - 1, what1]
delta = np.append(delta, diff)
except IndexError:
pass

delta = np.insert(delta, 0, 0, axis = 0)
delta = delta[1:]

# Make the positive gains (up) and negative gains (down) Series
up, down = delta.copy(), delta.copy()
up[up < 0] = 0
down[down > 0] = 0

up = np.array(up)
down = np.array(down)

roll_up = up
roll_down = down

roll_up = np.reshape(roll_up, (-1, 1))
roll_down = np.reshape(roll_down, (-1, 1))

roll_up = adder(roll_up, 3)
roll_down = adder(roll_down, 3)

roll_up = ema(roll_up, 2, rsi_lookback, what2, 1)
roll_down = ema(abs(roll_down), 2, rsi_lookback, what2, 1)

# Calculate the SMA
roll_up = roll_up[rsi_lookback:, 1:2]
roll_down = roll_down[rsi_lookback:, 1:2]
Data = Data[rsi_lookback + 1:,]

# Calculate the RSI based on SMA
RS = roll_up / roll_down
RSI = (100.0 - (100.0 / (1.0 + RS)))
RSI = np.array(RSI)
RSI = np.reshape(RSI, (-1, 1))
RSI = RSI[1:,]

Data = np.concatenate((Data, RSI), axis = 1)
return Data

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

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

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

Триггер покупки:
  • Восемь последовательных значений RSI, где текущее значение ниже, чем значение три баров назад, и одновременно текущее значение ниже, чем значение пять баров назад.
  • Если какое-либо из вышеуказанных условий в любой момент не выполняется, паттерн становится недействительным.
Триггер продажи:
  • Восемь последовательных значений RSI, где текущее значение выше, чем значение три бара назад, и одновременно текущее значение выше, чем значение пять баров назад.
  • Если какое-либо из вышеуказанных условий в любой момент не выполняется, паттерн становится недействительным.

Пример паттерна Astral на RSI AUDCAD, часовой таймфрейм (рисунок автора).

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


График сигналов для указанной выше стратегии Astral-RSI на AUDCAD (рисунок автора).

Понятно, что такие сигналы не очень распространены, о чем свидетельствует приведенная ниже таблица. Обратите внимание, что период RSI, используемый ниже, равен 10. Мы снова будем использовать систему управления рисками на основе ATR со стоимостью 0,2 пункта за раунд сделки. Проверенные на исторических данных данные представляют собой часовые бары с января 2010 года, что составляет около 67 000 проанализированных баров.


Сводная таблица эффективности (рисунок автора).

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


Кривые капитала в соответствии со стратегией (рисунок автора).

Как я уже упоминал в своих предыдущих статьях, коэффициент успешности ничего не значит без соотношения риска и прибыли. В приведенной выше таблице показано, что средний коэффициент успешности составляет 78–81%. Означает ли это, что мы должны быть намного более прибыльными, чем показывают приведенные выше кривые капитала? Нет, из-за соотношения риска и прибыли. Когда я представляю систематические стратегии, я, как правило, даю им некоторое пространство для передышки и не навязываю соотношение риска и вознаграждения 2,00, скорее я использую около 0,30, что, конечно, не оптимально.


График сигналов с использованием стратегии Astral-RSI (50) на AUDCAD. Кажется, сигналов очень мало (рисунок автора).

Поскольку мы не уверены в корреляции между RSI и парами активов, мы пока не можем делать никаких выводов по этому поводу. Однако это дает нам идею:

Что, если мы применим паттерн Astral к RSI при вычислении скользящей корреляции между указанным RSI и текущими ценами? Затем, если мы получаем сигнал Astral при относительно сильной корреляции между RSI и валютной парой, у нас есть зеленый свет для открытия сделки.

Создание функции корреляции

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

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

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

В этом исследовании мы будем придерживаться меры корреляции Пирсона. Мы применим формулу в функции Python для вычисления скользящей меры корреляции с использованием ретроспективного анализа (или окна) по нашему выбору.

from scipy.stats import pearsonrdef rolling_correlation(Data, first_data, second_data, lookback, where):

for i in range(len(Data)):

try:
Data[i, where] = pearsonr(Data[i - lookback + 1:i + 1, first_data], Data[i - lookback + 1:i + 1, second_data])[0]


except ValueError:
pass

return Data

Давайте посмотрим на график ниже, показывающий график AUDCAD с RSI(10) и 50-периодной корреляцией между ними. Обратите внимание: когда корреляция равна нулю, это означает, что между двумя переменными нет никакой связи, а когда она больше 0,50, это означает, что между двумя переменными существует сильная положительная связь. Корреляция может быть отрицательной и интерпретируется таким же образом. Например, значение корреляции -0,76 означает сильную отрицательную связь между двумя переменными (когда одна растет, другая падает).


AUDCAD на первой панели, 10-периодный RSI на второй панели и 50-периодная корреляция на третьей панели (рисунок автора).

Интересно, что мы можем применять наши стратегии RSI всякий раз, когда корреляция между рыночной ценой и индикатором достаточно высока. Мы не будем тестировать стратегию корреляции Astral-RSI, потому что она будет слишком длинной, но главный вопрос: добавляет ли корреляция значимость в обнаружении паттернов на технических индикаторах? Это интересно.

Примером торговой стратегии может быть:
  • Открывать длинную позицию всякий раз, когда генерируется бычий сигнал Astral после значений RSI, в то время как текущая корреляция между активом и RSI больше 0,75.
  • Открывать короткую позицию всякий раз, когда генерируется медвежий сигнал Astral после значений RSI, в то время как текущая корреляция между активом и RSI больше 0,75.
Заключение

Паттерн Astral - это хороший индикатор, основанный на времени и точках Фибоначчи. Всегда интересно протестировать его на ценах и других индикаторах. В этой статье мы протестировали результаты на RSI, но мы можем протестировать его и на других технических индикаторах.

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

Комментариев нет:

Отправить комментарий