Алгоритм поиска уровней поддержки и сопротивления цены в Python

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

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

Что такое поддержки и сопротивления?

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

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

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

Существует эмпирическое правило, согласно которому чем больше раз тестировался ключевой уровень (т. Е. Рынок отскакивал от него много раз), тем выше важность уровня.

Еще одно практическое правило состоит в том, что после пробития уровня сопротивления он автоматически становится уровнем поддержки. И наоборот, пробитый уровень поддержки становится уровнем сопротивления.

Уровни или области?

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

Как определить ключевые уровни

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

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

Фракталы

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

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

Автоматическое обнаружение в Python

Давайте посмотрим на пример на Python с использованием данных S&P 500. Мой блокнот можно найти на GitHub здесь: https://github.com/gianlucamalato/machinelearning/blob/master/Support_and_resistance.ipynb

Для кода всех графиков свечей я использовал часть кода, найденного здесь: https://saralgyaan.com/posts/python-candlestick-chart-matplotlib-tutorial-chapter-11/

Давайте сначала установим библиотеки yfinance и mpl_finance.

!pip install yfinance
!pip install mpl_finance

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

import pandas as pd
import numpy as np
import yfinance
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mpl_dates
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = [12, 7]
plt.rc('font', size=14)

Теперь мы можем скачать дневные данные S&P 500.

name = 'SPY'
ticker = yfinance.Ticker(name)
df = ticker.history(interval="1d",start="2020-03-15", end="2020-07-15")
df['Date'] = pd.to_datetime(df.index)
df['Date'] = df['Date'].apply(mpl_dates.date2num)
df = df.loc[:,['Date', 'Open', 'High', 'Low', 'Close']]

Давайте не будем создавать две функции, которые идентифицируют фракталы из 4 свечей.

def isSupport(df,i):
  support = df['Low'][i] < df['Low'][i-1]  and df['Low'][i] < df['Low'][i+1] and df['Low'][i+1] < df['Low'][i+2] and df['Low'][i-1] < df['Low'][i-2]
  return support
def isResistance(df,i):
  resistance = df['High'][i] > df['High'][i-1]  and df['High'][i] > df['High'][i+1] and df['High'][i+1] > df['High'][i+2] and df['High'][i-1] > df['High'][i-2]
  return resistance

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

levels = []
for i in range(2,df.shape[0]-2):
  if isSupport(df,i):
    levels.append((i,df['Low'][i]))
  elif isResistance(df,i):
    levels.append((i,df['High'][i]))

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

def plot_all():
  fig, ax = plt.subplots()
  candlestick_ohlc(ax,df.values,width=0.6, \
                   colorup='green', colordown='red', alpha=0.8)
  date_format = mpl_dates.DateFormatter('%d %b %Y')
  ax.xaxis.set_major_formatter(date_format)
  fig.autofmt_xdate()
  fig.tight_layout()
  for level in levels:
    plt.hlines(level[1],xmin=df['Date'][level[0]],\
               xmax=max(df['Date']),colors='blue')
  fig.show()

Наконец, мы можем построить результат.

Как видите, мы смогли определить основные уровни отклонения, но все же есть некоторый шум. Некоторые уровни выше других, но по сути это один и тот же уровень.

Мы можем убрать этот шум, изменив функцию, которая определяет ключевые уровни. Если уровень находится рядом с другим, он будет сброшен. Тогда мы должны решить, что означает «рядом». Мы можем сказать, что уровень находится рядом с другим, если их расстояние меньше, чем средний размер свечи на нашем графике (т.е. средняя разница между максимальной и минимальной ценами в свече). Это даст нам приблизительную оценку волатильности.

s =  np.mean(df['High'] - df['Low'])

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

def isFarFromLevel(l):
   return np.sum([abs(l-x) < s  for x in levels]) == 0

Теперь мы можем сканировать ценовую историю в поисках ключевых уровней, используя эту функцию в качестве фильтра.

levels = []
for i in range(2,df.shape[0]-2):
  if isSupport(df,i):
    l = df['Low'][i]
    if isFarFromLevel(l):
      levels.append((i,l))
  elif isResistance(df,i):
    l = df['High'][i]
    if isFarFromLevel(l):
      levels.append((i,l))

Наконец, мы можем снова все построить.

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

Выводы

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

Примечание редакторам Data Science. Хотя мы разрешаем независимым авторам публиковать статьи в соответствии с нашими правилами и рекомендациями, мы не поддерживаем вклад каждого автора. Не следует полагаться на работы автора без консультации с профессионалами. См. Подробности в наших Условиях для читателей.