Feature Request: Allow passing of data object to Sizer



  • I find that I am searching for a way to specify the data used in the sizer depending on order of data feeds created or whether I am in live or static mode.

    Would it be possible to add a dataname parameter to the sizer class that would allow me to pass the proper data source?



  • Actually just found the magic for passing this as a parameter:

    cerebro.addsizer(lsizers.VaRContracts, percent=1, leverage=args.leverage,
                                   scaled=args.scaled, dataname=cerebro.datas[0])
    
    class VaRContracts(bt.Sizer):
        params = (('percent', 1),
                  ('leverage', 40000),
                  ('scaled', None),
                  ('reverse', False),
                  ('dataname', None))
    
        def __init__(self):
            if self.p.dataname:
                self.dataobj = self.p.dataname
    
        def _getsizing(self, comminfo, cash, data, isbuy):
            self.pchg = self.calc_pchg(self.dataobj.close.get(size=51))
    

  • administrators

    The solution above is for sure one that works. There are alternatives.

    For example, Sizer` instances have a specific attribute which was thought for such thing.

    Strategy and Cerebro instances share the same array of data feeds. With that in mind the code above could look different.

    class VaRContracts(bt.Sizer):
        params = (('percent', 1),
                  ('leverage', 40000),
                  ('scaled', None),
                  ('reverse', False),
                  ('didx', 0),
        )
    
        def __init__(self):
            self._data = self.strategy.datas[self.p.didx]
    
        def _getsizing(self, comminfo, cash, data, isbuy):
            self.pchg = self.calc_pchg(self._data.close.get(size=51))
    

    This uses an numeric index to address the array.

    Using names could make even more sense. This has the advantage that you don't need to have created the data feed before adding the sizer.

    cerebro.addsizer(lsizers.VaRContracts, percent=1, leverage=args.leverage,
                                   scaled=args.scaled, dataname='SPY')
    
    cerebro.adddata(data0, name='SPY')
    
    class VaRContracts(bt.Sizer):
        params = (('percent', 1),
                  ('leverage', 40000),
                  ('scaled', None),
                  ('reverse', False),
                  ('dataname', None),
        )
    
        def __init__(self):
            self._data = self.strategy.getdatabyname(self.p.dataname)
    
        def _getsizing(self, comminfo, cash, data, isbuy):
            self.pchg = self.calc_pchg(self._data.close.get(size=51))
    


  • Very nice. Thank you for that guidance.



  • @backtrader appears that self.strategy.getdatabyname() is not available in __init__()

    I don't see it until we hit _getsizing()


  • administrators

    Should be (meaning it will be there as soon as possible, because it should be there in __init__ and not after it)


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.