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

Indicator warmup period

  • Imagine, we want to run strategy during 2017 year using RSI(14) indicator on daily basis. Strategy should say that warmup period is 14 days.

    How to know that strategy need some data from 2016 to start trading from 1st of January 2017 before running whole trading loop.

  • administrators

    Because you want an RSI indicator with period 14 (which actually needs 15 data points to produce values)

    This is simply common sense and no magic. If you want to load the smallest possible dataset, you have to do two runs:

    • A dry run to see what the auto-calculated minimum period is

    • A run loading the data and executing your backtesting

    Even in this case you don't exactly when the original dataset has to start (date-wise) because some days may have been bank holidays. But in any case to get the auto-calculated minimum period:

    • In the start method of a strategy

    • Check the attribute: _minperiod

    Should several timeframes be in place then:

    • Check the attribute _minperiods which is a list containing the minimum period that applies to each timeframe (in the order in which the data/timeframes were inserted in the system)

  • Thanks for the information about _minperiod. Seems like exceptions in dry run are needed to immediately stop first execution.

  • administrators

    @Maxim-Korobov You don't have to pass the actual data to do a dry run. Just something that let you see the _minperiod.

    Or you can call cerebro.runstop() as soon as your strategy gets started. Docs - Cerebro

  • You don't have to pass the actual data to do a dry run

    Yes, all internals of strategies are called even without passing data. But

    strategies_info =

    returns empty list when run without data. How to reach strategies data from the outside?

  • administrators

    You don't have to pass the actual data

    This doesn't mean you don't have to pass one data feed. You can pass a data feed which has no data.

    But no data, no fun.

  • Could you please provide such fake data feed?

    I tried

    class FakeFeed(btfeeds.DataBase):
        def __init__(self):
            super(FakeFeed, self).__init__()

    which crashed internally:

    class Average(PeriodN):
        for i in range(start, end):
            dst[i] = math.fsum(src[i - period + 1:i + 1]) / period

    Because of empty src.

  • administrators

    Run in the non-once mode, The runonce preprocess all indicators before the logic is run.

  • Thank you!

    With this flag it works like a charm. Code:

    import backtrader as bt
    class WarmupDetector:
    	def detect(strategies):
    		greatest_warm_up_period, strategy_name = 0, ""
    		runner = bt.Cerebro()
    		for sta in strategies:
    			runner.addstrategy(sta, silent=True)
    		stub_data = bt.DataBase()
    		sis =
    		for si in sis:
    			period = si.get_warm_up_period()
    			if period > greatest_warm_up_period:
    				greatest_warm_up_period, strategy_name = period, si.__class__.__name__
    		return greatest_warm_up_period, strategy_name
    	def detect_period(strategies):
    		return WarmupDetector.detect(strategies)[0]


    warm_up_period, warm_up_strategy_name = WarmupDetector.detect(strategies_to_add)

  • works for me with

    period = si._minperiod

    instead of

    period = si.get_warm_up_period()

Log in to reply