Overall Statistics |
Total Trades 1634 Average Win 0.08% Average Loss -0.04% Compounding Annual Return 42.377% Drawdown 11.500% Expectancy 1.028 Net Profit 42.377% Sharpe Ratio 1.722 Probabilistic Sharpe Ratio 78.601% Loss Rate 38% Win Rate 62% Profit-Loss Ratio 2.28 Alpha 0.357 Beta -0.227 Annual Standard Deviation 0.177 Annual Variance 0.031 Information Ratio 0.344 Tracking Error 0.223 Treynor Ratio -1.342 Total Fees $1695.11 |
""" Shareholder Yield Algo. This is for learning the QuantConnect Algo Framework. I don't expect it to be useful outside of that. The goal of this algo is: - create a universe of liquid stocks with the best share holder yield (dividends + buybacks) relative to the market. - buy an equal weighted portfolio of these stocks. - rebalance monthly based on share holder yield. Classes: - ShareHolderYieldAlgo() is the main class that configures and instantiates the QuantConnect algo framework. - LiquidTotalYieldUniverseSelectionModel() is a class which creates a liquid universe of stocks ranking by dollar volume, then filters the list down for the top X yielders based on share holder yield. - LongShareHolderYieldAlphaModel() is an alpha model class which emits buy and sell signals based on changes to the universe selection. """ from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel class ShareHolderYieldAlgo(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 1, 1) # Set Start Date self.SetEndDate(2020, 1, 1) self.SetCash(100000) # Set Strategy Cash self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverseSelection(LiquidTotalYieldUniverseSelectionModel()) self.AddAlpha(LongShareHolderYieldAlphaModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetExecution(ImmediateExecutionModel()) class LiquidTotalYieldUniverseSelectionModel(FundamentalUniverseSelectionModel): def __init__(self): super().__init__(True, None, None) self.lastMonth = -1 # Use this to determined how many stocks we take off the dollar volume sorted list. self.dollarVolumeListSize = 200 # Number of securities to select and return from universe. self.selectionSize = 10 def SelectCoarse(self, algorithm, coarse): if self.lastMonth == algorithm.Time.month: return Universe.Unchanged self.lastMonth = algorithm.Time.month sortedByDollarVolume = sorted([x for x in coarse if x.HasFundamentalData], key=lambda x: x.DollarVolume, reverse=True) return [x.Symbol for x in sortedByDollarVolume[:self.dollarVolumeListSize]] def SelectFine(self, algorithm, fine): sortedByYields = sorted(fine, key=lambda f: f.ValuationRatios.TotalYield, reverse=True) return [f.Symbol for f in sortedByYields][:self.selectionSize] class LongShareHolderYieldAlphaModel(AlphaModel): def __init__(self): self.lastMonth = -1 # Average number of trading days per month self.signalTimeDelta = timedelta(days = 21) self.symbols = [] def Update(self, algorithm, data): insights = [] # Skip if we have already run this month. if self.lastMonth == algorithm.Time.month: return insights self.lastMonth = algorithm.Time.month for symbol in self.symbols: insights.append(Insight.Price(symbol, self.signalTimeDelta, InsightDirection.Up)) return insights def OnSecuritiesChanged(self, algorithm, changes): for security in changes.AddedSecurities: symbol = security.Symbol if symbol not in self.symbols: self.symbols.append(security.Symbol) for security in changes.RemovedSecurities: self.symbols.remove(security.Symbol)