안녕하세요.
이번엔 백트레이더를 활용해서 여러종목을 백테스트 해보려 합니다.
여기선 여러 종목을 읽어오고 데이터를 전달하는데 초점을 맞추었습니다.
조건 : '삼성전자, SK하이닉스, 현대자동차를 일간시세 기준 RSI 40 미만 매수, 60초과 매도'
전체적인 코드의 흐름은 첫번째 백트레이더 포스트와 동일하니, 참고해주시면 되겠습니다.
백트레이더로 여러 종목 데이터를 전달하려면 여러 종목의 데이터프레임 변수가 필요합니다.
'삼성전자', 'SK하이닉스', '현대자동차' 3종목을 가져와보겠습니다.
mk = Analyzer.MarketDB()
# 종목명 기입
stocks = ['삼성전자', 'SK하이닉스', '현대자동차']
datalist = []
cerebro = bt.Cerebro()
cerebro.broker.setcash(10000000)
# 여러 종목의 데이터를 받기 위해 반복문 사용
for i in range(0, len(stocks)):
df = mk.get_daily_price(stocks[i], '2020-07-31')
df['date'] = pd.to_datetime(df['date'])
df.columns = ['code', 'datetime', 'open', 'high', 'low', 'close', 'diff', 'volume']
df.drop(['code', 'diff'], axis=1, inplace=True)
datalist.append(df)
data = bt.feeds.PandasData(dataname=datalist[i])
cerebro.adddata(data, name=stocks[i])
먼저 빈 데이터 리스트를 만들고 종목이 여러개인 만큼 for 반복문을 써서 각 종목의 데이터프레임을 불러와 편집한 후, 데이터리스트에 하나씩 추가한 다음 백트레이더에 데이터를 전달해 주는 형태입니다.
여러 종목에 대한 데이터를 전달했으니, 백테스팅 전략도 여러 데이터에 대한 것으로 바꿔줘야 합니다.
이 또한 마찬가지로 각 종목에 대한 반복문을 써서 바꿔주도록 합니다.
class MyStrategy(bt.Strategy):
def __init__(self):
self.rsi = dict()
for i, d in enumerate(self.datas): # 여러 데이터 반복
self.rsi[d] = bt.indicators.RSI_SMA(d.close, period=21)
def next(self):
for i, d in enumerate(self.datas): # 여러 데이터 반복
pos = self.getposition(d).size # 단일 데이터일 때와 다른 형태
if not pos: # no market / no orders
if self.rsi[d] < 40:
self.order = self.buy(data=d)
else:
if self.rsi[d] > 60:
self.order = self.sell(data=d)
전체 코드는 아래와 같습니다. ([1]을 참고하시면 더욱 좋습니다.)
from datetime import datetime, timedelta
import backtrader as bt
from backtrader import cerebro
from pandas.io.formats import style
import Analyzer
import pandas as pd
class MyStrategy(bt.Strategy):
def __init__(self):
self.rsi = dict()
for i, d in enumerate(self.datas):
self.rsi[d] = bt.indicators.RSI_SMA(d.close, period=21)
def next(self):
for i, d in enumerate(self.datas):
pos = self.getposition(d).size
if not pos: # no market / no orders
if self.rsi[d] < 40:
self.order = self.buy(data=d)
else:
if self.rsi[d] > 60:
self.order = self.sell(data=d)
mk = Analyzer.MarketDB()
stocks = ['삼성전자', 'SK하이닉스', '현대자동차']
datalist = []
cerebro = bt.Cerebro()
cerebro.broker.setcash(10000000)
for i in range(0, len(stocks)):
df = mk.get_daily_price(stocks[i], '2020-07-31')
df['date'] = pd.to_datetime(df['date'])
df.columns = ['code', 'datetime', 'open', 'high', 'low', 'close', 'diff', 'volume']
df.drop(['code', 'diff'], axis=1, inplace=True)
datalist.append(df)
data = bt.feeds.PandasData(dataname=datalist[i])
cerebro.adddata(data, name=stocks[i])
cerebro.addstrategy(MyStrategy)
cerebro.broker.setcommission(commission=0.0014)
cerebro.addsizer(bt.sizers.SizerFix, stake=30)
cerebro.run()
cerebro.plot(style='candlestick')
마지막으로 이를 실행해보면 아래 차트가 출력됩니다. 위에서부터 삼성전자, SK하이닉스, 현대자동차의 차트입니다.
3종목에 대한 백테스팅이 된걸 확인하실 수 있습니다.
종목명이 한글이라 깨진 현상을 확인할 수 있는데요, 이는 추후 포스팅 해보도록 하겠습니다.
참고.
[1]. https://backtest-rookies.com/2017/08/22/backtrader-multiple-data-feeds-indicators/
[2]. https://jsp-dev.tistory.com/104
'프로젝트 > [ing]_백테스팅_툴' 카테고리의 다른 글
[python] 인터넷 연결 안되있으면 컴퓨터 다시 시작하는 프로그램 (0) | 2021.10.21 |
---|---|
[투자지표] 나쁜 투자 종목을 피해보자 (1). - PER (0) | 2021.10.18 |
[python] 백트레이더(Backtrader) 로 데이터 추출 및 전략 세우기 (0) | 2021.08.22 |
[Python] 백트레이더 (Backtrader) 에서 matplotlib 오류 수정하기 (0) | 2021.08.08 |
[Python] 백트레이더(Backtrader) 로 Pandas Dataframe import 하기 (4) | 2021.08.08 |