이번 글은 python을 이용하여 매매에 있어서 참고할 수 있는 보조지표를 구현해보겠습니다. 보조지표대로 매매를 해서 부자가 되면 좋겠습니다만 절대 만능이 아닙니다. 매매를 하다 보면 절대 마법공식이라는 것이 존재하지 않기 때문입니다. 하지만 의사결정하는데 있어 참고 정도만 하는 데에는 도움이 될 수 있습니다. 많이 지표들 중 가장 직관적으로 활용하기 좋은 RSI(Relative Strength Index)를 소개하고 비슷한 지표인 MFI(Money Flow Index)와 CCI(Commodity Channel Index)를 다루어보도록 하겠습니다. 지표에 대한 정말 디테일한 개념은 Reference만 남기도록 하고, 여기 글에서는 Dataframe을 부르고 나서 사용자함수로 어떻게 구현하는지 보여드릴 예정입니다.
데이터 부르기
사용할 데이터는 아래 글에서의 코드를 참고하려고 합니다.
2022.07.01 - [Programming/Crypto] - pyupbit 활용 - 암호화폐 데이터 부르기
import pickle
import pyupbit
# 이전 글에서 작성한 API의 Key들 활용
with open('./keypair/upbit_secret_key.pkl', 'rb') as k:
secret_key = pickle.load(k)
upbit = pyupbit.Upbit(secret_key['access key'], secret_key['secret key'])
# 15분봉 비트코인 데이터 부름
temp_df = pyupbit.get_ohlcv('KRW-BTC',
interval = "minute15",
count = 500,
to = '20220827 22:00:00',
period = 0.1)
15분 데이터 최근 20봉을 조회하면 다음과 같습니다.
위의 Dataframe의 close(종가)가격과 차트 상에서 8월 27일 17시 종가 가격이 같음을 알 수 있습니다.
RSI
RSI(Relative Strength Index) 개념 및 정의는 이 글을 참고하면 됩니다. 일반적으로 70이 넘으면 과매수 구간이고, 30 아래를 밑돌면 매도 국면이라고 익히 알려져 있습니다.
아래와 같이 코드를 구현합니다.
import numpy as np
import pandas as pd
def get_rsi(df, period = 14):
df["close"] = df["close"]
delta = df["close"].diff() # 종가의 차이를 계산
up, down = delta.copy(), delta.copy() # 상승분과 하락분을 따로 계산하기 위해 복사
up[up < 0] = 0 # 상승분, U
down[down > 0] = 0 # 하락분, D
_gain = up.ewm(com=(period - 1), min_periods=period).mean() # AU(U값의 평균)
_loss = down.abs().ewm(com=(period - 1), min_periods=period).mean() # DU(D값의 평균)
RS = _gain / _loss
rsi_14 = pd.Series(100 - (100 / (1 + RS)), name="RSI")
df['rsi'] = rsi_14
return df
get_rsi(temp_df).tail(20)
보통 기간(period)은 14일을 기준으로 두고 계산하기 때문에 14일을 기준으로 계산하면 아래와 같습니다.
붉은색 동그라미 값과 위의 Dataframe에서의 8월 27일 rsi 값과 같음을 알 수 있습니다.
MFI
RSI는 가격에만 초점을 맞추지만 여기에 거래량까지 반영한 모멘텀 지표로는 MFI(Money Flow Index)가 있습니다. 개념글로는 이 글을 참고 하면 됩니다. 20 아래에 하락국면, 80 이상이면 상승국면으로 이야길 하곤 합니다. 구현하는 코드는 아래와 같습니다.
def get_mfi(df, period = 14):
# 우선적으로 각 기간에 맞게 평균 가격(TP)을 구합니다.
typical_price = (df['high'] + df['low'] + df['close']) / 3 # TP
money_flow = typical_price * df['volume']
positive_flow =[]
negative_flow = []
# 반복문을 돌면서 기간별 양의 RMF, 음의 RMF를 구현합니다.
# Loop through the typical price
for i in range(1, len(typical_price)):
if typical_price[i] > typical_price[i-1]:
positive_flow.append(money_flow[i-1])
negative_flow.append(0)
elif typical_price[i] < typical_price[i-1]:
negative_flow.append(money_flow[i-1])
positive_flow.append(0)
else:
positive_flow.append(0)
negative_flow.append(0)
positive_mf = []
negative_mf = []
# 기간동안 평균 가격들의 분류가 끝난 경우, RMF 계산식을 이용해 평균 가격과 당일 거래량을 곱합니다.
# Get all of the positive money flows within the time period
for i in range(period-1, len(positive_flow)):
positive_mf.append(sum(positive_flow[i+1-period : i+1]))
# Get all of the negative money flows within the time period
for i in range(period-1, len(negative_flow)):
negative_mf.append(sum(negative_flow[i+1-period : i+1]))
# MFR을 계산합니다. 그 후 MFI를 구합니다.
mfi = list(100 * (np.array(positive_mf) / (np.array(positive_mf) + np.array(negative_mf) )))
mfi = list(np.repeat(np.nan,len(df)-len(mfi))) + mfi
df['mfi'] = mfi
return df
get_mfi(temp_df).tail(20)
CCI
CCI(Commodity Channel Index)는 주가와 이동평균의 차이를 측정하는 보조지표로써 이격을 바탕으로 과매수와 과매도를 판단합니다. CCI가 높다는 것은 이동평균의 주가보다 현재 주가가 높다는 뜻입니다. 이동평균을 바탕으로 계산하기 때문에 RSI, MFI보다 더욱 쉽게 계산을 할 수 있습니다. 개념에 대한 글은 이 글을 참고하면 될 것 같습니다. 구현하는 코드는 아래와 같습니다. 기간은 14일 대신 9일을 기본 값으로 설정하여 사용했습니다.
def get_cci(df, ndays = 9):
df['tp'] = (df['high'] + df['low'] + df['close']) / 3
df['sma'] = df['tp'].rolling(ndays).mean()
df['mad'] = df['tp'].rolling(ndays).apply(lambda x: pd.Series(x).mad())
df['cci'] = (df['tp'] - df['sma']) / (0.015 * df['mad'])
df.drop(columns=['sma','mad','tp'], inplace=True)
return df
get_cci(temp_df).tail(20)
마무리 & Reference
모든 보조지표들은 참고만 하는 것이 좋지, 한계가 반드시 존재하며 잘못된 시그널일 수 있음을 반드시 유의하셔야 합니다. 또한 코드는 구글링 하면서 직접 구현해도 좋고, 다른 사람들이 짜놓은 것을 활용하는 것이 좋습니다. 또한 설치가 까다롭지만 약 200개의 Indicator들을 활용할 수 있는 Ta-Lib라는 Library도 있는데 참고하시면 될 것 같습니다.
참고한 자료들은 다음과 같습니다.
https://m.blog.naver.com/junhyung34/221606117183
https://blog.naver.com/leeys3927/220323668238
https://github.com/mrjbq7/ta-lib
아래는 블로그 주인장의 토스 익명 후원 링크입니다. 글이 너무 너무 도움되거나 흡족스러웠다면 후원해주시면 감사하겠습니다.
'Programming > Crypto' 카테고리의 다른 글
바이낸스 암호화폐 데이터 부르기 (ccxt를 활용한 binance 암호화폐 데이터 부르기) (7) | 2022.09.06 |
---|---|
바이낸스(Binance) API Key 발급하기 (0) | 2022.09.02 |
AWS 서버에 파일 전송하기 (FTP 프로그램 활용하기) (2) | 2022.07.18 |
AWS EC2 서버 설정하기 (0) | 2022.07.17 |
pyupbit 활용 - 암호화폐 데이터 부르기 (0) | 2022.07.01 |