<< Sommaire QC | Précédent : QC-Py-Cloud-05-MLP-Forecasting << | Suivant : QC-Py-Cloud-06-PCA-StatArb >>

QC-Py-Cloud-11 — Regime Switching : Momentum in Bull, Defense in Bear

Module: Hands-On AI Trading, Ch.9 — Regime Detection & Adaptive Stratégies

Objectif: Implementer et comparer des variantes de regime switching (bull/bear/sideways) sur un univers multi-actifs, en demontrant l’impact de la detection de regime sur l’allocation.

Approche cloud-native: L’algorithme est execute sur QuantConnect Cloud. Les résultats sont syncs ci-dessous.

Note de conception : Ce notebook est un descriptif pedagogique. Le code executable se trouve dans le projet QuantConnect Cloud correspondant (voir le lien dans le notebook). L’absence d’outputs est intentionnelle.

1. Concept : Regime Switching

Le regime switching est une approche adaptive qui change de stratégie selon le regime de marche detecte (bull, bear, sideways). L’idee est qu’une stratégie optimale en bull market ne l’est pas en bear market.

Detection de regime : On utilise la relation entre le prix de SPY et ses moyennes mobiles : - Bull : Prix > SMA200 ET SMA50 > SMA200 (tendance haussiere confirmee) - Bear : Prix < SMA200 ET SMA50 < SMA200 (tendance baissiere confirmee) - Sideways : Tout autre cas (signals mixtes)

Reference academique

Hamilton (1989) a introduit les modèles a changement de regime (Markov-switching models). Dans notre cas, on utilise une approximation simple (SMA crossover) plutot qu’un modèle probabiliste, mais le principe est le même : le marche alterne entre des etats distincts qui necessitent des stratégies différentes.

Tension pedagogique : complexite vs robustesse

Le regime switching semble elegamment adaptatif. Mais en pratique, la detection de regime est retroactive (on identifie le regime après qu’il a commence). La question est : un signal simple (SMA crossover) suffit-il, ou faut-il une detection plus sophistiquee (HMM, ML) ?

2. Les trois variantes

v1 — Simple Binary Switch

Paramètre Valeur
Univers SPY, QQQ, IEF, GLD
Regime SMA50/200 crossover sur SPY
Bull 100% SPY
Bear/Sideways 100% IEF
Rebalance Mensuel + regime change

Version la plus simple : tout ou rien. En bull, 100% actions. Sinon, 100% obligations intermediaires.

v2 — Regime + Momentum Sélection

Paramètre Valeur
Univers SPY, QQQ, IEF, GLD
Regime SMA50/200 crossover
Bull Top momentum parmi SPY/QQQ (70/30 split)
Bear 50% IEF + 50% GLD
Sideways 30% SPY + 35% IEF + 35% GLD
Momentum Risk-adjusted (return/vol) sur 3 mois
Rebalance Mensuel + regime change

En bull, on selectionne le meilleur actif par momentum ajuste au risque. En bear, on se refugie en defensif diversifie.

v3 — Full Switching (Momentum + Mean-Reversion)

Paramètre Valeur
Univers SPY, QQQ, IEF, GLD
Regime SMA50/200 crossover
Bull Top momentum (70/30)
Bear Mean-reversion RSI<30 + defensif
Sideways 30% SPY + 35% IEF + 35% GLD
Stop-loss Trailing 10% sur positions risky
Rebalance Mensuel + regime change

En bear, au lieu de rester purement defensif, on cherche des opportunites de mean-reversion (RSI < 30) parmi les actifs risky, combinees avec des positions defensives.

Exercice 1 : Detection de regime par SMA crossover

Le regime switching detecte l’etat du marche avec un SMA crossover : prix > SMA200 ET SMA50 > SMA200 = Bull. Prix < SMA200 ET SMA50 < SMA200 = Bear. Autre = Sideways.

Objectif : Implementez detect_regime(prices) qui retourne “BULL”, “BEAR” ou “SIDEWAYS”. Testez sur des series simulees avec des transitions de regime.

Indices : - Indice : Calculer SMA50 et SMA200, puis comparer au prix actuel. - Indice : BULL = prix > SMA200 ET SMA50 > SMA200 (double confirmation).

# Exercice 1 : Detection de regime par SMA crossover
# TODO etudiant : implementer detect_regime(prices) -> str
# Indice : BULL si prix > SMA200 ET SMA50 > SMA200

import numpy as np

def detect_regime(prices):
    # TODO etudiant : calculer SMA50 et SMA200
    # TODO etudiant : comparer au prix actuel
    return None  # TODO etudiant : retourner "BULL", "BEAR" ou "SIDEWAYS"

# Test avec une serie simulee
np.random.seed(42)
sim_prices = 100 + np.cumsum(np.random.randn(300) * 0.5)
result_regime = None  # TODO etudiant : tester detect_regime
print("Exercice a completer : detection de regime")

3. Résultats QC Cloud

Projet QC Cloud: 30823208 (Cloud-RegimeSwitching) Periode: 2014-01-01 au 2025-01-01 (11 ans) Capital initial: $100,000

Version Stratégie Sharpe CAGR MaxDD Net Profit Ordres Win Rate
v1 (Simple Binary) 100% SPY ou 100% IEF 0.488 9.34% 26.1% +167.1% 395 57%
v2 (Momentum Select) Bull: momentum, Bear: defensif 0.622 12.42% 26.8% +262.7% 884 59%
v3 (Full Switching) Bull: mom, Bear: mean-rev 0.603 11.97% 26.8% +247.2% 884 59%

Benchmark : SPY Buy & Hold

Sur la même periode, SPY a un CAGR ~12.8% et un MaxDD ~24%.

Exercice 2 : Allocation adaptive par regime

La v2 adapte l’allocation au regime detecte : en Bull, momentum parmi SPY/QQQ ; en Bear, 50% IEF + 50% GLD ; en Sideways, 30% SPY + 35% IEF + 35% GLD.

Objectif : Implementez adaptive_allocation(regime, momentum_scores) qui retourne un dictionnaire de poids.

Indices : - Indice : En Bull, donner 70% au meilleur momentum et 30% au second. - Indice : En Bear, splitter equitablement entre IEF et GLD.

# Exercice 2 : Allocation adaptive par regime
# TODO etudiant : implementer adaptive_allocation(regime, momentum_scores)
# Indice : BULL -> top momentum 70/30, BEAR -> IEF/GLD 50/50

def adaptive_allocation(regime, momentum_scores=None):
    # momentum_scores : {ticker: score}
    # TODO etudiant : implementer la logique par regime
    return None  # TODO etudiant : retourner {ticker: weight}

scores = {"SPY": 0.08, "QQQ": 0.15, "IEF": 0.02, "GLD": 0.04}
result_adaptive = None  # TODO etudiant : tester pour chaque regime
print("Exercice a completer : allocation adaptive")

4. Analyse : pourquoi le regime switching fonctionne

v1 : Le binaire est déjà bon

La v1 (100% SPY ou 100% IEF selon le regime) atteint déjà un Sharpe de 0.488. C’est mieux que le Risk Parity (0.278) et le Mean Reversion (0.307). Pourquoi :

  1. Evite les bear markets : Quand SPY passe sous le SMA200, on bascule en IEF. Cela protege contre les grosses pertes de 2020 (COVID) et 2022 (rate hikes).

  2. Captation du beta haussier : En bull, on est a 100% en actions, captant la hausse du marche.

  3. Simplicité : Pas de sélection d’actifs complexe, pas de signals multiples. Un seul indicateur (SMA50/200) pilote tout.

Limite : le MaxDD de 26.1% reste eleve car le SMA200 est un signal retarde. Le bear est detecte après que la baisse a commence.

v2 : La sélection momentum ajoute de l’alpha

La v2 ameliore la v1 en selectionnant le meilleur actif par momentum (risk-adjusted) en bull. Le gain est significatif :

  • Sharpe : 0.488 -> 0.622 (+27%)
  • CAGR : 9.34% -> 12.42% (+33%)
  • Net Profit : +167% -> +263% (+57% de profit absolu)

Le momentum sélection entre SPY et QQQ fait la différence : en 2017-2021, QQQ avait un momentum plus fort que SPY, et la stratégie a surpondere QQQ, captant la surperformance tech.

Le bear defensive (50% IEF + 50% GLD) offre une meilleure diversification que 100% IEF seul.

v3 : Le mean-reversion en bear est legerement inferieur

La v3 ajoute du mean-reversion en bear (achat RSI < 30) et un stop-loss trailing. Résultat : Sharpe 0.603 vs 0.622 pour la v2.

Le mean-reversion en bear market est marginalement benefique mais le stop-loss trailing (10%) coupe des positions qui auraient pu se retablir. C’est coherent avec la lecon de Cloud-04 : les mécanismes de protection sont souvent contre-productifs en mean reversion.

Les ordres sont identiques (884) entre v2 et v3, suggérant que le mean-reversion ne declenche pas beaucoup de trades supplémentaires en bear.

5. Lecon principale : la detection de regime est l’edge le plus puissant

Comparaison avec toutes les stratégies cloud :

Stratégie Sharpe CAGR MaxDD Edge
Risk Parity v4 (Cloud-01) 0.278 6.17% 20.4% Allocation inverse-vol
Sector Rotation v3 (Cloud-02) 0.614 10.76% 15.5% Trend multi-asset
Dual Momentum v2 (Cloud-03) 0.392 8.79% 23.6% Momentum + univers
Mean Reversion v2 (Cloud-04) 0.307 5.89% 14.6% RSI + regime filter
Regime Switch v2 (Cloud-05) 0.622 12.42% 26.8% Regime + momentum

Observations :

  1. Le regime switching atteint le meilleur Sharpe (0.622), legerement au-dessus du trend following multi-asset (0.614). C’est la stratégie la plus performante de la serie cloud.

  2. Le CAGR de 12.42% approche SPY (12.8%) mais avec un meilleur ratio rendement/risque.

  3. Le MaxDD de 26.8% est le point faible : plus eleve que le Sector Rotation (15.5%) et le Mean Reversion (14.6%). Le signal SMA200 retarde la detection du bear, laissant passer les premières semaines de baisse.

  4. La combinaison regime + momentum est synergique : le regime filter protege en bear, le momentum optimise en bull. C’est mieux que chaque signal seul.

  5. Le regime switching bat le Dual Momentum (0.622 vs 0.392) car il adapte explicitement la stratégie au regime, tandis que le Dual Momentum n’a qu’un seul signal (momentum 12m).

Exercice 3 : Comparaison des stratégies par ratio de Sharpe

Le regime switching v2 atteint le meilleur Sharpe de la serie cloud (0.622). Pour comparer objectivement les stratégies, le Sharpe ratio est la metrique standard.

Objectif : Implementez sharpe_ratio(returns, risk_free_rate=0.02) qui calcule le Sharpe annualise.

Indices : - Indice : Sharpe = (rendement_moyen - taux_sans_risque) / ecart_type_rendements * sqrt(252). - Indice : Annualiser en multipliant par sqrt(252) pour des rendements quotidiens.

# Exercice 3 : Comparaison des strategies par ratio de Sharpe
# TODO etudiant : implementer sharpe_ratio(returns, rf=0.02) -> float
# Indice : Sharpe = (mean - rf) / std * sqrt(252)

import numpy as np

def sharpe_ratio(returns, risk_free_rate=0.02):
    # returns : array de rendements quotidiens
    # TODO etudiant : calculer le Sharpe annualise
    return None  # TODO etudiant : retourner le Sharpe

np.random.seed(42)
strategies = {
    "Regime Switch": np.random.normal(0.0005, 0.008, 252),
    "Risk Parity": np.random.normal(0.0003, 0.006, 252),
    "Mean Reversion": np.random.normal(0.0002, 0.005, 252),
}
result_sharpe = None  # TODO etudiant : calculer et comparer les Sharpe
print("Exercice a completer : ratio de Sharpe")

6. Code source (v2 — meilleur résultat)

Le code est disponible sur QC Cloud (projet 30823208). Le notebook local ne contient que les résultats et l’analyse, conformement au workflow cloud-native.

# Lien QC Cloud : https://www.quantconnect.com/project/30823208
# Approche : Regime switching (SMA50/200) + risk-adjusted momentum
# Univers : SPY, QQQ, IEF, GLD
# Bull : Top momentum parmi SPY/QQQ (70/30)
# Bear : 50% IEF + 50% GLD
# Sideways : 30% SPY + 35% IEF + 35% GLD
#
# Points cles :
# 1. Detection regime par SMA crossover sur SPY
# 2. Momentum risk-adjusted (return/vol) pour sélection
# 3. Diversification defensive (IEF+GLD, pas IEF seul)
# 4. Rebalance mensuel + trigger sur changement de regime

7. Pour aller plus loin

  1. Hidden Markov Models (HMM) : Remplacer le SMA crossover par un modèle HMM qui estime probabilistement le regime. Plus reactif mais risque de sur-apprentissage.

  2. Multi-asset regime : Detecter le regime sur plusieurs marches (US, Europe, Emerging) pour des signaux diversifies.

  3. VIX-based regime : Utiliser le VIX comme indicateur de regime complementaire (VIX > 25 = bear probable).

  4. Machine Learning regime : Entrainer un classificateur (Random Forest, XGBoost) sur des features de marche pour predire le regime futur.

Reference : Hamilton, J.D. (1989) — “A New Approach to the Economic Analysis of Nonstationary Time Series and the Business Cycle”, Econometrica. Ang, A. & Bekaert, G. (2002) — “Regime Switches in Interest Rates”, Journal of Business & Economic Statistics.

Retour au sommet