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

How to determine if the data is being replayed in strategy?



  • Suppose I have one-minute candle data of an instrument.
    My strategy mainly works in the 5-minute candles but it also needs to make some decisions based on 1-minute candles.

    So in this case, how will I determine within next() that the current data value(say: self.data.close[0]) refers to its original 1-minute value or the resampled 5-minute ohlc data?

    From what I gathered from the docs, the len(self.data) will remain the same if the data is being sent to next() at the original(1-minute) timeframe. It will change when it receives the 5-minute(replayed) candle.

    I tried the following:

    class Test(bt.Strategy):
        def __init__(self):
            self.last_len = 1
    
        def logdata(self):
            txt = list()
            txt.append("{}".format(len(self)))
            txt.append("{}".format(self.data.datetime.datetime(0)))
            txt.append("O:{:.2f}".format(self.data.open[0]))
            txt.append("H:{:.2f}".format(self.data.high[0]))
            txt.append("L:{:.2f}".format(self.data.low[0]))
            txt.append("C:{:.2f}".format(self.data.close[0]))
            txt.append("V:{:.2f}".format(self.data.volume[0]))
            print(", ".join(txt))
    
        def next(self):
            print("*" * 10)
            self.logdata()
            if len(self.data) == self.last_len:
                print("in the one minute compression")
            else:
                print("in 5 minute data")
            print("*" * 10)
            self.last_len = len(self.data)
    
        cerebro = bt.Cerebro()
        cerebro.addstrategy(Test)
        cerebro.replaydata(data, timeframe=bt.TimeFrame.Minutes, compression=5)
        cerebro.broker.setcash(100000)
        cerebro.broker.set_shortcash(False)
        cerebro.run()
    

    I get the following output:

    1, 2018-02-28 18:30:00, O:10533.00, H:10533.50, L:10522.00, C:10522.00, V:1200369.00
    in the one minute compression
    **********
    **********
    2, 2018-02-28 18:31:00, O:10522.00, H:10525.00, L:10510.00, C:10524.00, V:3230384.00
    in 5 minute data
    **********
    **********
    2, 2018-02-28 18:32:00, O:10522.00, H:10525.00, L:10510.00, C:10520.50, V:3679580.00
    in the one minute compression
    **********
    **********
    2, 2018-02-28 18:33:00, O:10522.00, H:10527.00, L:10510.00, C:10526.50, V:4515465.00
    in the one minute compression
    **********
    **********
    2, 2018-02-28 18:34:00, O:10522.00, H:10535.00, L:10510.00, C:10531.50, V:5627619.00
    in the one minute compression
    **********
    **********
    2, 2018-02-28 18:35:00, O:10522.00, H:10535.00, L:10510.00, C:10530.00, V:6467266.00
    in the one minute compression
    **********
    **********
    3, 2018-02-28 18:36:00, O:10530.00, H:10530.00, L:10519.00, C:10524.50, V:843598.00
    in 5 minute data
    **********
    ...
    

    At 18:36, it is recognized as replayed 5-minute data according to the logic above but it is not the actual OHLC of the 5 minute timeframe but just the orignal 1-minute candle value at 18:36. I would like the resampled 5-minute candle.

    How do I make this distinction in the code?


  • administrators

    @kausality said in How to determine if the data is being replayed in strategy?:

    From what I gathered from the docs, the len(self.data) will remain the same if the data is being sent to next() at the original(1-minute) timeframe. It will change when it receives the 5-minute(replayed) candle.

    Your 5-minutes replayed bar is constantly delivered. Only the 1st tick will contain an original 1-minute bar. The other 4 ticks will mix the incoming values to replicate (replay) how the final 5-minutes bar is constructed.

    @kausality said in How to determine if the data is being replayed in strategy?:

    So in this case, how will I determine within next() that the current data value(say: self.data.close[0]) refers to its original 1-minute value or the resampled 5-minute ohlc data?

    You cannot, because you cannot also guarantee that for each replayed 5-minutes bar you have 5 underlying 1-minute bars. If your dataset is perfect and the time boundaries too, you could count the 5 ticks that each replayed bar generates.

    @kausality said in How to determine if the data is being replayed in strategy?:

    How do I make this distinction in the code?

    You cannot also when trading live, because you only know that a bar is closed because you enter the next one.

    The only feasible approach:

    • Add a 2nd resampled feed from the original data. This bar will be delivered only once when complete, before the 1st tick of the next replayed data comes in.