Backtest multiple tickers at a same time
-
Hi, I'm a beginner using backtrader.
I have some data feeds (using sqlite from my local laptop), and I wanna backtest multiple tickers at a same time with a same logic.
My logic is simple. Buy stocks at a close price, Sell stocks at a open price next day.
I can run this logic when just backtest a stock.
But I have some trouble when adding tickers (two stocks)My code is here.
class OverNight(bt.Strategy):
def log(self, txt, dt=None): dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.inds = {} for i, d in enumerate(self.datas): self.inds[d] = dict() self.order = None # Issued Order (not yet executed) self.buyprice = None self.buycomm = None def next(self): for i, d in enumerate(self.datas): dt, dn = self.datetime.date(), d._name pos = self.getposition(d).size if not pos: self.buy(data=d, exectype=bt.Order.Close) else: self.close(data=d) self.buy(data=d, exectype=bt.Order.Close def notify_order(self, order): if order.status != order.Completed: return if order.status in [order.Completed]: if order.isbuy(): self.log('매수 완료 | 매수가격: %.2f, 총매매금액: %.2f, 수수료: %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm elif order.issell(): self.log('매도 완료 | 매도가격: %.2f, 총매매금액: %.2f, 수수료: %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) pass self.bar_executed = len(self) self.order = None def notify_trade(self, trade): if trade.justopened: pass if not trade.isclosed: self.log('매매 손익 | 총손익: %.2f, 순손익: %.2f, 주식수: %.2f' % (trade.pnl, trade.pnlcomm, trade.size)) self.log('총자산: %.2f' % self.broker.getvalue())
class maxRiskSizer(bt.Sizer):
'''
Returns the number of shares rounded down that can be purchased for the max risk tolerance
'''
params = (('risk', 0.03),)def __init__(self): if self.p.risk > 1 or self.p.risk < 0: raise ValueError('The risk parameter is a percentage which must be' 'entered as a float. e.g. 0.5') def _getsizing(self, comminfo, cash, data, isbuy): if isbuy == True: size = math.floor((self.broker.getvalue() * self.p.risk) / data[0]) print('현금: %s, 주식수: %s, 주가: %s' % (math.floor(cash), size, data[0])) else: size = math.floor((self.broker.getvalue() * self.p.risk) / data[0]) * -1 print('현금: %s, 주식수: %s, 주가: %s' % (math.floor(cash), size, data[0])) return size
if name == 'main':
cerebro = bt.Cerebro()# 전략 추가 cerebro.addstrategy(OverNight) # Analyzer cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta") cerebro.addanalyzer(bt.analyzers.SQN, _name="sqn") # 데이터 입력 data_path = 'E:/AutoTrading_test/DB/cmp_ohlcv.db' sql = "SELECT * FROM '{0}' WHERE day > ""20201001"" ORDER BY day ASC" con = sqlite3.connect(data_path) code_list = pd.read_sql("SELECT * FROM cmp_master", con) code_list = list(np.array(code_list['Code'].tolist())) code_list = ['A005930', 'A000660'] for code in code_list: data = pd.read_sql(sql.format(code), con, index_col='day', parse_dates=['day']) data = bt.feeds.PandasData(dataname=data, name=code) cerebro.adddata(data) startcash = 1000000 cerebro.broker.set_cash(startcash) cerebro.broker.setcommission(0.0015) cerebro.addsizer(maxRiskSizer, risk=0.7) strategies = cerebro.run() firstStrat = strategies[0] portvalue = cerebro.broker.getvalue() print('기초자산: %.2f' % startcash) print('기말자산: %.2f' % portvalue) # print the analyzers printTradeAnalysis(firstStrat.analyzers.ta.get_analysis()) printSQN(firstStrat.analyzers.sqn.get_analysis()) cerebro.plot(style='candlestick')
-
So are you saying you want to run the backtest on multiple stocks? Did you ever figure it out? I may have found something helpful a few weeks back, I will try to find it again.
-
heyy, @cwjeong did you find a way to test multiple tickers at the same time? If yes, can you Please help me with the same!
Thanks in advance.