# 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")<< 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).
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 :
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).
Captation du beta haussier : En bull, on est a 100% en actions, captant la hausse du marche.
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 :
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.
Le CAGR de 12.42% approche SPY (12.8%) mais avec un meilleur ratio rendement/risque.
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.
La combinaison regime + momentum est synergique : le regime filter protege en bear, le momentum optimise en bull. C’est mieux que chaque signal seul.
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 regime7. Pour aller plus loin
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.
Multi-asset regime : Detecter le regime sur plusieurs marches (US, Europe, Emerging) pour des signaux diversifies.
VIX-based regime : Utiliser le VIX comme indicateur de regime complementaire (VIX > 25 = bear probable).
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.