본문 바로가기

파이썬으로 퀀트 프로그램 만들기 project

Ta-lib를 통해 기술적 지표 계산하기 - 이동평균, RSI, 볼린저밴드

728x90

기술적 지표를 이용한 트레이딩 전략은 크게 두 가지로

'추세추종전략'과 '평균회귀전략'으로 나눌 수 있습니다.

 

추세추종 전략은 주가가 동일한 방향으로 지속될 것이라는데 배팅하고, 이동평균 등의 지표가 사용됩니다.

평균회귀 전략은 주가가 평균으로 다시 회귀하는데 배팅하며, RSI, 볼린저밴드 등의 지표가 사용됩니다.

 

각각의 기술적 지표를 계산하는 수식이 존재하기 때문에 이를 이용해 계산할 수도 있지만,

패키지를 이용하면 매우 손쉽게 기술적 지표를 계산할 수 있습니다.

기술적 지표 계산에 사용되는 대표적인 패키지는 'TA-Lib'입니다.

 

이것을 통해 150개 이상의 지표를 계산할 수 있으며, C언어로 작성되어 있기에 속도 또한 매우 빠릅니다.

그러나 TA-Lib는 다른 패키지들처럼 pip install 명령어로 설치할 수 없습니다. 

먼저 설치 방법 부터 배워보겠습니다.

 

#TA-Lib 설치

캘리포니아 대학교 어바인 캠퍼스에서 컴파일러 없이도 파이썬 라이브러리를 설치할 수 있도록 미리 컴파일된 파이썬 패키지를 제공합니다. 본인의 파이썬 버젼 및 윈도우 환경을 확인한 후 TA-Lib 설치 파일을 다운로드 해줍니다.

아나콘다 프롬프트에서 python을 입력하면 본인의 python 버젼과 pc 운영체제를 확인할 수 있습니다.

 

위의 이미지처럼 확인 하셨으면, https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib 해당 사이트에서 ta-lib에서 본인에게 맞는 ta-lib 패키지를 다운 받으시면 됩니다.

저는 python 3.9에 윈도우 64비트 이므 TA_Lib‑0.4.24‑cp39‑cp39‑win_amd64.whl 을 선택했습니다.

 

이제 다시 아나콘다 프롬프트를 킨 후 자신이 다운받은 파일 위치로 경로를 바꿔줍니다.

그리고 pip install [다운 받은 파일 이름].whl을 입력합니다.

윈도우 말고 다른 운영체제를 사용하시는 분들은 다음 사이트를 참조해주세요.

https://blog.quantinsti.com/install-ta-lib-python/

 

 

#이동평균

트랜드 지표 중 가장 대표적인 '이동평균'을 계산하는 방법을 알아보겠습니다.

 

이동평균은 정해진 기간동안 주식의 평균 가격을 의미합니다.

예를 들어 10일간의 이동평균은 최근 10일간 가격의 평균을 의미합니다.

이 기간이 길수록 장기간의 추세를 나타내며, 짧을수록 단기간의 추세를 나타냅니다.

이동평균은 현재의 추세나 추세역전, 저항 수준을 확인할 때 사용합니다.

이동평균이 상승하는 상황에서 주가가 그 위에 있다면 상승 신호로 여겨집니다.

반대로 이동평균이 하락하는 상황에서 주가가 그보다 아래에 있다면 하락 신호로 여겨집니다.

 

이동평균을 계산하는 방법은 크게 '단순이동평균''지수이동평균'이 있습니다.

단순이동평균(SMA, Simple Moving Average)는 이동평균을 계산할 때 사용되는 가장 일반적인 방법으로써,

단순히 주어진 기간 동안의 종가의 평균을 구합니다.

지수이동평균(EMA, Exoponential Moving Average)는 최근 데이터가 더욱 중요할 수 있음을 감안하여 각 데이터에 가중치를 다르게 부여한 후 평균을 구합니다.

 

이제 ta-lib패키지를 이용해 단순이동평균과 지수이동평균을 계산해보도록 하겠습니다.

 

 

#파이썬 실습 - 이동평균

우선 S&P 500 데이터의 최근 500일 데이터를 통해 단순이동평균을 계산하고 plot해보겠습니다.

import talib
import yfinance as yf

stock_data = yf.download('^GSPC')#S&P500 데이터에 해당
stock_data = stock_data.tail(500) #최근 500일

#종가를 이용한 N일 단순이동평균계산
stock_data['SMA_20'] = talib.SMA(stock_data['Close'], 20)
stock_data['SMA_60'] = talib.SMA(stock_data['Close'], 60)

stock_data[['Close', 'SMA_20', 'SMA_60']].plot()

 

 

결과 이미지

파란색 선은 S&P 500의 종가 데이터이고, 주황색은 20일, 초록색은 60일 단순이동평균선 입니다.

 

이제는 지수이동평균을 계산해보겠습니다.

이전과 똑같지만 단순이동평균은 'SMA()'를 통해 계산하고, 지수이동평균은 'EMA()'를 통해 계산합니다.

 

#지수이동평균
stock_data['EMA_60'] = talib.EMA(stock_data['Close'], 60)
stock_data[['Close', 'SMA_60', 'EMA_60']].plot(figsize=(10,6))

 

 

 

결과를 보시면, 지수이동평균이 최근일의 주가에 더 민감하게 반응하는 것을 확인할 수 있습니다.

 

 

#상대강도지수(RSI)

RSI는 일정기간동안 주가의 상승폭과 하락폭의 크기를 비교해 상승과 하락의 상대적인 강도를 나타낸 지표입니다.

크게 4단계로 계산합니다.

 

1. U(Up): 가격이 상승한 날의 상승폭

2. D(Down): 가격이 하락한 날의 하락폭

3. AU(Average Up)와 AD(Average Down): U값과 D값의 평균을 각각 구함

4. RS(Relative Strenth): AU/AD를 통해 상대강도를 구함

 

RS 값이 크다는 것은 일정기간동안 상승한 폭이 하락한 폭보다 크다는 것을 의미합니다.

RSI는 0에서 100범위 내에서 움직입니다.

일반적으로 RSI가 70 이상일 경우 과매수 구간, 30 이하이면 과매도 구간입니다.

 

 

#파이썬 실습 - RSI

#RSI
stock_data['RSI_14'] = talib.RSI(stock_data['Close'], 14) #14일 기준

 

해당 데이터를 S&P 500과 같이 plot해주겠습니다.

 

import matplotlib.pyplot as plt
from matplotlib import gridspec
fig = plt.subplots(figsize=(10,6), sharex = True)#sharex를 통해 두그림의 x축을 공유함
gs = gridspec.GridSpec(nrows=2, ncols=1, height_ratios=[2,1])#gridspec을 통해 여러 축들을 원하는 대로 배치 가능

#주가 나타내기
ax1 = plt.subplot(gs[0])
ax1 = stock_data['Close'].plot()
ax1.set_xlabel('')
ax1.axes.xaxis.set_ticks([])

#RSI 나타내기
ax2 = plt.subplot(gs[1])
ax2 = stock_data['RSI_14'].plot(color='black', ylim=[0,100])
ax2.axhline(y=70, color='r', linestyle='-')#과매수
ax2.axhline(y=30, color='r', linestyle='-')#과매도
ax2.set_xlabel
plt.subplots_adjust(wspace=0, hspace=0)

 

 

#볼린저밴드

이동평균선을 중심으로 일정 표준편차를 상한성과 하한선으로 설정한 밴드입니다.

- 중심선: n 기간동안의 이동평균

- 상단선: 중심 선 기준 k 표준편차 위

- 하단선: 중심선 기준 k 표준편차 아래

 

볼린저밴드는 주식 수익률의 움직임이 정규분포를 따른다고 가정에 기초합니다.

정규분포에서 데이터가 1 표준편차 내에 있을 확률이 약 68%, 2 표준편차 내에 있을 확률이 약 95%, 3 표준편차 내에 있을 확률이 약 99% 입니다.

만약 주식 수익률이 정규분포를 따른다면 주가는 상한선과 하한성으로 구성된 밴드 내에서만 움직일 확률이 높습니다.

따라서 주가가 상한선 위에 있다는 것은 과매수 상태이므로 하락할 가능성이, 하단선 아래에 있다는 것은 과매도 상태이므로 상승할 가능성이 높다는 것을 뜻합니다.

 

 

#파이썬 실습 - 볼린저 밴드

#볼린저 밴드
import pandas as pd

upper_2sd, mid_2sd, lower_2sd = talib.BBANDS(stock_data['Close'],
                                             nbdevup=2, #상단 2 표준편차
                                             nbdevdn=2, #하단 2 표준편차
                                             timeperiod=20) #20일 기준

#axis=1 열방향으로 합침
bb = pd.concat([upper_2sd, mid_2sd, lower_2sd, stock_data['Close']], axis=1)
bb.columns = ['Upper Band', 'Mid Band', 'Lower Band', 'Close']
bb.plot(color={
    'Upper Band': 'red',
    'Lower Band' : 'blue',
    'Mid Band': 'green',
    'Close': 'black'
})