Hi, I'm new to Quantconnect. 

I started this with adding 1 ticker via the AddEquity-function - then I had everything working, rolling windows of EMAs, VWAP and the symbol price.

Now I am trying to convert everything to use a custom universe, but I am stuck.

Been reading dozens of different forum topics to try and find someone seeking help for something similar, but I still can't understand what I am doing wrong. As the code is now, it's a mix of different snippets from different topics..

Can someone please look at this and advice me?

#region imports
from AlgorithmImports import *
#endregion
class FirstTest(QCAlgorithm):
    
    def Initialize(self):
        self.SetCash(100000)
        self.SetTimeZone(TimeZones.NewYork)    
        # Start and end dates for backtest
        self.SetStartDate(2022,5,23)
        self.SetEndDate(2022,6,23)

        # Maximum Price offset for stop order
        self.initialStopRisk = 0.03

        # for testing purposes - adding symbols one by one
        #self.symbol = self.AddEquity("BHAT", Resolution.Minute, Market.USA, True, 1, True).Symbol
        
        self.SetUniverseSelection(CoarseFundamentalUniverseSelectionModel(self.CoarseFilter))
        self.UniverseSettings.ExtendedMarketHours = True
        self.UniverseSettings.Resolution = Resolution.Minute
        self.universe = []
        self.AddEquity("SPY", Resolution.Minute)
        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(9, 31), self.SelectUniverse)
        self.previous_close_by_symbol = {}

        #Initiate Indicators:
        self.indicators = {}
        self.EMA_Period_Fast = 10
        self.EMA_Period_Slow = 20
        emaL_is_true=0
        self.deadVWAP=0.0001  

        #Schedules:
        #self.rebuyTime=datetime.min  # if I want to minimize rebuys within e.g. 10 mins
        
        #Sell all before market close
        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 15), self.ClosePositions)

    def CoarseFilter(self, coarse):
        selected = [c for c in coarse if c.HasFundamentalData and c.Price>100]
        selected = sorted(selected, key=lambda x: x.DollarVolume, reverse=True)[:10]
        self.Debug(f"Universe size after coarse filter: {len(selected)}")
        self.previous_close_by_symbol = {}
        
        for l in selected:
            self.previous_close_by_symbol[l.Symbol] = l.AdjustedPrice
        return list(self.previous_close_by_symbol.keys())
        
        
    def SelectUniverse(self):
        self.universe = []
        
        for symbol, previous_close in self.previous_close_by_symbol.items():
            if symbol not in self.CurrentSlice.Bars:
                continue  #  return?
            open_price=self.CurrentSlice.Bars[symbol].Open
            gap=(open_price - previous_close) / previous_close
            
            #self.Debug(str(symbol)+" not gapping up at" + str(self.Time))
            if gap>0.01:
                self.universe.append(symbol)
                self.Log(str(symbol) + str(self.Time) + "Gap is " + str(gap * 100))
                self.Debug(f"Universe size after looking for gaps: {len(self.universe)}")

    def OnSecuritiesChanged(self, changes):
        # Create indicator for each new security
        for security in changes.AddedSecurities:
            self.indicators[security.Symbol] = SymbolData(security.Symbol, self, self.EMA_Period_Fast, self.EMA_Period_Slow)
            self.Debug("Added indicators for" + str(security.Symbol))
        for security in changes.RemovedSecurities:
            if security.Invested:
                self.Liquidate(security.Symbol, "Universe Removed Security")  # sell the removed security
            if security in self.indicators:
                self.indicators.pop(security.Symbol, None)  # removes the indicator
            if security.Symbol in self.data:            
                del self.data[security.Symbol]         

#Nope, self.Bars would only be accessible in SymbolData class. 
# In OnData method in youralgo class, you would call self.Data[symbol].Bars[0].Close. 
# In the above example, since the dictionary value has been called as a variable, 
# you can call symbolData.Bars[0].Close in the line that I hashtaged # your actions

    def OnData(self, data):
        #self.Plot("Data Chart", self.symbol, self.Securities[self.symbol].Low)   # plots the chart of the testing symbol
        for symbol in self.universe:
            self.Log(str(self.Securities[symbol])+str(self.Time))
            if not data.ContainsKey(symbol):
                continue
            if data[symbol] is None:
                continue
            if not symbol in self.indicators:
                continue         
            if not self.indicators[symbol].slow_ema.IsReady:  # Ensure indicators are ready to update rolling windows
                continue
            # Update EMA rolling windows
            self.indicators[symbol].fast_ema_window.Add(self.indicators[symbol].get_fast_EMA())
            self.indicators[symbol].slow_ema_window.Add(self.indicators[symbol].get_slow_EMA())
            self.indicators[symbol].vwap_window.Add(self.indicators[symbol].get_VWAP())

            # Check for Indicator Readiness within Rolling Window
            #-------------------------------------------------------
            if not (self.indicators[symbol].fast_ema_window.IsReady and self.indicators[symbol].slow_ema_window.IsReady and self.indicators[symbol].vwap_window.IsReady): 
                continue     

            #SymbolData=data[symbol]

            if SymbolData.IsReady(self):    #and SymbolData.WasJustUpdated(self, self.Time):
                continue
            if (self.Time.hour == 9 and self.Time.minute == 33):

                max_of_opening_highs=max(SymbolData.Bars[1].High, SymbolData.Bars[2].High)
                self.Debug("Max of ORH 2 last minutes:" +str(max_of_opening_highs)) 
                self.Debug("High at this time:" +str(SymbolData.Bars[0].High)) 
                if SymbolData.Bars[0].High > max_of_opening_highs:
                    self.LowOfBuyBar = SymbolData.Bars[0].Low
                    self.Debug("Buy order created")
                    self.SetHoldings(symbol, 0.25, False, "ORH BUY")  # buy with 25% of account
              
     

    # old way
    #def CustomBarHandler(self, bar):
     #       self.rollingWindow.Add(bar)

    def OnOrderEvent(self, orderevent):
            # check if orderevent is a fill
        if orderevent.Status == OrderStatus.Filled:
             symbol = orderevent.Symbol
             fill_price = orderevent.FillPrice
             current_price = self.Securities[symbol].Price
             self.Debug("Fill price of order is: " +str(orderevent.FillPrice))
             self.BuyPrice=fill_price
             # Create trailing stop loss if invested 
             if self.Securities[symbol].Invested:
                # If no order exists, send stop-loss
                if not self.Transactions.GetOpenOrders(symbol):
                    self.stopMarketTicket = self.StopMarketOrder(symbol, \
                                            -self.Portfolio[symbol].Quantity, \
                                            (1-min(self.initialStopRisk, 1-(self.LowOfBuyBar/self.BuyPrice)))*self.BuyPrice-0.01, "STOPLOSS")  # setting stop 1 cent below 

                    self.Debug("Stop loss set at: "+ str((1-min(self.initialStopRisk, 1-(self.LowOfBuyBar/self.BuyPrice)))*self.BuyPrice-0.01))


 
## should be called at market close, if wanted
 #   def ClosePositions(self):
 #       for security in self.universe:
  #          if self.Securities[security.Symbol].Invested:
  #              self.Liquidate(security.Symbol)
      
class SymbolData(object):
    
    rolling_window_length = 5
    
    def __init__(self, symbol, context, fast_ema_period, slow_ema_period):
        self.symbol = symbol
        self.BarPeriod = timedelta(minutes=1)
        self.Bars = RollingWindow[IBaseDataBar](2)
        self.fast_ema_period = fast_ema_period
        self.slow_ema_period = slow_ema_period
        self.vwap = VolumeWeightedAveragePriceIndicator(20) #60*24 = 1440 minutes in a day
        self.fast_ema = context.EMA(symbol, self.fast_ema_period, Resolution.Minute)    #, fillDataForward = True, leverage = 1, extendedMarketHours = False)
        self.slow_ema = context.EMA(symbol, self.slow_ema_period, Resolution.Minute)    #, fillDataForward = True, leverage = 1, extendedMarketHours = False)
        #self.vwap = context.VWAP(symbol)    #, fillDataForward = True, leverage = 1, extendedMarketHours = False)
        self.fast_ema_window = RollingWindow[float](self.rolling_window_length)
        self.slow_ema_window = RollingWindow[float](self.rolling_window_length)
        self.vwap_window = RollingWindow[float](self.rolling_window_length)

        ### old way rollingwindow, now testing self.Bars
        #self.rollingWindow = RollingWindow[TradeBar](4)
        #self.Consolidate(self.symbol, Resolution.Minute, self.CustomBarHandler)

        # Warm up indicators
        history = context.History([symbol], slow_ema_period + self.rolling_window_length, Resolution.Minute)
        for time, row in history.loc[symbol].iterrows():
            self.fast_ema.Update(time, row["close"])
            self.slow_ema.Update(time, row["close"])
           # self.vwap.Update(time, row["close"])  # vwap does not support this method of updating according to error message so did below
            tradeBar = TradeBar(time, symbol, row.open, row.high, row.low, row.close, row.volume, timedelta(minutes=1))
            self.vwap.Update(tradeBar)

            # Warm up rolling windows    ## check indentation ?
            if self.fast_ema.IsReady:
                self.fast_ema_window.Add(self.fast_ema.Current.Value)
            if self.slow_ema.IsReady:
                self.slow_ema_window.Add(self.slow_ema.Current.Value)
            if self.vwap.IsReady:
                self.vwap_window.Add(self.vwap.Current.Value)
        
        self.consolidator = TradeBarConsolidator(Resolution.Minute)
        self.consolidator.DataConsolidated += self.consolidation_handler
        context.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
        
    def IsReady(self):
        return self.Bars.IsReady
    def WasJustUpdated(self, current):
        return self.Bars.Count > 0 and self.Bars[0].Time == current - self.BarPeriod 
    def consolidation_handler(self, sender, consolidated):
        self.vwap.Update(consolidated)
    def get_fast_EMA(self):
        return self.fast_ema.Current.Value
    def get_slow_EMA(self):
        return self.slow_ema.Current.Value  
    def get_VWAP(self):
        return self.vwap.Current.Value   

    

Author