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
-1.198
Tracking Error
0.135
Treynor Ratio
0
Total Fees
$0.00
class RelativeVolumeUniverseSelector(QCAlgorithm):
    
    def Initialize(self):
        self.SetStartDate(2020, 1, 1)
        self.SetEndDate(2020, 1, 5)
        self.SetCash(100000)
        
        # relative volume universe selection.
        self.UniverseSettings.Resolution = Resolution.Minute
        self.AddUniverse(self.CoarseSelectionFunction) 
        self.universeAvgVol = { }
        self.symbols = list()
        
    def CoarseSelectionFunction(self, universe):
        # calculate the 60-day average volume, then compare with premarket volume to get Relative Volume
        selected = []

        for coarse in universe:  
            symbol = coarse.Symbol
            
            # create list of all symbols with 60 day volume sma
            
            if symbol not in self.universeAvgVol:
                self.universeAvgVol[symbol] = SelectionData(symbol, 60)
                history = self.History(symbol, 60, Resolution.Daily)
                self.universeAvgVol[symbol].warmUp(history)
                
            # update symbol volume sma daily
                
            sd = self.universeAvgVol[symbol]
            sd.update(self.Time, coarse.Volume)
            
            if  sd.is_ready():
                selected.append(symbol)
        
        selected.sort(key=lambda x: self.universeAvgVol[x].relativeVolume, reverse=True)
        self.symbols = selected[:10]
        
        return self.symbols
    


class SelectionData(object):
    
    def __init__(self, symbol, period):
        self.symbol = symbol
        self.sma = SimpleMovingAverage(period)
        self.premarketVolume = 0
        self.relativeVolume = 1
    
    def is_ready(self):
        return self.sma.IsReady
    
    def update(self, time, volume):
        self.sma.Update(time, volume)
        if self.sma.Current.Value != 0:
            self.relativeVolume = self.premarketVolume / self.sma.Current.Value
        
    def warmUp(self, history):
        if history.empty:
            return
        for bar in history.itertuples():
            self.sma.Update(bar.Index[1], bar.volume)