| Overall Statistics |
|
Total Trades 288 Average Win 0.09% Average Loss -0.17% Compounding Annual Return 28.767% Drawdown 12.100% Expectancy 0.293 Net Profit 27.967% Sharpe Ratio 1.113 Sortino Ratio 1.549 Probabilistic Sharpe Ratio 66.904% Loss Rate 16% Win Rate 84% Profit-Loss Ratio 0.55 Alpha 0 Beta 0 Annual Standard Deviation 0.135 Annual Variance 0.018 Information Ratio 1.5 Tracking Error 0.135 Treynor Ratio 0 Total Fees $454.03 Estimated Strategy Capacity $13000000.00 Lowest Capacity Asset SGEN S2TCB9V1OIG5 Portfolio Turnover 0.53% |
# region imports
from AlgorithmImports import *
# endregion
TICKER = "QQQ"
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.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)