Overall Statistics
Total Orders
558
Average Win
0.14%
Average Loss
-0.04%
Compounding Annual Return
54.376%
Drawdown
17.900%
Expectancy
2.486
Start Equity
100000
End Equity
198571.56
Net Profit
98.572%
Sharpe Ratio
1.719
Sortino Ratio
2.124
Probabilistic Sharpe Ratio
85.564%
Loss Rate
18%
Win Rate
82%
Profit-Loss Ratio
3.27
Alpha
0.08
Beta
1.728
Annual Standard Deviation
0.186
Annual Variance
0.035
Information Ratio
2.036
Tracking Error
0.089
Treynor Ratio
0.185
Total Fees
$556.00
Estimated Strategy Capacity
$1500000.00
Lowest Capacity Asset
BMY R735QTJ8XC9X
Portfolio Turnover
0.74%
from AlgorithmImports import *

class FactorSectorRotationAlgorithm(QCAlgorithm):
    def initialize(self):
        self.set_start_date(2023, 2, 26)
        self.universe_settings.schedule.on(self.date_rules.month_start())
        self._universe = self.add_universe(lambda fundamental: [f.symbol for f in sorted(fundamental, key=lambda f: f.market_cap, reverse=True)[:50]])
        self.schedule.on(self.date_rules.month_start(), self.time_rules.at(9, 30), self.rebalance)
        
    def rebalance(self):
        factor_scores = {sector_code: [0, 0] for sector_code in [101, 102, 103, 104, 205, 206, 207, 308, 309, 310, 311]}
        factors = self.history[KavoutCompositeFactorBundle](list(self._universe.members.keys), 1, Resolution.DAILY)
        for row in factors:
            for data in row:
                factor_scores[self.securities[data.key].fundamentals.asset_classification.morningstar_sector_code][0] += data.value.growth + data.value.value_factor \
                    + data.value.quality + data.value.momentum + data.value.low_volatility
                factor_scores[self.securities[data.key].fundamentals.asset_classification.morningstar_sector_code][1] += 1

        factor_scores_sum = sum(abs(x[0]) for x in factor_scores.values())
        if factor_scores_sum:
            self.set_holdings([PortfolioTarget(x.key, 2 * factor_scores[x.value.fundamentals.asset_classification.morningstar_sector_code][0] / factor_scores_sum \
                / factor_scores[x.value.fundamentals.asset_classification.morningstar_sector_code][1]) for x in self._universe.members
                if factor_scores[x.value.fundamentals.asset_classification.morningstar_sector_code][1] != 0])