Hi,

Attached you can find a backtest in which I use custom indicator on 3 minute data. I am getting Runtime error, but can't find the source of the problem.

I am posting the code, because I can't attach backtest with an error.

#region imports
from AlgorithmImports import *
#endregion
from datetime import timedelta

from collections import deque


class LogicalBrownKoala(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2022, 4, 1)
        # self.SetEndDate(2020, 11, 1)
        self.SetCash(100000)
        future = self.AddFuture(Futures.Energies.CrudeOilWTI, Resolution.Minute)
        future.SetFilter(timedelta(10), timedelta(180))

        # parameters
        self.slow_sma = None
        self.slow_sma_period = 25
        self.fast_sma = None
        self.fast_sma_period = 12
        self.CCIPeriod = 30 # CCI period
        self.CCIupperBound = 100 # CCI upper bound line
        self.CCIlowerBound = -100 # CCI lower bound line
        self.volume_sma_period = 30

        # init
        self.consolidator_by_symbol = {}
        
    def OnData(self, slice):
        
        # define time we trade
        stop_time_start = self.Time.replace(hour=15, minute=00)
        stop_time_end = self.Time.replace(hour=16, minute=30)
        if self.Time > stop_time_end or self.Time < stop_time_start:
            return
        
        for chain in slice.FutureChains.Values:
            contracts = chain.Contracts
            if len(contracts) == 0:
                continue
            sorted_by_oi_contracts = sorted(contracts.Values, key=lambda k: k.OpenInterest, reverse=True)
            # self.Debug(f"contract 1: {sorted_by_oi_contracts[0].Symbol}, underlying {sorted_by_oi_contracts[0].UnderlyingSymbol}, expiry {sorted_by_oi_contracts[0].Expiry}, last price {sorted_by_oi_contracts[0].LastPrice}")
            # self.Debug(f"contract 1: {sorted_by_oi_contracts[1].Symbol}, underlying {sorted_by_oi_contracts[1].UnderlyingSymbol}, expiry {sorted_by_oi_contracts[1].Expiry}, last price {sorted_by_oi_contracts[1].LastPrice}")
            popular_contract = sorted_by_oi_contracts[0]
            
            #         class FuturesContract:
            # self.Symbol # (Symbol) Symbol for contract needed to trade.
            # self.UnderlyingSymbol # (Symbol) Underlying futures asset.
            # self.Expiry # (datetime) When the future expires
            # self.OpenInterest # (decimal) Number of open interest.
            # self.LastPrice # (decimal) Last sale price.
            # self.Volume # (long) reported volume.
            # self.BidPrice # (decimal) bid quote price.
            # self.BidSize # (long) bid quote size.
            # self.AskPrice # (decimal) ask quote price.
            # self.AskSize # (long) ask quote size.
            
            # calculate TrueRange
            # if close_window[1] > slice[popular_contract.Symbol].High: 
            #     TH = close_window[1]
            # else:
            #     TH = slice[popular_contract.Symbol].High
            
            # if close_window[1] < slice[popular_contract.Symbol].Low: 
            #     TL = close_window[1] 
            # else: 
            #     TL = slice[popular_contract.Symbol].Low
            # TrueRange = TH - TL

            # plot indicators
            #if self.slow_sma:
            #    self.Plot("Indicators", "SMA", self.slow_sma.Current.Value)
            
            if popular_contract.Symbol not in self.consolidator_by_symbol:

                # rolling windows
                # close_window = RollingWindow[float](2)
                # high_window = RollingWindow[float](2)
                # low_window = RollingWindow[float](2)

                minutesConsolidator = TradeBarConsolidator(timedelta(minutes=3))
                #minutesLongConsolidator = TradeBarConsolidator(timedelta(minutes=3))
                minutesConsolidator.DataConsolidated += self.MinutesHandler
                # minutesLongConsolidator.DataConsolidated += self.MinutesLongHandler
                self.SubscriptionManager.AddConsolidator(popular_contract.Symbol, minutesConsolidator)
                # self.SubscriptionManager.AddConsolidator(popular_contract.Symbol, minutesLongConsolidator)
                self.consolidator_by_symbol[popular_contract.Symbol] = minutesConsolidator
                
                self.slow_sma = LinearWeightedMovingAverage(self.slow_sma_period)
                self.fast_sma = LinearWeightedMovingAverage(self.fast_sma_period)
                self.volume_sma = LinearWeightedMovingAverage(self.fast_sma_period)
                self.true_range = TrueRange("TrueRange", 2)

                # Commodity Channel Index (https://en.wikipedia.org/wiki/Commodity_channel_index)
                self.cci = self.CCI(popular_contract.Symbol, self.CCIPeriod,  MovingAverageType.Simple, Resolution.Daily)
                
                self.RegisterIndicator(popular_contract.Symbol, self.slow_sma, minutesConsolidator)
                self.WarmUpIndicator(popular_contract.Symbol, self.slow_sma, Resolution.Minute)

                self.RegisterIndicator(popular_contract.Symbol, self.fast_sma, minutesConsolidator)
                self.WarmUpIndicator(popular_contract.Symbol, self.fast_sma, Resolution.Minute)

                self.RegisterIndicator(popular_contract.Symbol, self.volume_sma, minutesConsolidator, Field.Volume)
                self.WarmUpIndicator(popular_contract.Symbol, self.volume_sma, Resolution.Minute)

                self.RegisterIndicator(popular_contract.Symbol, self.cci, minutesConsolidator)
                self.WarmUpIndicator(popular_contract.Symbol, self.cci, Resolution.Minute)

                self.RegisterIndicator(popular_contract.Symbol, self.true_range, minutesConsolidator)
                self.WarmUpIndicator(popular_contract.Symbol, self.true_range, Resolution.Minute)

            self.Plot("Indicator", "SMA slow", self.slow_sma.Current.Value)
            self.Plot("Indicator", "SMA fast", self.fast_sma.Current.Value)
            # self.Plot("Indicator", "TrueRange", self.true_range.Value)

            self.Plot("Indicator 2", "SMA Volume", self.volume_sma.Current.Value)
            self.Plot("CCI", "CCI value", self.cci.Current.Value)

            # trading rule
            if self.slow_sma.Current.Value > self.fast_sma.Current.Value:
                self.SetHoldings(popular_contract.Symbol, 1)

    def MinutesHandler(self, sender: DataConsolidator, bar: TradeBar):
        # close_window.Add(bar.Close)
        # high_window.Add(bar.High)
        # low_window.Add(bar.low)
        pass


class TrueRange(PythonIndicator):

    def __init__(self, name, period):
        self.Name = name
        self.Value = None
        self.period = period
        self.WarmUpPeriod = period
        self.Time = datetime.min
        self.queue_close = deque(maxlen=period)
        self.queueTime = deque(maxlen=period)
    
    def Update(self, input):
        self.queue_close.appendleft(input.Close)
        self.queueTime.appendleft(input.EndTime)
        self.Time = input.EndTime
        count = len(self.queue)

        if self.queue_close[0] > input.High: 
            TH = self.queue_close[0]
        else:
            TH = input.High
        if self.queue_close[0] < input.Low: 
            TL = self.queue_close[0]
        else: 
            TL = input.Low
        self.Value = TH - TL

        self.IsReady = count == self.queue.maxlen
        return self.IsReady