For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See:

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]
        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 =, d._name
            pos = self.getposition(d).size
            if not pos:
      , exectype=bt.Order.Close)
      , exectype=bt.Order.Close
    def notify_order(self, order):
        if order.status != order.Completed:
        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))
            self.bar_executed = len(self)
        self.order = None
    def notify_trade(self, trade):
        if trade.justopened:
        if not trade.isclosed:
            self.log('매매 손익 | 총손익: %.2f, 순손익: %.2f, 주식수: %.2f' % (trade.pnl, trade.pnlcomm, trade.size))
            self.log('총자산: %.2f' %

    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.p.risk) / data[0])
            print('현금: %s, 주식수: %s, 주가: %s' % (math.floor(cash), size, data[0]))
            size = math.floor(( * self.p.risk) / data[0]) * -1
            print('현금: %s, 주식수: %s, 주가: %s' % (math.floor(cash), size, data[0]))
        return size

    if name == 'main':
    cerebro = bt.Cerebro()

    # 전략 추가
    # 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)
    startcash = 1000000
    cerebro.addsizer(maxRiskSizer, risk=0.7)
    strategies =
    firstStrat = strategies[0]
    portvalue =
    print('기초자산: %.2f' % startcash)
    print('기말자산: %.2f' % portvalue)
    # print the analyzers

Log in to reply