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))
-
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
(See the docs: Sizers - Smart Stakng )
Strategy
andCerebro
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()
-
Should be (meaning it will be there as soon as possible, because it should be there in
__init__
and not after it)