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/

    Don't start next() until specific date

    General Code/Help
    3
    4
    1511
    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.
    • A
      algoguy235 last edited by algoguy235

      In my strategy I'm using a 200 hour EMA, which means for different futures products that could take anywhere from 10 to 35 days of preloaded data. I have 1-minute data so it's not so simple to figure out exactly how many minute bars would be required to complete the 200-hour preload.

      Instead, I want to just load 40 extra days of data for every product, and just make sure I don't start trading until my true start date.

      I was thinking I could manipulate either start() or nextstart() to delay the strategy's 'change to adulthood'. But I couldn't figure it out.

      class strat(bt.strategy):
          params = {start_date: datetime.datetime(1,1,1)}
          def __init__(self): 
              pass
          def next(self):
              if self.data0.datetime.datetime() < self.p.start_date:
                  return
              
              #strategy
              ....
      

      This solution adds a lot of overhead to my next function, around 50% increase overall. I was hoping I could implement similar logic but instead put it into nextstart() or possibly start(). nextstart() didn't work, but this was my naive idea, to somehow overwrite the normal nextstart() functionality.

      # NOT CORRECT USE OF NEXTSTART
      class strat(bt.strategy):
          params = {start_date: datetime.datetime(1,1,1)}
          def __init__(self): 
              pass
          def nextstart(self):
              if self.data0.datetime.datetime() < self.p.start_date: 
                  return
              else: 
                  self.next()
          def next(self):
              #strategy
              ....
      

      This is functionally what I would like to do. But is there a correct way do it?

      1 Reply Last reply Reply Quote 0
      • A
        algoguy235 last edited by algoguy235

        Ok here's the best I got to far, found a way to use the behind the scenes lines calculation during init. Definitely a performance improvement, but still looking for better.

        class strat(bt.strategy):
            params = {start_date: datatime(1,1,1)}
            def __init__(self): 
                self.trade_delay = self.data0.datetime < bt.date2num(self.p.start_date)
            def next(self):
                if self.trade_delay: return
                
                #strategy ...
        
        1 Reply Last reply Reply Quote 0
        • B
          backtrader administrators last edited by

          Getting into next (adulthood) is not foreseen in terms of datetime. The requirement is that all lines objects that play a role in the Strategy (data feeds, indicators and those generated with, for example, arithmetic operations) deliver.

          As such, the only actual way is to have a guard in next itself (and not in nextstart which will be called only once by the system)

          Something along the lines of (not dissimilar to what you have tried)

          def next(self):
              if self.data.datetime.datetime(0) < self.minimum_date:
                  return
          
          1 Reply Last reply Reply Quote 1
          • B
            Batman last edited by

            I had a similar problem and resolved following way.

            First, there is a base strategy class that can verify if date is within interval:

            
                class StrategyBase(bt.Strategy):
            
                params = (
                    ('start_date', None),
                    ('end_date', None),
                    )
                
                
                def within_range(self):
                    date = self.data.datetime.datetime(0)
                    if date >= self.p.start_date and date <= self.p.end_date:
                        return True
                    else:
                        return False
            

            The methold within_range() is called in self() of derived class:

                def next(self):
                    if not self.within_range():
                        return
            

            Then I have a function to adjust the dates that will be loaded from the feed:

            
            def adjust_start_date(date, *params):
                maximum = 0
                for p in params:
                    if isinstance(p, int):
                        if p > maximum:
                            maximum = p
                # For every week there are only 5 trading days (stocks)
                days = math.ceil(maximum * 7/5)
                adjusted = date - datetime.timedelta(days = days)
                return adjusted 
            
            

            This function is used to adjust the date of the feed. So there are two start dates: one for the feed, other for the strategy:

            feed_start_date = adjust_start_date(start_date, param1, param2, param3)
            
            cerebro.adddata(bt.feeds.GenericCSVData(fromdate = feed_start_date, todate=end_date))
                
                
            cerebro.addstrategy(Strategy, 
                                    param1 = param1, 
                                    param2 = param2,
                                    param3 = param3,
                                    
                                    start_date = feed_start_date,
                                    end_date = end_date
                                    )
            
            
            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors