[Python] backtrader를 이용한 주식 전략 백테스팅 시뮬레이션
Python backtrader 주식 전략 백테스팅 시뮬레이션
과거의 주식 데이터를 이용하여 내가 작성한 전략 알고리즘이 어느 정도 수익을 낼 수 있는지 테스트를 해볼 수 있는 시뮬레이션을 해보려 합니다. 특정 상황에서의 매수와 매도 등 간단하게 구현을 해도 되지만 python의 backtrader를 이용하여 간단한 백테스팅 시뮬레이션을 진행해보겠습니다.
과거의 데이터를 이용할 때 가장 주의해야할점은 시뮬레이션 결과가 아무리 좋더라도 과거는 과거일 뿐이라는 겁니다. 과거에 성과가 좋았더라도 미래에는 성공한다는 보장이 없기 때문에 과거에 전략을 너무 믿지는 마세요!
자, 그럼 가장 먼저 backtrader를 설치해야합니다.
pip install backtrader
zipline이라는 라이브러리도 있지만 해당 라이브러리는 python 3.5까지만을 지원하고 있기 때문에 최신 python을 지원하는 backtrader를 이용하겠습니다. 현재 샘플은 python 3.7 에서 테스트 되었습니다.
백테스팅 테스트 케이스
가장 간단한 예를 들기 위해 조건은 SMA5 이평선과 SMA30 이평선을 기준으로 크로스가 되었을 때 풀 매수, 풀 매도하는 전략의 백테스팅입니다.
아래의 케이스는 2019년 1월 1일 ~ 2019년 12월 31일까지의 삼성전자 주식
을 테스팅해본 결과입니다.
수익률은 아래 보이는 것처럼 좋지는 않네요 1,000,000원으로 시작해서 1년 동안 1,084,750으로 마감을 했습니다.
평균가 49,000원 기준으로 55,800원까지 약 17%가량 상승에 대비 8% 수익률이면 그렇게 나쁘지도 않네요
다른 케이스를 한번 보겠습니다.
늘 저 정도라도 이득을 보면 다행이겠지만.. 같은 조건을 두고 삼성전자의 2017.12.1일부터 ~ 2018년 12월 31일까지
의 데이터로 돌렸을 때 계좌가 조금씩 박살 나는 것을 볼 수 있습니다.. (1월 1일부터 SMA30 이동평균을 내기 위해 12월 1일부터 진행)
backtrader python code
위의 백테스팅 전략을 python code로 구현하기 위해선 위에서 얘기했던 backtrader
를 사용하도록 합니다.
backtrader 내에서 다양한 indicator를 제공하기 때문에 backtrader.ind
내에 SMA, EMA, RSI
등등 다양한 indicator들을 직접 구현하지 않고도 사용할 수 있습니다.
buy 함수에서 size를 아무값도 입력하지않으면 1개씩 매수 하게 되기때문에 전략에 따라 변경하시면 됩니다.
cerebro.broker.setcash (default : 10,000원)
: 초기 자본금을 임의로 설정할 수 있습니다.
cerebro.broker.setcommision (default : 0.0%)
: 매매 수수료를 임의로 설정할 수 있습니다.
cerebro.broker.addstrategy
: 자신만의 매매 전략을 추가할 수 있습니다.
from datetime import datetime
import backtrader as bt
class SmaCross(bt.Strategy): # bt.Strategy를 상속한 class로 생성해야 함.
params = dict(
pfast=5, # period for the fast moving average
pslow=30 # period for the slow moving average
)
def __init__(self):
sma1 = bt.ind.SMA(period=self.p.pfast) # fast moving average
sma2 = bt.ind.SMA(period=self.p.pslow) # slow moving average
self.crossover = bt.ind.CrossOver(sma1, sma2) # crossover signal
def next(self):
if not self.position: # not in the market
if self.crossover > 0: # if fast crosses slow to the upside
close = self.data.close[0] # 종가 값
size = int(self.broker.getcash() / close) # 최대 구매 가능 개수
self.buy(size=size) # 매수 size = 구매 개수 설정
elif self.crossover < 0: # in the market & cross to the downside
self.close() # 매도
cerebro = bt.Cerebro() # create a "Cerebro" engine instance
# 삼성전자의 '005930.KS' 코드를 적용하여 데이터 획득
data = bt.feeds.YahooFinanceData(dataname='005930.KS',
fromdate=datetime(2019, 1, 1),
todate=datetime(2019, 12, 31))
cerebro.adddata(data)
cerebro.broker.setcash(1000000) # 초기 자본 설정
cerebro.broker.setcommission(commission=0.00015) # 매매 수수료는 0.015% 설정
cerebro.addstrategy(SmaCross) # 자신만의 매매 전략 추가
cerebro.run() # 백테스팅 시작
cerebro.plot() # 그래프로 보여주기
코드는 주석을 달아놔서 간단하게 보시면 되며, 국내 코스닥, 코스피의 모든 종목 코드를 가져오는 방법은 지난번에 소개해드린 Pandas를 이용하여 주식 종목 코드 가져오기! 를 참조하면 됩니다.
backtrader documents
backtrader의 공식문서는 아래 페이지에서 확인 가능합니다.
https://www.backtrader.com/docu/
'⌨ DEVELOPMENT > Python' 카테고리의 다른 글
[Python] 이미지 한장으로 정리하는 Python3 기초! (3) | 2020.05.30 |
---|---|
[Python] 네이버 Finance API를 이용한 ETF 종목 가져오기 (10) | 2020.01.02 |
[Python] pandas 주식정보 이동평균(moving average) 구하기 (1) | 2019.12.29 |
[Python] pandas 주식정보로 스토캐스틱(Stochastic Oscillator) 구하기 (3) | 2019.12.28 |
[Python] pandas_datareader를 이용하여 주식 데이터 가져오기! Yahoo Finance (3) | 2019.12.26 |
[Python] Pandas를 이용하여 주식 종목 코드 가져오기! 한국 거래소 (KRX). (4) | 2019.12.26 |
Python django vs Flask. web framework 무엇을 선택해야할까? (6) | 2019.12.25 |
Google Colaboratory 소개 및 사용법 : 주피터 노트북 (jupyter notebook) (2) | 2019.12.16 |
댓글
이 글 공유하기
다른 글
-
[Python] 이미지 한장으로 정리하는 Python3 기초!
[Python] 이미지 한장으로 정리하는 Python3 기초!
2020.05.30 -
[Python] 네이버 Finance API를 이용한 ETF 종목 가져오기
[Python] 네이버 Finance API를 이용한 ETF 종목 가져오기
2020.01.02 -
[Python] pandas 주식정보 이동평균(moving average) 구하기
[Python] pandas 주식정보 이동평균(moving average) 구하기
2019.12.29 -
[Python] pandas 주식정보로 스토캐스틱(Stochastic Oscillator) 구하기
[Python] pandas 주식정보로 스토캐스틱(Stochastic Oscillator) 구하기
2019.12.28