Overall Statistics |
Total Trades 280 Average Win 0.10% Average Loss -0.19% Compounding Annual Return 28.245% Drawdown 12.400% Expectancy 0.308 Net Profit 27.460% Sharpe Ratio 1.087 Sortino Ratio 1.497 Probabilistic Sharpe Ratio 65.861% Loss Rate 13% Win Rate 87% Profit-Loss Ratio 0.51 Alpha 0 Beta 0 Annual Standard Deviation 0.135 Annual Variance 0.018 Information Ratio 1.473 Tracking Error 0.135 Treynor Ratio 0 Total Fees $331.97 Estimated Strategy Capacity $12000000.00 Lowest Capacity Asset SGEN S2TCB9V1OIG5 Portfolio Turnover 0.50% |
# region imports from AlgorithmImports import * # endregion TICKER = "QQQE" class ETF_Debug(QCAlgorithm): def Initialize(self): self.SetStartDate(2023, 1, 8) # Set Start Date self.SetEndDate(2024, 1, 1) self.SetCash(1000000) # Set Strategy Cash self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.SetSecurityInitializer(self.CustomSecurityInitializer) self.SetWarmup(timedelta(1)) self.UniverseSettings.Resolution = Resolution.Minute self.AddUniverse(self.Universe.ETF(TICKER, Market.USA, self.UniverseSettings, self.ETFConstituentsFilter)) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 30), self.CheckSecurities) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15,30), self.Rebalance) self.selected = [] def CustomSecurityInitializer(self, security: Security): seeder = FuncSecuritySeeder(self.GetLastKnownPrices) seeder.SeedSecurity(security) def ETFConstituentsFilter(self, constituents: List[ETFConstituentData]) -> List[Symbol]: for c in constituents: if c.Weight is None: self.Log(f"{c.Symbol} weight is None, skipping!") if len(list(constituents)) > 100: self.Log(f"{len(list(constituents))} constituents in filter!") self.selected = [c.Symbol for c in constituents] return self.selected def OnSecuritiesChanged(self, changes: SecurityChanges) -> None: if 0 < len(changes.AddedSecurities) < 90: line = ", ".join([f"{x.Symbol.Value}" for x in changes.AddedSecurities]) self.Log(f"{line} were added to universe") if len(changes.RemovedSecurities) > 0: line = ", ".join([f"{x.Symbol.Value}" for x in changes.RemovedSecurities]) self.Log(f"{line} were removed from universe") def CheckSecurities(self): if self.ActiveSecurities.Count > 0 and self.ActiveSecurities.Count > 100: self.Log(f"Active securities count = {self.ActiveSecurities.Count}!") for s in self.selected: if s not in self.ActiveSecurities: self.Log(f"{s.Value} is not in ActiveSecurities!") def Rebalance(self): if self.Securities.Count == 0 or len(self.selected) == 0: return if self.Securities.Values[0].Exchange.DateIsOpen(self.Time+timedelta(1)): return targets = [PortfolioTarget(x, 1/len(self.selected)) for x in self.selected] self.SetHoldings(targets, liquidateExistingHoldings=True)