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

The problem of using [-1] with the first bar when backtesting



  • I find there is something wrong in the QuickStart example:

     if self.dataclose[0] < self.dataclose[-1]:
    

    Actually, when the bar of the first day comes (2000-01-03), self.dataclose[-1] actually refers the bar of the last date (2000-12-28). This is unrealistic.

    I am not sure if this is actually a problem. Or there is some misunderstanding?



  • @LUS8806

    so it should add some logic before this line, the following should be works:

      def next(self):
            self.log('Close, {:.2f}'.format(self.dataclose[0]))
            # added lines
            if len(self) < 3:
                return
    
            if self.dataclose[0] < self.dataclose[-1]:
                # current close less than previous close
    
                if self.dataclose[-1] < self.dataclose[-2]:
                    # previous close less than the previous close
                          ....
    


  • @LUS8806 said in The problem of using [-1] with the first bar when backtesting:

    Actually, when the bar of the first day comes (2000-01-03), self.dataclose[-1] actually refers the bar of the last date (2000-12-28). This is unrealistic.

    How are you concluding that the previous bar, which would have been the last trading day in 1999, is now the last day in 2000? You should know that all of the data in the data file (1995-2014) is available to backtrader. So if backtrader needs to access information from the last trading day of 1999 it can. Hope that helps.



  • @run-out

    I've set the start date as the first date in the data file. Please see the code:

    import backtrader as bt
    import datetime
    
    
    class TestStrategy(bt.Strategy):
        def __init__(self):
            self.dataclose = self.datas[0].close
    
            self.order = None
    
        def next(self):
            self.log('Close, {:.2f}'.format(self.dataclose[0]))
            print({"current_date": self.datas[0].datetime.date(0),
                   "current_close": self.dataclose[0],
                   "pre_date": self.datas[0].datetime.date(-1),
                   "pre_close": self.dataclose[-1]})
    
    
    if __name__ == '__main__':
        cerebro = bt.Cerebro()
        cerebro.addstrategy(TestStrategy)
        data_path = '../backtrader/datas/orcl-1995-2014.txt'
        data = bt.feeds.YahooFinanceCSVData(
            # 数据文件路径
            dataname=data_path,
            # 开始日期
            fromdate=datetime.datetime(1995, 1, 3),
            # 结束日期
            todate=datetime.datetime(1995, 1, 10),
            reverse=False
        )
        cerebro.adddata(data)
        cerebro.broker.setcash(100000.0)
    
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        cerebro.run()
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    

    the output is:

    Starting Portfolio Value: 100000.00
    {'current_date': datetime.date(1995, 1, 3), 'current_close': 1.88, 'pre_date': datetime.date(1995, 1, 10), 'pre_close': 1.94}
    {'current_date': datetime.date(1995, 1, 4), 'current_close': 1.9, 'pre_date': datetime.date(1995, 1, 3), 'pre_close': 1.88}
    {'current_date': datetime.date(1995, 1, 5), 'current_close': 1.86, 'pre_date': datetime.date(1995, 1, 4), 'pre_close': 1.9}
    {'current_date': datetime.date(1995, 1, 6), 'current_close': 1.88, 'pre_date': datetime.date(1995, 1, 5), 'pre_close': 1.86}
    {'current_date': datetime.date(1995, 1, 9), 'current_close': 1.94, 'pre_date': datetime.date(1995, 1, 6), 'pre_close': 1.88}
    {'current_date': datetime.date(1995, 1, 10), 'current_close': 1.94, 'pre_date': datetime.date(1995, 1, 9), 'pre_close': 1.94}
    Final Portfolio Value: 100000.00
    

    Have you see this line, when i get the pre_close in the first bar, the system returns the data of last bar which is 1995-01-10

    {'current_date': datetime.date(1995, 1, 3), 'current_close': 1.88, 'pre_date': datetime.date(1995, 1, 10), 'pre_close': 1.94}
    


  • Since you are looking back to before the data starts, you need to let Backtrader know that is the case by adding in a minimum period before it starts the backtest. Insert after next()

            if len(self.dataclose) <= 1:
                return
    


  • @run-out
    Thanks a lot. I'll try.


Log in to reply
 

});