Overall Statistics
Total Trades
2824
Average Win
0.17%
Average Loss
-0.21%
Compounding Annual Return
-25.261%
Drawdown
38.100%
Expectancy
-0.080
Net Profit
-25.202%
Sharpe Ratio
-0.696
Probabilistic Sharpe Ratio
1.810%
Loss Rate
49%
Win Rate
51%
Profit-Loss Ratio
0.82
Alpha
0
Beta
0
Annual Standard Deviation
0.231
Annual Variance
0.053
Information Ratio
-0.696
Tracking Error
0.231
Treynor Ratio
0
Total Fees
$2913.54
Estimated Strategy Capacity
$15000000.00
Lowest Capacity Asset
FDX R735QTJ8XC9X
# Division by zero when adding volume universe modified

MA = 100; N_COARSE = 40; N_FACTOR = 10; LEV = 1.00;

class AddUniverse(QCAlgorithm):
    def Initialize(self):       
        self.SetStartDate(2021, 5, 1)
        self.SetEndDate(2022, 5, 1)
        self.SetWarmUp(MA, Resolution.Daily)
        self.UniverseSettings.Resolution = Resolution.Minute
        self.AddUniverse(self.CoarseFilterFunction)    
        self.SetCash(100000)
        self.SetTimeZone("America/New_York")
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)   
        self.symbolData = {}
        self.symbols = []

       
    def CoarseFilterFunction(self, coarse):
        eqs =  [x for x in coarse if (x.HasFundamentalData and x.Price > 5)]
        dollar_volume_sorted = sorted(eqs, key=lambda x: x.DollarVolume, reverse = True)
        top = dollar_volume_sorted[:N_COARSE]
        top_dv = [x for x in top]
        ## added above dollar volume prefilter
        for c in top_dv:
            if c.Symbol not in self.symbolData:
                self.symbolData[c.Symbol] = SelectionData(c.Symbol, MA)
            avg = self.symbolData[c.Symbol]
            avg.update(c.EndTime, c.AdjustedPrice, c.DollarVolume)
        values = [sd for sd in self.symbolData.values() if sd.volume > sd.sma.Current.Value]
        values.sort(key=lambda sd: sd.volume_ratio, reverse=True)
        self.symbols =  [ sd.symbol for sd in values[:N_FACTOR] ] 
       
        return self.symbols
       
   
    ## added  OnData
    def OnData(self, data):
        if self.IsWarmingUp: return
        if self.Time.time() < time(10, 1): return
    
        for sec in self.Portfolio.Keys:
            if sec not in self.symbols:                
                self.Liquidate(sec)
        for sec in self.symbols:
            if self.Time.time() == time(10, 1): 
                self.SetHoldings(sec, LEV/len(self.symbols))     
       
       
class SelectionData(object):
    def __init__(self, symbol, period):
        self.symbol = symbol
        self.volume = 1                                                        ## changed to 1
        self.volume_ratio = 1                                                  ## changed to 1
        self.sma = SimpleMovingAverage(period)
   
    def update(self, time, price, volume):
        self.volume = volume
        if self.sma.Update(time, volume):
            self.volume_ratio = volume / self.sma.Current.Value  if self.sma.Current.Value > 0 else 1      ## added  if self.sma.Current.Value > 0 else 1