본문 바로가기
Quant Stock

파이썬 - RSI(Relative Strength Index, 상대강도지수) 차트 만들기

by quantWhale 2023. 3. 19.
반응형

안녕하세요. 지식을 공유하는 투자자 인천고래입니다.

 

오늘은 파이썬을 이용해서 RSI 보조지표를 차트에 표현하는 코드를 알아보도록 하겠습니다.

이전의 이동평균선 혹은 엔벨로프, 볼린져밴드는 주가차트와 같이 겹쳐 보이는 형태였으나

RSI는 별도의 차트 구성으로 주가와 별개로 차트를 표현해야 합니다.

아래는 코드가 실행된 결과 화면입니다.

 

1. 코드 실행 결과 화면

아래와 같은 RSI 결과물을 만들기 위해서는 다음의 항목을 사용해야 합니다.

  • 데이터 : FinanceDataReader를 사용해서 데이터 가져옵니다.
  • 차트 생성 : Matplotlib 라이브러리를 사용하여 주가 데이터와 하단에 RSI 보조지표 차트를 구현하였습니다.
  • 매개 변수 : 상단에 입력 필드와 버튼을 만듦으로 RSI의 매개변숫값을 받아서 RSI 값이 변동될 수 있도록 하였습니다.

 

핀치 줌 아웃을 하면 차트나 글자를 확대해서 보실 수 있습니다.

RSI는 종목마다 적용되는 수치를 다르게 해야 하기 때문에

기존에 사용하던 HTS와 같이 손쉽게 수치를 바꾸면서 원하는 값을 찾을 수 있도록 사용자가 매개변수 값을 입력할 수 있게 해 두었습니다. 원하시는 기간을 입력하신 후 버튼을 클릭하면 하단의 차트에 값이 반영이 되도록 되어 있습니다.

 

 

2. 파이썬으로 차트에 RSI 지표 추가하기

아래의 코드를 실행하면, 주가 데이터 차트와 RSI차트가 각각 생성됩니다.

코드는 이전에 작성한 이동평균선과 큰 차이가 없으며

2개의 차트를 만들어야 하기 때문에 subplots을 2,1로 설정하여 위, 아래에 2개의 차트가 보이도록 하였습니다.

# 2023년 3월 19일 인천고래 (상업적 이용을 금지합니다.)
# ============================================================
import FinanceDataReader as fdr
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import TextBox, Button

# RSI 계산 함수
def compute_rsi(data, window):
    delta = data.diff()
    gains = delta.where(delta > 0, 0)
    losses = -delta.where(delta < 0, 0)
    avg_gain = gains.rolling(window=window).mean()
    avg_loss = losses.rolling(window=window).mean()
    rs = avg_gain / avg_loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

# 주가 데이터 가져오기
symbol = '005930'  # 삼성전자 종목코드
df = fdr.DataReader(symbol)

# 차트 그리기
fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [3, 1]}, figsize=(10, 8))
fig.subplots_adjust(hspace=0.5)

# 종가 그래프
ax1.plot(df.index, df['Close'], label='Close', linewidth=1.0)

# RSI 그래프
default_window = 14
df['RSI'] = compute_rsi(df['Close'], default_window)
ax2.plot(df.index, df['RSI'], label='RSI', linewidth=1.0)

# 차트 설정
ax1.set_title(symbol)
ax1.set_xlabel('Date')
ax1.set_ylabel('Price')
ax1.legend(loc='upper left')

ax2.set_title('RSI')
ax2.set_xlabel('Date')
ax2.set_ylabel('RSI')
ax2.axhline(30, color='red', linestyle='--')
ax2.axhline(70, color='red', linestyle='--')
ax2.set_ylim(0, 100)

# 입력 필드 및 버튼 생성
def submit(text):
    window = int(text)
    df['RSI'] = compute_rsi(df['Close'], window)
    ax2.clear()
    ax2.plot(df.index, df['RSI'], label='RSI', linewidth=1.0)
    ax2.set_title('RSI')
    ax2.set_xlabel('Date')
    ax2.set_ylabel('RSI')
    ax2.axhline(30, color='red', linestyle='--')
    ax2.axhline(70, color='red', linestyle='--')
    ax2.set_ylim(0, 100)
    fig.canvas.draw()

box = TextBox(plt.axes([0.15, 0.93, 0.1, 0.05]), 'RSI Window', initial=str(default_window))
box.on_submit(submit)
button = Button(plt.axes([0.27, 0.93, 0.1, 0.05]), 'Apply')
button.on_clicked(lambda x: submit(box.text))

plt.show()

그리고 버튼을 클릭하면 람다함수를 사용해서 submit 함수를 호출하고 submit 함수에서 차트를 다시 생성하도록 코드를 작성하였습니다.

 

3. RSI 생성 코드에 대한 설명

아래의 함수가 RSI를 생성하는 코드입니다.

RSI 함수는 주어진 주가 데이터와 기간에 대해 RSI 지표를 계산하는 함수로 함수의 구성은 아래와 같습니다.

def compute_rsi(data, window):
    # 1. 주가 데이터의 차분(변동폭)을 구한다.
    delta = data.diff()

    # 2. 상승분과 하락분을 구한다.
    gains = delta.where(delta > 0, 0)
    losses = -delta.where(delta < 0, 0)

    # 3. 상승분과 하락분의 이동평균을 구한다.
    avg_gain = gains.rolling(window=window).mean()
    avg_loss = losses.rolling(window=window).mean()

    # 4. 상대 강도(RS)를 계산한다.
    rs = avg_gain / avg_loss

    # 5. RSI 값을 계산한다.
    rsi = 100 - (100 / (1 + rs))

    return rsi

위의 함수를 기능별로 구분을 하자면 다음과 같은 과정을 거쳐 RSI를 계산합니다.

  • 주가 차분: data.diff()를 사용하여 주가 데이터의 차분(변동폭)을 계산합니다.

  • 상승분과 하락분: delta.where(delta > 0, 0)와 -delta.where(delta < 0, 0)를 사용하여 상승분과 하락분을 구합니다.

  • 이동평균 계산: gains.rolling(window=window).mean()과 losses.rolling(window=window).mean()를 사용하여 상승분과 하락분의 이동평균을 구합니다.

  • 상대 강도(RS) 계산: avg_gain / avg_loss를 사용하여 상대 강도(RS)를 계산합니다.

  • RSI 값 계산: 100 - (100 / (1 + rs))를 사용하여 RSI 값을 계산한 후 반환합니다.

 

 

4. 차트 확대 기능

파이썬에서 제공하는 차트의 기능 중에 돋보기 버튼을 클릭하면 차트의 일부분만 확대해서 볼 수 있는 기능이 있습니다.

이 기능을 이용하기 위해서는 subplots에서 sharex=True를 선언해 주셔야 합니다.

fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [3, 1]}, sharex=True, figsize=(10, 8))

 

아래는 실행 동영상입니다.

참고 바랍니다.

 

4. 마무리

오늘은 FinanceDataReader로 데이터를 불러오고 Matplotlib라이브러리를 이용해서 주가 차트를 만들고 RSI 보조지표 차트를 추가해 보는 코드를 작성해 봤습니다.

 

파이썬 코드로 작성한 이유는 매매를 함에 있어서 확률을 높이기 위함이고

확률을 높이기 위해서는 우선 분석하고자하는 매매기법의 기반이 되는 보조지표 또는 그 대상이 되는 지표를 코드로 만들어놔야 합니다. 관심 있으신 분들의 많은 활용 바라겠습니다.

 

오늘도 제 글을 읽어주신 모든 분들께 감사의 말씀을 드립니다.

반응형
-

댓글