Python

Как определить уровни сопротивления и поддержки, а также прорыв уровня с помощью Python

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

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

Вступление

В трейдинге уровни поддержки и сопротивления являются фундаментальным индикатором и их легко понять. По смыслу они такие как называются.

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

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

Первый вопрос заключается в том, что как мы программно находим уровни поддержки и сопротивления?

Фрактальная свеча

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

Метод сдвига окна

Еще один способ, это использование сдвига окна для определения опорных точек.

Давайте взглянем на иллюстрацию ниже. Первое, мы берем окно из 9 свечей (показано желтой рамкой) и находим максимум от свечей в окне. Затем сдвигаем окно выше свечей(зеленая рамка) и находим максимум от свечей внутри окна. Делаем то же самое 5 раз. Если свечи с наибольшим значением остаются неизменными на протяжений всех шагов, у нас есть точка разворота.

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

Реализация

Давайте начнем с первого метода определения фрактального свечного паттерна.

# Импортируем необходимые библиотеки
!pip install yfinance
!pip install mplfinance
import pandas as pd
import yfinance as yf
import numpy as np
import math
from mplfinance.original_flavor import candlestick_ohlc
import matplotlib.dates as mpl_dates
import matplotlib.pyplot as plt
# get stock prices using yfinance library
def get_stock_price(symbol):
  df = yf.download(symbol, start='2021-02-01', threads= False)
  df['Date'] = pd.to_datetime(df.index)
  df['Date'] = df['Date'].apply(mpl_dates.date2num)
  df = df.loc[:,['Date', 'Open', 'High', 'Low', 'Close']]
  return df
symbol = 'COST'
df = get_stock_price(symbol)

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

#метод 1: фрактальная свеча
# определение бычьего фрактала  
def is_support(df,i):  
  cond1 = df['Low'][i] < df['Low'][i-1]   
  cond2 = df['Low'][i] < df['Low'][i+1]   
  cond3 = df['Low'][i+1] < df['Low'][i+2]   
  cond4 = df['Low'][i-1] < df['Low'][i-2]  
  return (cond1 and cond2 and cond3 and cond4) 
# определение медвежьего фрактал 
def is_resistance(df,i):  
  cond1 = df['High'][i] > df['High'][i-1]   
  cond2 = df['High'][i] > df['High'][i+1]   
  cond3 = df['High'][i+1] > df['High'][i+2]   
  cond4 = df['High'][i-1] > df['High'][i-2]  
  return (cond1 and cond2 and cond3 and cond4)
# чтобы проверить, что область нового уровня еще не существует
def is_far_from_level(value, levels, df):    
  ave =  np.mean(df['High'] - df['Low'])    
  return np.sum([abs(value-level)<ave for _,level in levels])==0
# список для хранения уровней сопротивления и поддержки
levels = []
for i in range(2, df.shape[0] - 2):  
  if is_support(df, i):    
    low = df['Low'][i]    
    if is_far_from_level(low, levels, df):      
      levels.append((i, low))  
  elif is_resistance(df, i):    
    high = df['High'][i]    
    if is_far_from_level(high, levels, df):      
      levels.append((i, high))

Далее, мы визуализируем уровни поддержки и сопротивления используя следующую функцию.

# для визуализаций
def plot_all(levels, df):    
  fig, ax = plt.subplots(figsize=(16, 9))   
  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)    
  for level in levels:        
    plt.hlines(level[1], xmin = df['Date'][level[0]], xmax = 
      max(df['Date']), colors='blue', linestyle='--')    
  fig.show()

Запуская код выше будет выведено что-то наподобие этого.

Теперь давайте перейдем ко второму способу и посмотрим что мы получим.

#метод 2: сдвиг окна
#используется тот же символ, что и в первом примере выше
symbol = 'COST'
df = get_stock_price(symbol)
pivots = []
max_list = []
min_list = []
for i in range(5, len(df)-5):
  # берем окно из 9 свечей
  high_range = df['High'][i-5:i+4]
  current_max = high_range.max()
  # если мы найдем новое максимальное значение, очистим max_list 
  if current_max not in max_list:
    max_list = []
  max_list.append(current_max)
  # если максимальное значение остается прежним после 5-кратного сдвига
  if len(max_list)==5 and is_far_from_level(current_max,pivots,df):
      pivots.append((high_range.idxmax(), current_max))
    
  low_range = df['Low'][i-5:i+5]
  current_min = low_range.min()
  if current_min not in min_list:
    min_list = []
  min_list.append(current_min)
  if len(min_list)==5 and is_far_from_level(current_min,pivots,df):
    pivots.append((low_range.idxmin(), current_min))
plot_all(pivots, df)

Как вы можете заметить мы повторно используем функций из первого метода: is_far_from_level и plot_all. Если мы запустим код выше, мы увидим что-то наподобие этого.

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

Скрининг

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

Давайте взглянем на полный код с пояснениями.

#метод 1: фрактальная свеча
def detect_level_method_1(df):
  levels = []
  for i in range(2,df.shape[0]-2):
    if is_support(df,i):
      l = df['Low'][i]
      if is_far_from_level(l, levels, df):
        levels.append((i,l))
    elif is_resistance(df,i):
      l = df['High'][i]
      if is_far_from_level(l, levels, df):
        levels.append((i,l))
  return levels

#метод 2: сдвиг окна
def detect_level_method_2(df):
  levels = []
  max_list = []
  min_list = []
  for i in range(5, len(df)-5):
      high_range = df['High'][i-5:i+4]
      current_max = high_range.max()
      if current_max not in max_list:
          max_list = []
      max_list.append(current_max)
      if len(max_list) == 5 and is_far_from_level(current_max, levels, df):
          levels.append((high_range.idxmax(), current_max))
      
      low_range = df['Low'][i-5:i+5]
      current_min = low_range.min()
      if current_min not in min_list:
          min_list = []
      min_list.append(current_min)
      if len(min_list) == 5 and is_far_from_level(current_min, levels, df):
          levels.append((low_range.idxmin(), current_min))
  return levels

# обнаружение прорыва
def has_breakout(levels, previous, last):
  for _, level in levels:
    cond1 = (previous['Open'] < level) 
    cond2 = (last['Open'] > level) and (last['Low'] > level)
  return (cond1 and cond2)

# списки для хранения проверенных результатов
screened_list_1 = [] 
screened_list_2 = []

# получить полный список акций S&P 500 
payload=pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
stock_list = payload[0]['Symbol'].values.tolist()

# цикл по каждому символу
for symbol in stock_list:
  try: 
    df = get_stock_price(symbol)
    
    # получить уровни, используя первый метод
    levels_1 = detect_level_method_1(df)
    if (has_breakout(levels_1[-5:], df.iloc[-2], df.iloc[-1])):
      screened_list_1.append(symbol)

    # получить уровни, используя второй метод
    levels_2 = detect_level_method_2(df)
    if (has_breakout(levels_2[-5:], df.iloc[-2], df.iloc[-1])):
      screened_list_2.append(symbol)

  except Exception as e:
    print(e)
  • Линия 1-13: функция первого метода.
  • Линия 15–36: функция второго метода.
  • Линия 38–43: функция для обнаружения пробоя, когда предыдущая свеча открывается ниже линий поддержки или сопротивления. А последняя свеча открывается и закрывается ниже этого уровня.
  • Линия 45~: основная программа для проверки индекса S&P 500 на предмет линий прорыва.

Запуск этой программы в 14 Августа 2021 дал мне следующий результат.

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

Заключение

Мы успешно определили ключевые уровни сопротивления и поддержки с помощью Python и, что более важно, мы можем отслеживать акции, которые только что испытали прорыв.

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

To top