| 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'))