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/

    Timer monthday reports trading on days prior to target

    General Code/Help
    3
    7
    155
    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.
    • J
      justinng last edited by

      Trying a fairly boilerplate application of the timer, rebalancing and carrying on the 15th of every quarter. My issue is that trades are being made on the 14th and occasionally the 12th or 13th, never the 15th. What's going on here?

      class St(bt.Strategy):
          params = (
              ('topn', 10),
              ('perctarget', 0.10),
              ('timer', True),
              ('when', bt.timer.SESSION_START),
              ('monthdays', [15]),
              ('monthcarry', True),
              ('cheat', True),
      
          def __init__(self):
              self.ranks = [data: data.ranking for data in self.datas]
              self.rtop = dict()
              self.rbot = dict()
              if self.p.timer:
                  self.add_timer(
                      when=self.p.when,
                      monthdays=self.p.monthdays,
                      monthcarry=self.p.monthcarry,
                      cheat=self.p.cheat,
                      )
      
          def next(self):
              self.ranks_sorted = sorted(
                  ranks.items(),
                  key=lambda x: x[1][0],
                  reverse=True,
              )
                      
              self.rtop = dict(self.ranks_sorted[:self.topn])
              self.rbot = dict(self.ranks_sorted[self.topn:])
      
          def notify_timer(self, timer, when, *args, **kwargs):
              date = self.datetime.date()
              if date.month in [3, 6, 9, 12]:
                          
                  posdata = [d for d, pos in self.getpositions().items() if pos]
      
                  #self.rbot[d][0][1]
                  # Sell off old rank n
                  for d in (d for d in posdata if d not in self.rtop):
                      self.log('Exit {} - Rank {:.2f}'.format(d._name, self.rbot[d][0]))
                      self.order_target_percent(d, target=0.0)
      
                  for d in (d for d in posdata if d in self.rtop):
                      self.log('Rebal {} - Rank {:.2f}'.format(d._name, self.rtop[d][0]))
                      self.order_target_percent(d, target=self.p.perctarget)
                      del self.rtop[d]
      
                  for d in self.rtop:
                      self.log('Enter {} - Rank {:.2f}'.format(d._name, self.rtop[d][0]))
                      self.order_target_percent(d, target=self.p.perctarget)
      
      

      Resulting output:
      Screen Shot 2020-10-19 at 12.55.07 AM.png

      1 Reply Last reply Reply Quote 0
      • hghhgghdf dfdf
        hghhgghdf dfdf last edited by

        I'm not very experienced with timers but here's what I think might be happening:

        Since you have cheat =True, it uses the data from the previous day.

        2015-03-15 was a sunday, so it uses friday's data.
        06-15 was a monday, again using friday's data.
        09-15 was a tuesday so using monday's data..

        1 Reply Last reply Reply Quote 0
        • J
          justinng last edited by

          Unfortunately that's not it; the same trading days are reported regardless of cheat.

          1 Reply Last reply Reply Quote 0
          • vladisld
            vladisld last edited by

            Could you please share the code for your log method? It seems you are printing the date from the first data only - right ?

            1 Reply Last reply Reply Quote 1
            • J
              justinng last edited by

              The logging method is the very basic one used in the sample rebalancing article.

                  def log(self, arg):
                      print('{} {}'.format(self.datetime.date(), arg))
              
              
              1 Reply Last reply Reply Quote 0
              • vladisld
                vladisld last edited by

                Could you log the when argument to the notify_timer instead of the date reported by the first data. Will it still print the same dates ?

                as a reference, I was running the following test:

                import os
                import backtrader as bt
                
                class TestStrategy(bt.Strategy):
                    def __init__(self):
                        self.add_timer( 
                            when=bt.timer.SESSION_START, 
                            monthdays=[15], 
                            monthcarry=True, 
                            cheat=True)
                
                    def notify_timer(self, timer, when, *args, **kwargs):
                        print(f'Data time: {self.datas[0].datetime.date()}. When: {when}')
                
                def runstrat():
                    cerebro = bt.Cerebro()
                    datapath = os.path.join(
                        bt.__file__, 
                        '../../datas/yhoo-1996-2015.txt')
                    data = bt.feeds.GenericCSVData( 
                        dataname=datapath, 
                        dtformat='%Y-%m-%d')
                    cerebro.adddata(data)
                    cerebro.addstrategy(TestStrategy)
                    cerebro.run()
                
                if __name__ == '__main__':
                    runstrat()
                

                and I've got the different reported dates:

                ...
                Data time: 2015-01-15. When: 2015-01-15 00:00:00
                Data time: 2015-02-17. When: 2015-02-17 00:00:00
                Data time: 2015-03-16. When: 2015-03-16 00:00:00
                Data time: 2015-04-15. When: 2015-04-15 00:00:00
                Data time: 2015-05-15. When: 2015-05-15 00:00:00
                Data time: 2015-06-15. When: 2015-06-15 00:00:00
                Data time: 2015-07-15. When: 2015-07-15 00:00:00
                Data time: 2015-08-17. When: 2015-08-17 00:00:00
                Data time: 2015-09-15. When: 2015-09-15 00:00:00
                Data time: 2015-10-15. When: 2015-10-15 00:00:00
                Data time: 2015-11-16. When: 2015-11-16 00:00:00
                Data time: 2015-12-15. When: 2015-12-15 00:00:00
                
                1 Reply Last reply Reply Quote 0
                • J
                  justinng last edited by

                  No, both self.data[0].datetime.date() and when log correctly. Thanks.

                  Screen Shot 2020-10-26 at 10.10.08 AM.png

                  The issue was printing from self.datetime.date() - not sure why there's a discrepancy?

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