주식공부/파이썬 주식

stocahstic(스토캐스틱)과 RSI를 활용한 매수,매도 신호 그리기

일찍자요 2022. 12. 15. 23:46
반응형

오늘은 Stochastic 지표와 RSI를 활용한 매수,매도를 차트에 나타내보는 코드입니다.

 

각 보조지표에 대한 설명은 생략하고 넘어갑니다.

스토캐스틱은 매수세가 매도세보다 강할 때는 그 위치가 높게 형성되고, 매도세가 매수세보다 강할 때는 그 위치가 낮게 형성된다는 것을 이용한 것이고, RSI는 가격의 상승압력과 하락압력 간의 상대적인 강도를 나타내는 것으로 상승하면 과매수, 하락하면 과매도로 보게 됩니다.

 

 

먼저 주요 모듈을 불러오고 삼성전자를 대표로 하여 2019년부터 22년12월14일까지 데이터를 가져옵니다.

#importing necessary libraries
import FinanceDataReader as fdr
from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt

#fetching data for Samsung stock
df = fdr.DataReader('005930', '2019', '2022-12-14')

rs_term = 25
st_term = 3

 

그리고 RSI와 stochastic 지표를 계산하게 되는데, 다음과 같은 정의에 따라 계산됩니다.

 

위키백과

위 수식에서 Average gain 이 AU, Average loss가 AD 이고 RS = AU/AD가 됩니다.

이 공식에 따라 RSI는 다음과 같이 계산이 됩니다.

여기서 rs_term은 AU,AD를 구하기 위한 기간이 되며, 맨 처음 코드에서 정의해주었습니다.

값은 임의로 변경 하시면 됩니다.

df['RSI'] = 0.0
for i in range(rs_term, len(df)):
    up = df['Close'][i] - df['Close'][i-1] if df['Close'][i] > df['Close'][i-1] else 0
    down = df['Close'][i-1] - df['Close'][i] if df['Close'][i] < df['Close'][i-1] else 0
    avg_up = (df['RSI'][i-1] * (rs_term-1) + up) / rs_term
    avg_down = (df['RSI'][i-1] * (rs_term-1) + down) / rs_term
    rs = avg_up / avg_down
    df.loc[df.index[i], 'RSI'] = 100 - (100 / (1 + rs))

 

 

그리고 Stochastic은 아래와 같이 %K라는 값이 있는데, 

최근 N일간 고가와 저가의 차 대비 최근 종가와 N일간 저가의 차의 비율을 나타낸 것입니다.

 

 

 

이를 계산하는 코딩을 짜면 다음과 같습니다.

여기서 st_term은 N일을 나타내며, 본 코딩에서는 맨 처음 코딩에서 rs_term과 같이 세팅해주었습니다.

사용자에 따라 바꿔주시면 됩니다.

#calculating Stochastic Slow
#using %K and %D
#Source: https://www.investopedia.com/terms/s/stochasticoscillator.asp
df['Stochastic Slow'] = 0.0
for i in range(st_term, len(df)):
    high = df['High'][i-(st_term):i].max()
    low = df['Low'][i-(st_term):i].min()
    close = df['Close'][i]
    df.loc[df.index[i], 'Stochastic Slow'] = (close - low)/(high - low) * 100

 

그리고 나서 이를 그래프로 나타내줄 창을 세팅해줍니다.

#plotting the chart
plt.figure(figsize=(15, 10))
plt.title('Samsung Stock Chart')
plt.plot(df['Close'], label='Close')
# plt.plot(df['RSI'], label='RSI')
# plt.plot(df['Stochastic Slow'], label='Stochastic Slow')
plt.legend()

 

 

마지막으로 중요한 매수,매도 시그널 표시 입니다.

RSI는 30언더에서 매수, 70초과에서 매수로 설정되었고, stochastic은 20언더를 매수, 60초과를 매도로 설정하였습니다.

여기서 이 수치는 임의로 변경하여 최적화된 값을 찾으시면 됩니다.

 

본 코딩에서는 RSI와 stochastic을 섞어서 매수/매도 시그널을 표시하고자 하였으므로, 두 조건이 동시에 맞는 조건으로 설정 하였습니다.

 

그리고나서 그래프에 마킹을 해주면 아래 그래프와 같이 매수, 매도 시그널이 표시가 됩니다.

 

#finding best values for buying and selling points
#buying points
buy_points = df[(df['RSI'] < 30) & (df['Stochastic Slow'] < 20)]
#selling points
sell_points = df[(df['RSI'] > 70) & (df['Stochastic Slow'] > 60)]

#plotting the buy and sell points on the chart
plt.scatter(buy_points.index, buy_points['Close'], color='black', marker='^', label='Buy Points')
plt.scatter(sell_points.index, sell_points['Close'], color='red', marker='v', label='Sell Points')
plt.legend()
plt.show()

 

 

시그널을 보면, 나쁘진 않아 보입니다. 2020년엔 정말 비정상적으로 치솟는 바람에 매수시그널이 감히 나올 수 없는 상황이었고, 21년이후는 또 대세 하락장의 시작이 진행되다보니, 매수시그널에서도 분할매수로 대응하지 않으면 매도 시그널에서 익절하기 쉽지 않은 상황들이 보입니다. 그래도 21년은 그나마 괜찮은데 전쟁에 금리인상까지 엮인 22년에는 정말 어려워 보이네요. 

 

아무쪼록 필요하신 분들에겐 도움이 조금이나마 되셨길 바라며,

마칩니다.

 

 

 

 

※ 코드 전체 공유.

#importing necessary libraries
import FinanceDataReader as fdr
from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt

#fetching data for Samsung stock
df = fdr.DataReader('005930', '2019', '2022-12-14')

rs_term = 25
st_term = 3

#calculating RSI
#using Wilder's smoothing method
#Source: https://school.stockcharts.com/doku.php?id=technical_indicators:relative_strength_index_rsi
df['RSI'] = 0.0
for i in range(rs_term, len(df)):
    up = df['Close'][i] - df['Close'][i-1] if df['Close'][i] > df['Close'][i-1] else 0
    down = df['Close'][i-1] - df['Close'][i] if df['Close'][i] < df['Close'][i-1] else 0
    avg_up = (df['RSI'][i-1] * (rs_term-1) + up) / rs_term
    avg_down = (df['RSI'][i-1] * (rs_term-1) + down) / rs_term
    rs = avg_up / avg_down
    df.loc[df.index[i], 'RSI'] = 100 - (100 / (1 + rs))

#calculating Stochastic Slow
#using %K and %D
#Source: https://www.investopedia.com/terms/s/stochasticoscillator.asp
df['Stochastic Slow'] = 0.0
for i in range(st_term, len(df)):
    high = df['High'][i-(st_term):i].max()
    low = df['Low'][i-(st_term):i].min()
    close = df['Close'][i]
    df.loc[df.index[i], 'Stochastic Slow'] = (close - low)/(high - low) * 100

#plotting the chart
plt.figure(figsize=(15, 10))
plt.title('Samsung Stock Chart')
plt.plot(df['Close'], label='Close')
# plt.plot(df['RSI'], label='RSI')
# plt.plot(df['Stochastic Slow'], label='Stochastic Slow')
plt.legend()

#finding best values for buying and selling points
#buying points
buy_points = df[(df['RSI'] < 30) & (df['Stochastic Slow'] < 20)]
#selling points
sell_points = df[(df['RSI'] > 70) & (df['Stochastic Slow'] > 60)]

#plotting the buy and sell points on the chart
plt.scatter(buy_points.index, buy_points['Close'], color='black', marker='^', label='Buy Points')
plt.scatter(sell_points.index, sell_points['Close'], color='red', marker='v', label='Sell Points')
plt.legend()
plt.show()

 

반응형