Overall Statistics |
Total Trades 182 Average Win 3.74% Average Loss -1.20% Compounding Annual Return 78.712% Drawdown 29.500% Expectancy 0.564 Net Profit 78.712% Sharpe Ratio 1.581 Probabilistic Sharpe Ratio 61.687% Loss Rate 62% Win Rate 38% Profit-Loss Ratio 3.12 Alpha 0.738 Beta -0.666 Annual Standard Deviation 0.383 Annual Variance 0.147 Information Ratio 0.977 Tracking Error 0.417 Treynor Ratio -0.909 Total Fees $2389.31 Estimated Strategy Capacity $4000.00 Lowest Capacity Asset CHRB R735QTJ8XC9X |
#from datetime import timedelta from QuantConnect.Data.UniverseSelection import * from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel from Execution.ImmediateExecutionModel import ImmediateExecutionModel from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel class FirstAttempt(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 1, 1) # Set Start Date self.SetEndDate(2022,1,1) # Setting end date self.SetCash(100000) # Set Strategy Cash #self.SetBenchmark('SPY') self.lastMonth = -1 self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverseSelection(HighRoICHighPEUniverse()) #self.AddUniverseSelection(HighRoICHighPEUniverse()) self.AddAlpha(BuyValue()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel(lambda time: None)) self.SetExecution(ImmediateExecutionModel()) class HighRoICHighPEUniverse(FundamentalUniverseSelectionModel): def __init__(self): super().__init__(True, None) #took it from the bootcamp self.lastMonth = -1 def SelectCoarse(self, algorithm, coarse): if algorithm.Time.month == self.lastMonth: return Universe.Unchanged self.lastMonth = algorithm.Time.month filtered = [ x for x in coarse if x.HasFundamentalData ] return [x.Symbol for x in filtered] def SelectFine(self,algorithm, fine): sorted_high = sorted([x for x in fine if x.MarketCap < 2e9 and x.OperationRatios.ROIC.OneYear > 0.2 and x.ValuationRatios.PERatio > 20 and x.AssetClassification.MorningstarSectorCode != MorningstarSectorCode.FinancialServices and x.AssetClassification.MorningstarSectorCode != MorningstarSectorCode.Healthcare], key=lambda x: x.ValuationRatios.PERatio, reverse=True) algorithm.Log(f"High Universe consists of {len(sorted_high)} securities") algorithm.Log(f"High Universe #1 {sorted_high[0]} securities") algorithm.Log(f"High Universe #2 {sorted_high[1]} securities") algorithm.Log(f"High Universe #3 {sorted_high[2]} securities") algorithm.Log(f"High Universe #4 {sorted_high[3]} securities") algorithm.Log(f"High Universe #5 {sorted_high[4]} securities") sorted_low = sorted([x for x in fine if x.MarketCap < 2e9 and x.OperationRatios.ROIC.OneYear < 0.05 and x.ValuationRatios.PERatio < 10 and x.AssetClassification.MorningstarSectorCode != MorningstarSectorCode.FinancialServices and x.AssetClassification.MorningstarSectorCode != MorningstarSectorCode.Healthcare], key=lambda x: x.ValuationRatios.PERatio, reverse=True) #and x.ValuationRatios.PERatio < 10 #key=lambda x: x.OperationRatios.OperationMargin.OneYear, reverse=True algorithm.Log(f"Low Universe consists of {len(sorted_low)} securities") algorithm.Log(f"Low Universe #1 {sorted_low[0]} securities") algorithm.Log(f"Low Universe #2 {sorted_low[1]} securities") algorithm.Log(f"Low Universe #3 {sorted_low[2]} securities") algorithm.Log(f"Low Universe #4 {sorted_low[3]} securities") algorithm.Log(f"Low Universe #5 {sorted_low[4]} securities") Universe = sorted_high[:5] + sorted_low[-5:] return [z.Symbol for z in Universe] class BuyValue (AlphaModel): def __init__(self): self.lastMonth = -1 self.longs = [] self.shorts = [] def Update (self, algorithm, data): if algorithm.Time.month == self.lastMonth: return [] self.lastMonth = algorithm.Time.month insights = [] #Check if existing algorithm portfolio contains any securities in long or short directories #if we are invested on securities that are not in long or shorts, then we go 'flat' for x in algorithm.Portfolio: holding = x.Value symbol = holding.Symbol if holding.Invested and symbol not in self.longs and symbol not in self.shorts: insights.append(Insight(symbol, timedelta(30), InsightType.Price, InsightDirection.Flat)) #generate insight-Up for long positions for symbol in self.longs: insights.append(Insight(symbol, timedelta(30), InsightType.Price, InsightDirection.Up)) #generate insights for short positions for symbol in self.shorts: insights.append(Insight(symbol, timedelta(30), InsightType.Price, InsightDirection.Down)) return insights def OnSecuritiesChanged(self, algorithm, changes): added = [x for x in changes.AddedSecurities] sortedByPE = sorted(added, key=lambda x: x.Fundamentals.ValuationRatios.PERatio, reverse=True) self.longs = [x.Symbol for x in sortedByPE[:5]] algorithm.Log('LONGS: ' + ', '.join(sorted([x.Value for x in self.longs]))) self.shorts = [x.Symbol for x in sortedByPE[-5:]] algorithm.Log('SHORTS: ' + ', '.join(sorted([x.Value for x in self.shorts])))