| Overall Statistics |
|
Total Orders 1010 Average Win 0.20% Average Loss -0.09% Compounding Annual Return 23.602% Drawdown 10.900% Expectancy 1.557 Start Equity 100000 End Equity 140926.62 Net Profit 40.927% Sharpe Ratio 0.974 Sortino Ratio 1.369 Probabilistic Sharpe Ratio 69.345% Loss Rate 19% Win Rate 81% Profit-Loss Ratio 2.17 Alpha -0.011 Beta 0.986 Annual Standard Deviation 0.115 Annual Variance 0.013 Information Ratio -0.267 Tracking Error 0.047 Treynor Ratio 0.114 Total Fees $1008.62 Estimated Strategy Capacity $5600000.00 Lowest Capacity Asset CCEP WZC7IOQFHS9X Portfolio Turnover 0.90% |
# region imports
from AlgorithmImports import *
# endregion
class TechnicalUniverseOnEtfConstituentsAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2023, 1, 1)
self._rsi_by_symbol = {}
self._previous_symbols = []
self._universe = self.add_universe(self.universe.etf('QQQ', universe_filter_func=self._select_assets))
spy = Symbol.create('SPY', SecurityType.EQUITY, Market.USA)
self.schedule.on(self.date_rules.every_day(spy), self.time_rules.after_market_open(spy, 1), self._trade)
def _select_assets(self, constituents):
for c in constituents:
if c.symbol not in self._rsi_by_symbol:
self._rsi_by_symbol[c.symbol] = RelativeStrengthIndex(14)
elif c.symbol in self._previous_symbols:
self._rsi_by_symbol[c.symbol].update(c.end_time, c.price)
symbols = [c.symbol for c in constituents]
new_symbols = set(symbols) - set(self._previous_symbols)
for bars in self.history[TradeBar](list(new_symbols), 14, Resolution.DAILY):
for symbol, bar in bars.items():
self._rsi_by_symbol[symbol].update(bar.end_time, bar.close)
self._previous_symbols = symbols
return [symbol for symbol, rsi in self._rsi_by_symbol.items() if rsi.is_ready and rsi.current.value < 100/3]
def _trade(self):
if self._universe.selected is None: return
weight = 1 / len(list(self._universe.selected))
self.set_holdings([PortfolioTarget(symbol, weight) for symbol in self._universe.selected], True)