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/

    Rebalancing at the end of the month with timers

    General Code/Help
    2
    4
    315
    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.
    • Laurentvw
      Laurentvw last edited by

      I would like to rebalance on the last trading day of each month.

      With timers, I'm not able to achieve this with just the "monthdays" parameter, since the day isn't fixed. So I thought about using the allow parameter to provide custom rules.

      import calendar
      
      class EndOfMonth(object):
              
          def __call__(self, d):
              if d.day == calendar.monthrange(d.year, d.month)[1]:
                  return True
              return False
      

      While I'm able to get the last day of the month this way, it doesn't work as desired since the timer callback isn't called on weekends and more importantly, holidays (because my data feeds simply don't have these dates included). This results in the monthly rebalance to be ignored for certain months.

      If I could somehow know in advance that the current day is the last available day of the month, by looking at next available date in the data feed, that might work, although the data feed doesn't seem to be passed as an argument to the callback.

      Does anyone know how to approach this problem? Thanks!

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

        You may try to use the TradingCalendar class, supplied with backtrader. It has a last_monthday method that returns true if a given trading day is a last trading day of the month.

        More docs here: https://www.backtrader.com/docu/tradingcalendar/tradingcalendar/

        1 Reply Last reply Reply Quote 1
        • Laurentvw
          Laurentvw last edited by

          Thank you, that might do the trick. Although I can't quite figure out how to call the instance of the calendar inside a Strategy. Could you elaborate?

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

            I've got it working, here's some boilerplate code:

            class EndOfMonth(object):
                
                def __init__(self, cal):
                    self.cal = cal
                    
                def __call__(self, d):
            
                    if self.cal.last_monthday(d):
                        return True
                    return False
            
            class AssetAllocation(bt.Strategy):
            
                params = (
                    ('cal', None),
                )
            
                def __init__(self):
                    self.add_timer(
                        when=bt.Timer.SESSION_START,
                        allow=EndOfMonth(self.p.cal),
                    )
                    
            if __name__ == '__main__':
                # Create a cerebro entity
                cerebro = bt.Cerebro()
                
                cal = bt.TradingCalendar()
                cerebro.addcalendar(cal)
                
                # Add a strategy
                cerebro.addstrategy(AssetAllocation, cal=cal)
                
            

            Thanks again.

            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
            $(document).ready(function () { app.coldLoad(); }); }