Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-16.605
Tracking Error
0.132
Treynor Ratio
0
Total Fees
$0.00
class UniverseRollingAlgorithm(QCAlgorithm):
    
    def Initialize(self):       #Initialize Dates, Cash, Equities, Fees, Allocation, Parameters, Indicators, Charts
        
        # Set Start Date, End Date, and Cash
        #-------------------------------------------------------
        self.SetStartDate(2020, 4, 22)   # Set Start Date
        self.SetEndDate(2020, 4, 24)      # Set End Date
        self.SetCash(100000)            # Set Strategy Cash
        #-------------------------------------------------------
        
        # Set Custom Universe
        #-------------------------------------------------------
        self.AddUniverse(self.CoarseSelectionFilter, self.FineSelectionFilter)
        self.UniverseSettings.Resolution = Resolution.Daily     #Needs to change to Resolution.Minute once code works, leaving Daily for now to minimize data
        self.UniverseSettings.SetDataNormalizationMode = DataNormalizationMode.SplitAdjusted
        self.UniverseSettings.FeeModel = ConstantFeeModel(0.0)
        self.UniverseSettings.Leverage = 1
        #-------------------------------------------------------
        
        self.EMA_Period_Fast = 50
        self.EMA_Period_Slow = 200
        self.UniverseSettings.MinimumTimeInUniverse = self.EMA_Period_Slow
        self.SetWarmUp(self.EMA_Period_Slow)
        
        self.__numberOfSymbols     = 100
        self.__numberOfSymbolsFine = 10
        
        self.indicators = {}
        
        self.fast_ema_window = RollingWindow[IndicatorDataPoint](20)
        self.slow_ema_window = RollingWindow[IndicatorDataPoint](20)
        
            
    def CoarseSelectionFilter(self, coarse):
        sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)   # sort descending by daily dollar volume
        return [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols] ]  # return the symbol objects of the top entries from our sorted collection
    
    def FineSelectionFilter(self, fine):  # sort the data by P/E ratio and take the top 'NumberOfSymbolsFine'
        sortedByPeRatio = sorted(fine, key=lambda x: x.OperationRatios.OperationMargin.Value, reverse=False)    # sort descending by P/E ratio
        self.universe = [ x.Symbol for x in sortedByPeRatio[:self.__numberOfSymbolsFine] ]  # take the top entries from our sorted collection
        return self.universe
    
    def OnSecuritiesChanged(self, changes):
        #self.Log(f"OnSecuritiesChanged({self.Time}):: {changes}"
        for security in changes.RemovedSecurities:
            if security.Invested:
                self.Liquidate(security.Symbol)
                del self.indicators[security.Symbol]  # clean up
    
    
    def OnData(self, data):         #Entry Point for Data and algorithm - Check Data, Define Buy Quantity, Process Volume, Check Portfolio, Check RSI, Execute Buy/Sell orders, Chart Plots
        
        for symbol in self.universe:
            
            if not data.ContainsKey(symbol): # is symbol in Slice object? (do we even have data on this step for this asset)
               continue
           
            if data[symbol] is None:    # Runtime Error: Python.Runtime.PythonException: AttributeError : 'NoneType' object has no attribute 'Price'
                continue
            
            if data[symbol].Price is None:  # Does this slice have the price data we need at this moment?
                continue
           
            if symbol not in self.indicators: # new symbol? setup indicator object. Then update
                self.indicators[symbol] = SymbolData(symbol, self, self.EMA_Period_Fast, self.EMA_Period_Slow, self.fast_ema_window, self.slow_ema_window)
        
        for symbol in self.universe:
            
            # Check for Indicator Readiness within Rolling Window
            #-------------------------------------------------------
            if not (self.fast_ema_window.IsReady and self.slow_ema_window.IsReady): 
                return
            
            #if self.IsWarmingUp: continue
          
            self.indicators[symbol].update_value(self.Time, data[symbol].Price) #update by value
            
            
            self.Debug("Rolling Fast Index[0] = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].fast_ema_window[0]))
            self.Debug("Rolling Fast Index[1] = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].fast_ema_window[1]))
            
            
            self.Debug("Rolling Slow Index[0] = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[0]))
            self.Debug("Rolling Slow Index[1] = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[1]))
            
            '''
            self.Debug("RW4F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[4]))
            self.Debug("RW5F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[5]))
            self.Debug("RW6F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[6]))
            self.Debug("RW7F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[7]))
            self.Debug("RW8F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[8]))
            self.Debug("RW9F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[9]))
            self.Debug("RW10F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[10]))
            self.Debug("RW11F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[11]))
            self.Debug("RW12F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[12]))
            self.Debug("RW13F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[13]))
            self.Debug("RW14F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[14]))
            self.Debug("RW15F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[15]))
            self.Debug("RW16F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[16]))
            self.Debug("RW17F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[17]))
            self.Debug("RW18F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[18]))
            self.Debug("RW19F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[19]))
            '''
            
            #EXECUTE TRADING LOGIC HERE - PSEUDOCODE FOR NOW
            #if self.EMA_FastWin[0] > self.EMA_SlowWin[0] and self.EMA_FastWin[1] < self.EMA_SlowWin[1]:
            #    buy_order = self.SetHoldings(security.Key, 0.10) 
                
            #elif self.EMA_FastWin[0] < self.EMA_SlowWin[0] and self.EMA_FastWin[1] > self.EMA_SlowWin[1]:
            #    self.Liquidate(security.Key)

class SymbolData(object):
    def __init__(self, symbol, context, fast_ema_period, slow_ema_period, fast_ema_window, slow_ema_window):
        
        self.symbol = symbol
        self.fast_ema_period = fast_ema_period
        self.slow_ema_period = slow_ema_period
        self.fast_ema = context.EMA(symbol, self.fast_ema_period)
        self.slow_ema = context.EMA(symbol, self.slow_ema_period)
        self.fast_ema.Updated += self.EMAUpdated_F
        self.slow_ema.Updated += self.EMAUpdated_S
        self.fast_ema_window = fast_ema_window #RollingWindow[IndicatorDataPoint](5)  
        self.slow_ema_window = slow_ema_window #RollingWindow[IndicatorDataPoint](5)
        
    #def update_bar(self, bar):
        #self.indicator.Update(bar)
        
    def update_value(self, time, value):
        self.fast_ema.Update(time, value)
        self.slow_ema.Update(time, value)
            
    def get_fast_EMA(self, context, symbol, period):
        return self.fast_ema.Current.Value
        
    def get_slow_EMA(self):
        return self.slow_ema.Current.Value
    
    def EMAUpdated_F(self, sender, updated):
        self.fast_ema_window.Add(updated)        # Adds updated values to rolling window
        
    def EMAUpdated_S(self, sender, updated):
        self.slow_ema_window.Add(updated)        # Adds updated values to rolling window 
        
   
        
#END CODE