차트 보조지표 중 하나인 macd, macd signal, 그리고 rsi을 추가적으로 이용하여 매매 백테스팅을 진행해 보겠습니다.
구체적인 매매 아이디어는 다음과 같습니다.
매수조건
1. macd 선이 macd singnal 상향돌파 (골든 크로스) 발생
2. rsi가 35 이하로 과매도
손익비는 1퍼센트로 하겠습니다.
한국 비트코인 5분봉 2만개 차트에서 백테스팅을 진행해보겠습니다.
#코드
본격적인 코드를 소개해드리겠습니다.
import pyupbit
access = "123abc" # 본인 값으로 변경
secret = "123abc" # 본인 값으로 변경
upbit = pyupbit.Upbit(access, secret)
print(upbit.get_balance("KRW-BTC")) # KRW-BTC 조회
print(upbit.get_balance("KRW")) # 보유 현금 조회
pyupbit 라이브러리를 이용하기 위한 access 값과 secret값을 입력해 줍니다.
get_balance를 통해 잘 로그인 되었는지 확인합니다.
import talib
count = 20000
df = pyupbit.get_ohlcv("KRW-BTC", interval='minute5',count = count)
df = df[["open","high","low","close"]]
df['RSI'] = talib.RSI(df['close'], timeperiod=14)
df['macd'],df['macd_signal'], macd_hist = talib.MACD(df["close"], fastperiod=12, slowperiod=26, signalperiod=9)
tf = 0.0005 #trading fee
df['buy_condition'] = False
df['hpr'] = 1 # 누적 수익률
df['ror'] = 1
df['buy_price'] = 0 # 평단가
df['dr'] = 1 # 금일 수익률
df["trading_number"] = 0
df["win"] = 0
df["lose"] = 0
비트코인 5분봉 데이터 2만개를 받아줍니다.
그리고 talib 라이브러리를 통해 rsi, macd, macd_signal 열들을 만들어줍니다.
그리고 매매 수수료를 0.05%로 설정해주고, 필요한 열들을 추가해줍니다.
golden_cross = False
#손익비
stop_profit = 0.01
stop_loss = 0.01
#과매도
over_sell = 35
for i in range(1,count):
if df.iloc[i-1,7] == False:
# macd 골든 크로스 발생
if df.iloc[i-1,5] < df.iloc[i-1,6] and df.iloc[i,5] > df.iloc[i,6]:
golden_cross = True
elif df.iloc[i-1,5] > df.iloc[i-1,6] and df.iloc[i,5] < df.iloc[i,6]:
golden_cross = False
# macd 골든 크로스, 과매도 -> 매수
if golden_cross == True and (df.iloc[i,4] < over_sell or df.iloc[i-1,4] < over_sell or df.iloc[i-2,4] < over_sell or df.iloc[i-3,4] < over_sell or df.iloc[i-2,4] < over_sell):
df.iloc[i,7] = True # buy condition
df.iloc[i,11] = 1 # dr
df.iloc[i,9] = 1 # ror
df.iloc[i,10] = df.iloc[i,3] # buy price
df.iloc[i,12] = df.iloc[i-1,12] + 1 # trading_number + 1
golden_cross = False
else:
df.iloc[i,12] = df.iloc[i-1,12] # trading_number
else: #df.iloc[i-1,7] == True
#익절
if df.iloc[i,1] >= df.iloc[i-1,10]*(1+stop_profit):
df.iloc[i,7] = False # buy condition
df.iloc[i,11] = df.iloc[i-1,10]*(1+stop_profit)/df.iloc[i-1,3]#dr
df.iloc[i,9] = df.iloc[i-1,9]*df.iloc[i,11] # ror
#손절
elif df.iloc[i,2] <= df.iloc[i-1,10]*(1-stop_loss):
df.iloc[i,7] = False # buy condition
df.iloc[i,11] = df.iloc[i-1,10]*(1-stop_loss)/df.iloc[i-1,3]# dr
df.iloc[i,9] = df.iloc[i-1,9]*df.iloc[i,11]# ror
else:
df.iloc[i,7] = df.iloc[i-1,7]
df.iloc[i,10] = df.iloc[i-1,10]
df.iloc[i,11] = df.iloc[i,3]/df.iloc[i-1,3]# dr
df.iloc[i,9] = df.iloc[i-1,9]*df.iloc[i,11]# ror
df.iloc[i,12] = df.iloc[i-1,12]
df['hpr'] = df['dr'].cumprod()
for i in range(1,count):
if df.iloc[i-1,7] == True and df.iloc[i,7] == False: # 매도했을때
if df.iloc[i,9] > 1: # 이기면
df.iloc[i,13] = df.iloc[i-1,13] + 1
df.iloc[i,14] = df.iloc[i-1,14]
elif df.iloc[i,9] <= 1: # 지면
df.iloc[i,14] = df.iloc[i-1,14] + 1
df.iloc[i,13] = df.iloc[i-1,13]
else:
df.iloc[i,13] = df.iloc[i-1,13]
df.iloc[i,14] = df.iloc[i-1,14]
본격적인 백테스트 코드입니다.
위에서 설명드린 매매 조건을 가지고 매매를 진행합니다.
결과를 띄워봅시다.
import matplotlib.pyplot as plt
from matplotlib import gridspec
fig = plt.subplots(figsize=(18,15), sharex = True)#sharex를 통해 두그림의 x축을 공유함
gs = gridspec.GridSpec(nrows=3, ncols=1, height_ratios=[3,1,1])#gridspec을 통해 여러 축들을 원하는 대로 배치 가능
#주가, 수익률 나타내기
ax1 = plt.subplot(gs[0])
ax1.plot(df.index, df['hpr']*df.iloc[100,0], color='black', label="trading") # 수익률
ax1 = df['close'].plot(label="index", alpha = 0.5) # 주가
plt.legend()
#RSI 나타내기
ax2 = plt.subplot(gs[1])
ax2 = df['RSI'].plot(color='brown')
ax2.hlines(70,df.index[0],df.index[-1], color= 'black')
ax2.hlines(35,df.index[0],df.index[-1], color= 'black')
#MACD
ax3 = plt.subplot(gs[2])
ax3 = df['macd'].plot(color='red')
ax3 = df['macd_signal'].plot(color='blue')
plt.grid(True)
plt.subplots_adjust(wspace=0, hspace=0)
맨윗칸에서 하늘색 그래프는 비트코인 차트이고, 검은 색 선은 누적 수익률입니다. 결과가 좋지 못하네요
두번째 칸은 rsi를 뜻하고, 세번째 칸은 macd와 macd signal을 보여줍니다.
구체적인 승률을 확인하고 buy&hold 와 누적수익률을 비교해봅시다.
win_ratio=df.iloc[-1,13]/df.iloc[-1,12]
buy_and_hold = df.iloc[-1,3]/df.iloc[0,0]
hpr = df.iloc[-1,8]
print("win: ",df.iloc[-1,13]," / lose: ", df.iloc[-1,14], sep="")
print("승률: ",win_ratio)
print("buy and hold: ", buy_and_hold)
print("hpr: ",hpr)
win: 38 / lose: 40
승률: 0.48717948717948717
buy and hold: 1.1675775951488072
hpr: 0.9763825018421127
확실히 결과가 아쉽게 나왔네요.
#소감
백테스팅 코드에서 macd골든크로스를 체크하는 방법이 아쉬웠던것같아요
한번 골든 크로스 되면 며칠이 지나도 계속 골든크로스가 되어있다고 체크되어 있어서 좋은 알고리즘이 되지 못한것 같네요
승률은 반반이었고 수익률은 buy and hold에 못미치는게 아쉬울 따름입니다.
'파이썬으로 퀀트 프로그램 만들기 project > 백테스팅' 카테고리의 다른 글
[백테스팅]MACD와 RSI를 이용한 선물 매매하기 (2) | 2024.02.06 |
---|---|
[백테스팅] 하이킨아시 캔들 이용하여 매매하기 (2) | 2024.02.03 |
[벡테스팅]볼린저 밴드를 이용한 백테스팅 (0) | 2023.11.13 |
[백테스팅]EMA 골든 크로스를 응용한 비중 투자 (0) | 2023.11.12 |
[백테스팅]EMA 60 상향 돌파 시 매수 (0) | 2023.11.10 |