Overall Statistics |
Total Orders 1579 Average Win 0.31% Average Loss -0.30% Compounding Annual Return 15.910% Drawdown 14.100% Expectancy 0.129 Start Equity 1000000 End Equity 1359330.74 Net Profit 35.933% Sharpe Ratio 0.605 Sortino Ratio 0.473 Probabilistic Sharpe Ratio 41.420% Loss Rate 44% Win Rate 56% Profit-Loss Ratio 1.03 Alpha 0.052 Beta 0.467 Annual Standard Deviation 0.126 Annual Variance 0.016 Information Ratio 0.18 Tracking Error 0.132 Treynor Ratio 0.163 Total Fees $5068.74 Estimated Strategy Capacity $25000000.00 Lowest Capacity Asset MTUM VFUDGZIY8ZMT Portfolio Turnover 12.23% |
#region imports from AlgorithmImports import * #endregion from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Algorithm.Framework") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Orders import * from QuantConnect.Algorithm import * from QuantConnect.Algorithm.Framework import * from QuantConnect.Algorithm.Framework.Selection import * from Alphas.HistoricalReturnsAlphaModel import HistoricalReturnsAlphaModel from QuantConnect.Algorithm.Framework.Execution import * from QuantConnect.Algorithm.Framework.Risk import * #from Portfolio.BlackLittermanOptimizationPortfolioConstructionModel import * #from Portfolio.UnconstrainedMeanVariancePortfolioOptimizer import UnconstrainedMeanVariancePortfolioOptimizer #from Risk.NullRiskManagementModel import NullRiskManagementModel #from Alphas.EmaCrossAlphaModel import EmaCrossAlphaModel #from Alphas.HistoricalReturnsAlphaModel import HistoricalReturnsAlphaModel #from Alphas.MacdAlphaModel import MacdAlphaModel #from Alphas.RsiAlphaModel import RsiAlphaModel #from Alphas.ConstantAlphaModel import ConstantAlphaModel from collections import deque from AlgorithmImports import * class EnergeticSkyBlueFrog(QCAlgorithm): def Initialize(self): self.SetStartDate(2022, 3, 1) self.SetEndDate(2024,3,31) self._cash= 1000000 self.SetCash(self._cash) #self.SetWarmUp(5) self.UniverseSettings.Resolution = Resolution.Daily symbols = [ # OUR INVESTMENT UNIVERSE # FACTORS Symbol.Create("USMV", SecurityType.Equity, Market.USA), Symbol.Create("DGRO", SecurityType.Equity, Market.USA), Symbol.Create("QUAL", SecurityType.Equity, Market.USA), Symbol.Create("DVY", SecurityType.Equity, Market.USA), Symbol.Create("MTUM", SecurityType.Equity, Market.USA), Symbol.Create("VLUE", SecurityType.Equity, Market.USA), Symbol.Create("TLT", SecurityType.Equity, Market.USA)] self.SetUniverseSelection(ManualUniverseSelectionModel(symbols)) self.AddAlpha(HistoricalReturnsAlphaModel(2, resolution = Resolution.Daily)) self.AddAlpha(EmaCrossAlphaModel(fastPeriod=5, slowPeriod=10, resolution = Resolution.Daily )) self.AddAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(days = 1), 0.025, None)) optimizer = UnconstrainedMeanVariancePortfolioOptimizer() self.SetPortfolioConstruction(BlackLittermanOptimizationPortfolioConstructionModel(optimizer = optimizer, tau=0.10)) self.SetExecution(ImmediateExecutionModel()) #self.AddRiskManagement(MaximumDrawdownPercentPortfolio(0.05, isTrailing=False)) self.riskManagement = TrailingPeriodDrawdownRiskManagementModel(0.03, 10) # 10 trading days as trailing period self.AddRiskManagement(self.riskManagement) self._benchmark = self.AddEquity("SPY", Resolution.Daily).Symbol self._benchmarkInitial = self.History(self._benchmark, 1, Resolution.Daily) self._benchmarkPrice = self._benchmarkInitial['close'][0] def OnData(self,data): self.Plot("Relative Performance", "SPY", self._cash*self.Securities["SPY"].Close/self._benchmarkPrice) self.Plot("Relative Performance", "Portfolio Value", self.Portfolio.TotalPortfolioValue) class TrailingPeriodDrawdownRiskManagementModel(RiskManagementModel): def __init__(self, maxDrawdownPercent, trailingPeriod): self.maxDrawdownPercent = maxDrawdownPercent self.trailingPeriod = trailingPeriod self.portfolioHighs = deque(maxlen=trailingPeriod) def ManageRisk(self, algorithm, targets): currentPortfolioValue = algorithm.Portfolio.TotalPortfolioValue self.portfolioHighs.append(currentPortfolioValue) trailingMax = max(self.portfolioHighs) if currentPortfolioValue < trailingMax * (1 - self.maxDrawdownPercent): # Liquidate all positions if drawdown exceeds the limit return [PortfolioTarget(symbol, 0) for symbol in algorithm.Portfolio.Keys] return []