Overall Statistics |
Total Trades 1643 Average Win 0.12% Average Loss -0.24% Compounding Annual Return -14.163% Drawdown 57.600% Expectancy -0.105 Net Profit -21.022% Sharpe Ratio -0.215 Probabilistic Sharpe Ratio 3.424% Loss Rate 40% Win Rate 60% Profit-Loss Ratio 0.50 Alpha -0.126 Beta 1.211 Annual Standard Deviation 0.289 Annual Variance 0.083 Information Ratio -0.493 Tracking Error 0.233 Treynor Ratio -0.051 Total Fees $1704.62 Estimated Strategy Capacity $3400000.00 Lowest Capacity Asset LNTH W1O47LFNB1PH |
# region imports from AlgorithmImports import * # endregion class PensiveSkyBlueBison(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 5, 17) # Set Start Date self.SetEndDate(2022, 12, 1) self.SetCash(100000) # Set Strategy Cash self.SetBenchmark("VHT") self.factor_by_symbol = {} self.universe_symbols = [] self.market_cap_threshold = int(self.GetParameter("market_cap_threshold")) self.universe_size = int(self.GetParameter("universe_size")) self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.CoarseFilterFunction, self.FineFundamentalFunction) # 300-day warm self.SetWarmUp(300, Resolution.Daily) def CoarseFilterFunction(self, coarse): for item in coarse: symbol = item.Symbol if symbol not in self.factor_by_symbol: self.factor_by_symbol[symbol] = Factor() self.factor_by_symbol[symbol].Update(item.EndTime, item.AdjustedPrice) if self.IsWarmingUp: return Universe.Unchanged return [c.Symbol for c in coarse if c.HasFundamentalData] def FineFundamentalFunction(self, fine): selected = {} for item in fine: if item.MarketCap > self.market_cap_threshold and item.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Healthcare: symbol = item.Symbol factor = self.factor_by_symbol[symbol] if factor.IsReady and factor.ScaledDelta > 0: selected[symbol] = factor self.universe_symbols = [kvp[0] for kvp in sorted(selected.items(), key = lambda kvp: kvp[1].ScaledDelta, reverse=True)[:self.universe_size]] return self.universe_symbols def OnData(self, slice): weight = 1 / len(self.universe_symbols) self.SetHoldings([PortfolioTarget(symbol, weight) for symbol in self.universe_symbols]) def OnSecuritiesChanged(self, changes): for security in changes.RemovedSecurities: self.Liquidate(security.Symbol) class Factor: def __init__(self): self.IsReady = False self.ScaledDelta = -999 self.fast_ema = ExponentialMovingAverage(100) self.slow_ema = ExponentialMovingAverage(300) def Update(self, time, value): self.IsReady = self.slow_ema.Update(time, value) & self.fast_ema.Update(time, value) if self.IsReady: fast = self.fast_ema.Current.Value slow = self.slow_ema.Current.Value self.ScaledDelta = (fast - slow) / ((fast + slow) / 2) return self.IsReady