Overall Statistics
Total Trades
847
Average Win
1.85%
Average Loss
-1.13%
Compounding Annual Return
20.113%
Drawdown
41.100%
Expectancy
0.385
Net Profit
1076.571%
Sharpe Ratio
0.844
Probabilistic Sharpe Ratio
17.870%
Loss Rate
48%
Win Rate
52%
Profit-Loss Ratio
1.64
Alpha
0.103
Beta
1.042
Annual Standard Deviation
0.229
Annual Variance
0.053
Information Ratio
0.852
Tracking Error
0.125
Treynor Ratio
0.186
Total Fees
$0.00
Estimated Strategy Capacity
$3700000.00
Lowest Capacity Asset
AMZN R735QTJ8XC9X
import numpy as np
import pandas as pd
class UniverseRollingAlgorithm(QCAlgorithm):
    def Initialize(self):  
        self.SetTimeZone(TimeZones.NewYork)   
        self.SetStartDate(2007, 1, 1)   
        self.SetEndDate(2020, 6,10)      
        self.SetCash(25000)            
        self.SetSecurityInitializer(lambda x: x.SetFeeModel(CustomFeeModel()))
        self.AddUniverse(self.CoarseSelectionFilter, self.FineSelectionFilter)
        self.UniverseSettings.Resolution = Resolution.Minute
        self.UniverseSettings.SetDataNormalizationMode = DataNormalizationMode.SplitAdjusted
        self.AddEquity('SPY', Resolution.Minute).Symbol
        self.Portfolio.MarginCallModel = MarginCallModel.Null
        self.__numberOfSymbols     = 300
        #self.UniverseSettings.Leverage = 1.9
        for i in range(1, 388, 1): 
            self.Schedule.On(self.DateRules.EveryDay(), \
            self.TimeRules.AfterMarketOpen("SPY", i), \
            self.auto)
    def CoarseSelectionFilter(self, coarse):
        sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) 
        return [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols]] 
    def FineSelectionFilter(self, fine):  # sort the data by P/E ratio and take the top 'NumberOfSymbolsFine'
        stocks = fine
        stocks = [x for x in stocks if x.MarketCap>20000000]
        stocks = [x for x in stocks if x.CompanyReference.CountryId == "USA"]
        #stocks = [x for x in self.get_top_zscore(stocks)]
        stocks = [x for x in stocks if x.AssetClassification.GrowthGrade in ["A", "B"]]
        stocks = sorted(stocks, key=lambda x: x.ValuationRatios.PERatio>30)
        stocks = [x for x in stocks if x.SecurityReference.IsPrimaryShare == 1]
        #stocks = [x for x in stocks if x.Symbol.Value != "UNH"]
        #stocks = [x for x in stocks if x.Symbol.Value != "GOOG"]
        stocks = sorted(stocks, key=lambda x: x.MarketCap, reverse=True)[:20] 
        stocks = sorted(stocks, key=lambda x: x.AssetClassification.GrowthScore, reverse=True)[:10] 
        stocks = sorted(stocks, key=lambda x: x.MarketCap, reverse=True)[:5]
        self.universe = [x.Symbol for x in stocks]
        return self.universe
    def get_top_zscore(self, stocks):
        gs = [[x.AssetClassification.GrowthScore, x] for x in stocks if x.AssetClassification.GrowthScore != 0.0]
        a = np.array([x[0] for x in gs])
        mean, std = a.mean(), a.std()
        gs_zscore = [[(x[0] - mean) / std, x[1]] for x in gs]
        gs_zscore = sorted(gs_zscore, key=lambda x: x[0])
        gs_zscore = gs_zscore[round(len(gs_zscore) * 0.3):]
        return [x[1] for x in gs_zscore]
    def OnData(self, data):
        pass
    def auto(self):
            positions = [sec.Symbol for sec in self.Portfolio.Values if self.Portfolio[sec.Symbol].Invested]
            if len(positions)>=5:
                for symbol in positions:
                    if symbol not in self.universe:
                        self.SetHoldings(symbol, 0,False,"OUT")
            elif len(positions)<=4:
                for symbol in self.universe:
                    if not self.Portfolio[symbol].Invested:
                        self.SetHoldings(symbol, 0.199,False,"Take Long Position")
class CustomFeeModel:
    def GetOrderFee(self, parameters):
        fee = 0
        return OrderFee(CashAmount(fee, 'USD'))