Overall Statistics
Total Orders
4561
Average Win
0.16%
Average Loss
-0.12%
Compounding Annual Return
-10.878%
Drawdown
31.500%
Expectancy
-0.060
Start Equity
100000
End Equity
82805.52
Net Profit
-17.194%
Sharpe Ratio
-0.606
Sortino Ratio
-0.701
Probabilistic Sharpe Ratio
2.003%
Loss Rate
60%
Win Rate
40%
Profit-Loss Ratio
1.33
Alpha
-0.263
Beta
1.085
Annual Standard Deviation
0.187
Annual Variance
0.035
Information Ratio
-1.708
Tracking Error
0.147
Treynor Ratio
-0.104
Total Fees
$6134.40
Estimated Strategy Capacity
$14000000.00
Lowest Capacity Asset
BHGE WLXQGVHQ03MT
Portfolio Turnover
50.61%
# region imports
from AlgorithmImports import *
# endregion


class TechnicalUniverseOnEtfConstituentsAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2023, 1, 1)
        etf = Symbol.create('QQQ', SecurityType.EQUITY, Market.USA)
        self._universe = self.add_universe(self.universe.etf(etf, universe_filter_func=self._select_assets))
        self.schedule.on(self.date_rules.every_day(etf), self.time_rules.after_market_open(etf, 1), self._trade)
        self._rsi_period = self.get_parameter('rsi_period', 14)
        self._rsi_threshold = self.get_parameter('rsi_threshold', 30)

    def _select_assets(self, constituents):
        symbols = []
        for c in constituents:
            history = self.indicator_history(RelativeStrengthIndex(self._rsi_period), c.symbol, 1, Resolution.DAILY).current
            if history and history[-1].value < self._rsi_threshold:
                symbols.append(c.symbol)
        return symbols

    def _trade(self):
        if not list(self._universe.selected): return
        weight = 1 / len(list(self._universe.selected))
        self.set_holdings([PortfolioTarget(symbol, weight) for symbol in self._universe.selected], True)