For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See:

Problem with resampling 1m data to 5m/15m

  • I have 1m OHLC data and would like to compress that into 5m and 15m data. I know Backtrader has resampling and I tried different options but I still can't get it to align correctly with my data and charts at TradingView.

    What I want to achieve:

    1m bars 17:00-17:04 (inclusive) -> 5m bar dated 17:00

    What Backtrader does by default:

    1m bars 17:01-17:05 (inclusive) -> 5m bar dated 17:05

    Obviously this gives me OHLC data that is not matching what I want so I used the boundoff=1 option. This results in correct OHLC for the 5m bars but they are dated incorrectly for my needs, like this:

    1m bars 17:00-17:04 (inclusive) -> 5m bar dated 17:04

    I tried other resampling options but perhaps I don't fully understand them and I could not get the result I want.

    Could you give me some hints if it can be achieved before I dive into the Backtrader code?

  • administrators

    You want rightedge=False. Docs - Data Resampling

    But what you probably really want is to resample your data outise of backtrader and thenn lod it, to avoid a problem with the convention.

  • @backtrader I tried that already and it does not seem to have any effect - I get the same results with either rightedge=false or true (default I guess).

    Might that be a conflict of this option with boundoff=1?

    In any case, I would prefer to avoid processing the data outside of Backtrader because I already am storing 1m bar data so no point storing 5m as well. So I'm thinking about writing a data source for Backtrader which converts this automatically or adding an option to the resampling method that outputs correct bars for my use case. If I would make it work with resampling, does it make sense to put it in a PR?

  • administrators

    There were several patches to resampling, which probably had an impact on rightedge.

    Use this code as a template to achieve your desired effect.

        rd = cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=5)
        def _new_load(self):
            ret = self._old_load()
            if ret:
                dt = self.datetime.datetime(0)
                self.datetime[0] = bt.date2num(dt - datetime.timedelta(minutes=5))
            return ret
        rd._old_load, rd._load = rd._load, _new_load.__get__(rd, rd.__class__)

  • Has there been any update to this code? I tried the suggested code and it still doesn't work.

    Basically I am trying to have resampling of 1m to 1h.
    So as an example the close of 1m at 10:59 should be the 1h close of 10:00.

    However I see that the 1m close at 10:59 becomes the 1h close of 11:00.

    How can I fix this?

  • Lexar, having a minute bar from 10:59 go back in time to generate a result at 10:00 is a good way to make a system that won't work.

  • Thanks for this solution @backtrader it works like a charm !
    I was wondering how you can pass an argument to the new_load function in order to deal with a variable minute (for dealing with multiple timeframes in a strategy).

    I looked on stack overflow and I tried this (but got this error AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute '_old_load'):

    def _new_load(self, minutes):
        ret = self._old_load()
        if ret:
            datetime = self.datetime.datetime(0)
            self.datetime[0] = bt.date2num(datetime - timedelta(minutes=minutes - 1))
        return ret
    minutes = 240
    rd = cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=minutes)
    ad, rd._load = rd._load, _new_load.__get__(rd, rd.__class__)(minutes)

    Thanks :)

Log in to reply