본문 바로가기

파이썬으로 퀀트 프로그램 만들기 project/백테스팅

[백테스팅]EMA 60 상향 돌파 시 매수

728x90

이번에 사용할 매매 알고리즘은 EMA 60일 선을 봉이 상향 돌파시 매수, 하향 돌파시 매도하는 것입니다.

s&p500의 3000일에 대한 일봉 데이터를 가지고 저의 알고리즘을 백테스팅해보겠습니다.

 

 

우선 s&p500 데이터를 다운받아 보겠습니다.

그리고 ema 60일 선을 만들어보겠습니다.

ema60일선은 talib패키지에서 제공해주는 메소드를 사용하겠습니다.

import talib
import yfinance as yf

stock_data = yf.download('^GSPC')#S&P500 데이터에 해당
count = 3000
stock_data = stock_data.tail(count)

stock_data['EMA_60'] = talib.EMA(stock_data['Close'], 60)

 

 

다음으로 stock_data에 필요한 열을 추가하겠습니다.

stock_data = stock_data[["Open","High","Low","Close","EMA_60"]]

stock_data['buy_condition'] = False
stock_data['hpr'] = 1 # 누적 수익률
stock_data['ror'] = 1 # 갖고 있는 포지션의 수익률
stock_data['buy_price'] = 0 # 평단가
stock_data['dr'] = 1 # 금일 수익률
stock_data["trading_number"] = 0 # 총 매매 횟수
stock_data["win"] = 0 # 이긴 횟수
stock_data["lose"] = 0 #  진 횟수

 

 

본견적으로 백테스팅 코드를 작성해보겠습니다.

for i in range(1,count):
    if stock_data.iloc[i-1,5] == False: # buy == false
        if stock_data.iloc[i-1,3] >= stock_data.iloc[i-1,4]: # 상향돌파 -> 매수
            stock_data.iloc[i,5] = True # 매수
            stock_data.iloc[i,8] = stock_data.iloc[i,0] # 평단가는 금일 시가
            stock_data.iloc[i,9] = stock_data.iloc[i,3]/stock_data.iloc[i,0] # 금익 수익률
            stock_data.iloc[i,7] = stock_data.iloc[i,3] / stock_data.iloc[i,8]
            stock_data.iloc[i,10] = stock_data.iloc[i-1,10] + 1 # trading_number +1
        else:
            stock_data.iloc[i,10] = stock_data.iloc[i-1,10]
            
    else: # buy == true
        if stock_data.iloc[i-1,3] <= stock_data.iloc[i-1,4]: # 하향돌파 -> 매도
            stock_data.iloc[i,5] = False # 매도
        else:
            stock_data.iloc[i,5] = True
            stock_data.iloc[i,8] = stock_data.iloc[i-1,8] # 평단가
            stock_data.iloc[i,7] = stock_data.iloc[i,3] / stock_data.iloc[i,8]
            stock_data.iloc[i,9] = stock_data.iloc[i,3] / stock_data.iloc[i-1,3] 

        stock_data.iloc[i,10] = stock_data.iloc[i-1,10]

# 금일 수익률의 누적곱 =  누적 수익률
stock_data['hpr'] = stock_data['dr'].cumprod()   

for i in range(1,count):
    if stock_data.iloc[i-1,5] == True and stock_data.iloc[i,5] == False: # 매도했을때
        if stock_data.iloc[i-1,7] > 1: # 이기면
            stock_data.iloc[i,11] = stock_data.iloc[i-1,11] + 1
            stock_data.iloc[i,12] = stock_data.iloc[i-1,12]
        elif stock_data.iloc[i-1,7] <= 1: # 지면
            stock_data.iloc[i,12] = stock_data.iloc[i-1,12] + 1
            stock_data.iloc[i,11] = stock_data.iloc[i-1,11]
    else:
        stock_data.iloc[i,11] = stock_data.iloc[i-1,11]
        stock_data.iloc[i,12] = stock_data.iloc[i-1,12]

 

 

이제 백테스팅 결과를 출력해보겠습니다.

import mpl_finance
import matplotlib.pyplot as plt


fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111)
mpl_finance.candlestick2_ohlc(ax, stock_data['Open'], stock_data['High'], stock_data['Low'], stock_data['Close'], width=0.5, colorup='r', colordown='b')
plt.plot(range(count), stock_data['EMA_60'], label="EMA", color="green")
plt.plot(range(count), stock_data['hpr']*stock_data.iloc[60,0], label = "trading", color='black')
plt.xlim(60,count)
plt.grid(True)
plt.legend()

 

 

처참한 결과네요..

누적 수익률과 승률을 살펴보겠습니다.

win_ratio=stock_data.iloc[-1,11]/stock_data.iloc[-1,10]
buy_and_hold = stock_data.iloc[-1,3]/stock_data.iloc[0,0]
hpr = stock_data.iloc[-1,6]
print("승률: ",win_ratio)
print("buy and hold: ", buy_and_hold)
print("hpr: ",hpr)

 

 

역시 처참하네요.

다음에는 더 나은 알고리즘으로 돌아오겠습니다.