Resample/Replay for custom (extended) Feed
I extended Pandas feed to add a volume weighted average. I'm feeding 5 seconds bars and want to resample (replay, actually), 1 minute bars along with 5 seconds. However, cerebro.resampledata() only produces OHLC columns... Where do I add custom code to for an extra column/line aggregation? I saw a hint to add another filter on top of Replayer or Resampler and I could add a dummy filter just to see if it work (and it does - it's call method does execute and gets resampled 1m bar) but I can't figure out how to add another line/column to that feed.
run-out last edited by
@alexgorbachev Can you share your code please?
vladisld last edited by
@alexgorbachev I think it was already discussed here:
@vladisld Thanks for the reference. I may give it a try to create a custom Replayer then. Resampling workaround is easy - I can just resample myself and feed as a normal feed but I can't do that to replay incomplete bars...
@vladisld: Thanks so much for your help! I spend few hours trying to find examples until you pointed me to that post.
So here is what seems to work but I have couple questions if you could confirm... See the questions in the code comments.
class PandasDataVW(PandasData): """Pandas feed with additional columns `vw` for volume weighted average.""" lines = ('vw',) params = (('vw', -1),) class _MyBar(bt.dataseries._Bar): def bstart(self, maxdate=False): super().bstart(maxdate) self.vw = float('NaN') self.vw_vol = 0 def bupdate(self, data, reopen=False): return_value = super().bupdate(data, reopen) self.vw_vol += data.vw * data.volume self.vw = self.vw_vol / self.volume if self.volume else data.vw return return_value class MyReplayer(bt.Replayer): def __init__(self, data): super().__init__(data) self.bar = _MyBar(maxdate=True) cerebro.addstrategy(TestStrat) data0 = PandasDataVW(dataname=df, timeframe=bt.TimeFrame.Seconds, compression=5) cerebro.adddata(data0, name='s5') # For some reason cloning doesn't work here - DataClone doesn't have my `vw` line # so I can recreate the feed. I assume I shouldn't add filter to the same feed directly # because I'm already using it as is. Do I do something wrong with cloning? # data1 = data0.clone() data1 = PandasDataVW(dataname=df, timeframe=bt.TimeFrame.Seconds, compression=5) data1.addfilter(MyReplayer, timeframe=bt.TimeFrame.Minutes, compression=1) cerebro.adddata(data1, name='m1') # `_doreply=True` I saw in cerebro.resampledata() along with cloning so I replicated it. # Is this required? cerebro._doreplay = True cerebro.run(preload=False)
Hope this comes useful to others.
@alexgorbachev at last ,it prove it is works,but there some thing to say,if your extend num>=2,
the extend in bstart and bupdate must be define and inplement by strict sort,it seem the backtrader recoginze them by order and not name