Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    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

    General Discussion
    2
    6
    517
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • LUS8806
      LUS8806 last edited by

      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 run-out 2 Replies Last reply Reply Quote 1
      • LUS8806
        LUS8806 @LUS8806 last edited by

        @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
                              ....
        
        1 Reply Last reply Reply Quote 0
        • run-out
          run-out @LUS8806 last edited by

          @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.

          RunBacktest.com

          LUS8806 1 Reply Last reply Reply Quote 0
          • LUS8806
            LUS8806 @run-out last edited by

            @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}
            
            1 Reply Last reply Reply Quote 1
            • run-out
              run-out last edited by

              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
              

              RunBacktest.com

              LUS8806 1 Reply Last reply Reply Quote 1
              • LUS8806
                LUS8806 @run-out last edited by

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

                1 Reply Last reply Reply Quote 0
                • 1 / 1
                • First post
                  Last post
                Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors