Hello,

So I am trying to code an algorithm that trades stocks that are in the best-performing sectors relative to SPY.

For this I want to rank the relative returns of the sector etfs and then go on and trade stocks that are in those sectors.

To rank the sector etfs I created a function called rank that takes the etf dictionary with log returns.

My problem is when I try to populate this etf dictionary. The key for the etf is a “None” object because I am doing something wrong with the Log Return Indicator.

I've had a very hard creating a Custome Indicator and I still get the same error when I use the Automatic Indicator so I wonder what is the best way to approach this problem.

# region imports
from AlgorithmImports import *
from sectorcodes import sectorcodes
# endregion

#sector codes is just a dictionary ex. sectorcodes = {
"MOO":"Agriculture",
..."ITB":"BuildingMateria#ls"}

class FatYellowGreenGoat(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 7, 26)
        self.SetEndDate(2021, 10, 26)
        self.SetCash(100000)  
        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
        self.Data = {}
        barPeriod = 15
        
        for etf in sectorcodes.keys():
            symbol = self.AddEquity(etf,Resolution.Daily).Symbol 
            self.rollingwindow = RollingWindow[TradeBar](barPeriod)

            self.EnableAutomaticIndicatorWarmUp = True 
            self.logr = self.LOGR(etf,barPeriod)
            self.logr.Updated += self.LogrUpdated
            self.logr_window = RollingWindow[IndicatorDataPoint](barPeriod)
            self.Data[etf] = self.logr_window

        
    def LogrUpdated(self,sender,updated):
        self.logr_window.Add(updated)
    
    def OnData(self, data: Slice):
        for etf in sectorcodes.keys(): 
            self.rollingwindow.Add(data[etf])

    def rank(self):
        if not self.logr_window.IsReady: return
        
        temp = {}
        codeswospy = sectorcodes.copy()
        codeswospy.pop('SPY')

        for etf in codeswospy.keys():
            temp[etf] = sum(self.Data[etf]) / sum(self.Data['SPY'])
        sorted_rank = (sorted(temp.items(), key=lambda item: item[1], reverse =True))    
        sorted_etfs = list(sorted_rank.keys())

        return sorted_etfs[:3]
        

    def CoarseSelectionFunction(self,coarse):
        sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
        byprice = [x for x in sortedByDollarVolume if x.DollarVolume > 1000000 and x.Price > 5 and x.HasFundamentalData]
        
        byprice = [x.Symbol for x in byprice][:1000]
        
        return byprice
    

    def FineSelectionFunction(self,fine):
        sorted_etfs = self.rank()
        sector1 = sorted_etfs[0]
        sector2 = sorted_etfs[1]
        sector3 = sorted_etfs[2]
        fineUniverse = [x for x in fine if x.AssetClassification.MorningstarIndustryGroupCode == MorningstarIndustryGroupCode.sector1
                        or x.AssetClassification.MorningstarIndustryGroupCode == MorningstarIndustryGroupCode.sector2
                        or x.AssetClassification.MorningstarIndustryGroupCode == MorningstarIndustryGroupCode.sector3 and x.MarketCap > 5e7]
        tickerSymbolValuesOnly = [c.Symbol for c in fineUniverse]

    def OnSecuritiesChanged(self, changes):
        for security in changes.AddedSecurities:
            self.MarketOrder(security,1)