<< Sommaire QC | Précédent : QC-Py-Cloud-03-Risk-Parity << | Suivant : QC-Py-Cloud-05-MLP-Forecasting >>

QC-Py-Cloud-04 — Mean Reversion on Sector ETFs

Module: Hands-On AI Trading, Ch.8 — Mean Reversion & Contrarian Stratégies

Objectif: Implementer et comparer des variantes de mean reversion (retour a la moyenne) sur les ETFs sectoriels GICS, en etudiant l’impact du filtre de regime et du stop-loss sur les performances.

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 : Mean Reversion

Le mean reversion (retour a la moyenne) part de l’hypothese qu’un actif qui s’eloigne significativement de sa tendance historique a une probabilite elevee de revenir vers cette tendance.

Signal : Quand le RSI d’un secteur tombe sous un seuil de survente (ex: RSI < 35-40), le secteur est considere “oversold”. On achete en anticipant un rebond.

Sortie : Quand le RSI remonte au-dessus d’un seuil de sortie (ex: RSI > 55-60), on vend.

Pourquoi les secteurs ?

Les ETFs sectoriels (GICS) presentent un biais mean-reverting plus marque que les actions individuelles : - Les secteurs ont une tendance a revenir vers des poids relatifs stables dans l’indice - Un secteur qui sous-performe fortement est souvent temporaire (rotation sectorielle) - Les ETFs sectoriels sont liquides et ont des historiques longs

Tension pedagogique : mean reversion vs trend following

Le mean reversion est conceptuellement oppose au trend following. En trend following, on achete les actifs qui montent (momentum positif). En mean reversion, on achete les actifs qui ont baisse (anticipation de rebond).

Lecon attendue : Sur un univers d’ETFs sectoriels correles, le mean reversion genere un edge marginal (Sharpe ~0.3) mais reste inferieur au trend following multi-asset (Cloud-02, Sharpe 0.614). Le regime filter (SMA200) est crucial pour eviter d’acheter en bear market.

Exercice 1 : Calcul du RSI sur une serie de prix

Le RSI (Relative Strength Index) mesure la vitesse et l’amplitude des mouvements de prix. Un RSI < 35-40 indique une condition de survente (signal d’achat en mean reversion).

Objectif : Implementez compute_rsi(prices, period=14) qui retourne le RSI actuel. Testez sur une serie simulee avec un mouvement de hausse puis de baisse brutale.

Indices : - Indice : RSI = 100 - 100/(1 + RS), ou RS = moyenne_gain / moyenne_perte. - Indice : Un RSI < 30 est fortement surventu, < 40 est modrement surventu.

# Exercice 1 : Calcul du RSI sur une serie de prix
# TODO etudiant : implementer compute_rsi(prices, period=14) -> float
# Indice : RSI = 100 - 100/(1 + RS), RS = avg_gain / avg_loss

import numpy as np

def compute_rsi(prices, period=14):
    # TODO etudiant : calculer les differences quotidiennes
    # TODO etudiant : separer gains et pertes
    # TODO etudiant : calculer RS puis RSI
    return None  # TODO etudiant : retourner le RSI

# Test : serie avec hausse puis baisse
np.random.seed(42)
test_prices = np.concatenate([100 + np.cumsum(np.random.randn(50)*0.5+0.1),
                               105 + np.cumsum(np.random.randn(30)*0.8-0.3)])
result_rsi = None  # TODO etudiant : calculer le RSI
print("Exercice a completer : calcul du RSI")

2. Les trois variantes

v1 — Pure RSI Mean Reversion

Paramètre Valeur
Univers 11 ETFs sectoriels GICS
Signal RSI(14) < 35 (oversold)
Sortie RSI > 55 ou 20 jours
Positions Top 3, equal-weight (33% chacun)
Filtre regime Aucun
Stop-loss Aucun
Rebalance Quotidien (verification)

v2 — RSI + SMA200 Regime Filter

Paramètre Valeur
Univers 11 ETFs sectoriels GICS
Signal RSI(14) < 40 (oversold)
Sortie RSI > 60 ou 15 jours
Positions Top 4, equal-weight (25% chacun)
Filtre regime Prix > SMA200 (sinon liquidation totale)
Stop-loss Aucun
Rebalance Quotidien (verification)

Changement cle : L’ajout d’un filtre de regime (SMA200) protege contre les achats en bear market prolonge. Quand le prix est sous le SMA200, on liquide tout.

v3 — RSI + SMA200 + Stop-Loss

Paramètre Valeur
Univers 11 ETFs sectoriels GICS
Signal RSI(14) < 40 (oversold)
Sortie RSI > 60 ou 15 jours
Positions Top 4, equal-weight (25% chacun)
Filtre regime Prix > SMA200
Stop-loss 8% (trailing)
Rebalance Quotidien (verification)

3. Résultats QC Cloud

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

Version Filtre Sharpe CAGR MaxDD Net Profit Ordres Win Rate
v1 (Pure RSI) Aucun 0.288 7.07% 42.4% +112.1% 417 67%
v2 (RSI+SMA200) SMA200 0.307 5.89% 14.6% +87.8% 694 59%
v3 (RSI+SMA200+Stop) SMA200 + 8% stop 0.278 5.60% 14.7% +82.1% 702 58%

Benchmark : SPY Buy & Hold

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

4. Analyse : regime filter et stop-loss

v1 : Le piege du mean reversion sans protection

La v1 (pure RSI, pas de filtre) achete aveugleement tout secteur en survente. Le CAGR de 7.07% semble correct, mais le MaxDD de 42.4% est catastrophique.

Pourquoi : En 2020 (COVID), presque tous les secteurs sont passes en survente simultanement. La stratégie a achete massivement au mauvais moment. En 2022 (bear market tech), la même chose s’est reproduite : XLK, XLY, XLF etaient en survente mais continuaient de chuter.

Le mean reversion sans filtre de regime est un “catching falling knives” (attraper des couteaux qui tombent).

v2 : L’impact massif du regime filter

La v2 ajoute un seul filtre : ne rien acheter si le prix est sous le SMA200. Ce filtre reduit : - Le MaxDD de 42.4% a 14.6% (division par 3) - Le CAGR de 7.07% a 5.89% (cout modeste) - Le Sharpe ameliore de 0.288 a 0.307

Pourquoi le regime filter fonctionne si bien : Le SMA200 identifie les bear markets. Quand un secteur est en bear (prix < SMA200), son RSI bas ne signifie pas “rebond imminent” mais plutot “vente massive en cours”. Ne pas acheter en bear market est la protection la plus efficace pour le mean reversion.

Note : le win rate baisse de 67% a 59%, mais les pertes sont beaucoup plus petites (les trades perdants sont limites par le filtre).

v3 : Le stop-loss degrade la performance

Contre-intuitivement, le stop-loss a 8% degrade legerement la performance (Sharpe 0.278 vs 0.307). Le MaxDD est quasi-identique (14.7% vs 14.6%).

Pourquoi : Le mean reversion achete par definition des actifs qui ont baisse. Un stop-loss a 8% declenche souvent sur des fluctuations normales après l’achat, avant que le rebond ne se materialise. C’est le même problème que le drawdown cap dans Cloud-01 : les mécanismes de protection empechent la recuperation.

Le stop-loss transforme des pertes temporaires (recoverables) en pertes permanentes.

Exercice 2 : Filtre de regime SMA200

Le regime filter est la différence entre le mean reversion dangereux (v1, MaxDD 42.4%) et le mean reversion viable (v2, MaxDD 14.6%). L’ajout d’un seul filtre – ne pas acheter si prix < SMA200 – divise le MaxDD par 3.

Objectif : Implementez qui retourne True si le marche est en regime haussier (prix > SMA). Combinez avec le RSI pour ne generer des signaux d’achat que quand RSI < 40 ET regime = haussier.

Indices : - Indice : Prix > SMA200 = regime haussier. Prix < SMA200 = bear market. - Indice : En bear market, un RSI bas ne signifie pas rebond imminent mais vente massive en cours.

# Exercice 2 : Filtre de regime SMA200
# TODO etudiant : implementer regime_filter(prices, sma_period=200)
# TODO etudiant : combiner avec RSI pour generer des signaux filtres
# Indice : acheter seulement si RSI < 40 ET prix > SMA200

def mean_reversion_signal(prices, rsi_period=14, rsi_threshold=40, sma_period=200):
    # TODO etudiant : calculer RSI et SMA
    # TODO etudiant : retourner ACHAT si RSI < threshold ET prix > SMA
    return None  # TODO etudiant : retourner le signal

result_regime = None  # TODO etudiant : tester le signal
print("Exercice a completer : filtre de regime SMA200")

Exercice 3 : Impact du stop-loss sur le mean reversion

Contre-intuitivement, le stop-loss a 8% degrade la performance en mean reversion (Sharpe 0.278 vs 0.307). Le mean reversion achete des actifs qui ont baisse ; un stop-loss declenche souvent avant le rebond.

Objectif : Simulez 50 trades de mean reversion. Chaque trade achete après une baisse de 5-15% et attend le rebond. Comparez deux stratégies : (a) sans stop-loss, (b) avec stop-loss a 8%. Calculez le taux de trades coupes inutilement (rebond après le stop).

Indices : - Indice : Simulez le prix post-achat comme un mouvement brownien avec un biais positif (mean reversion). - Indice : Un stop a 8% sous l’achat se declenche si le prix descend de 8% avant de remonter.

# Exercice 3 : Impact du stop-loss sur le mean reversion
# TODO etudiant : simuler 50 trades de mean reversion avec et sans stop-loss
# Indice : comparer le nombre de trades coupes inutilement

import numpy as np

def simulate_mean_rev_trades(n_trades=50, stop_loss=0.08, seed=42):
    np.random.seed(seed)
    # TODO etudiant : pour chaque trade, simuler le chemin post-achat
    # TODO etudiant : avec stop-loss, couper si prix tombe a -8%
    return None  # TODO etudiant : retourner resultats avec/sans stop

result_stop = None  # TODO etudiant : lancer la simulation
print("Exercice a completer : impact du stop-loss")

5. Lecon principale : le mean reversion a un edge marginal sur secteurs

Le mean reversion sur ETFs sectoriels genere un Sharpe de 0.307 (meilleur cas). Comparaison avec les autres stratégies cloud :

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

Observations :

  1. Le mean reversion est inferieur au trend following : Le trend following (Cloud-02, Sharpe 0.614) surpasse largement le mean reversion (Cloud-04, Sharpe 0.307) sur le même univers d’ETFs. Les secteurs en momentum positif ont plus de persistance que les secteurs en survente n’ont de probabilite de rebond.

  2. Le regime filter est obligatoire : Sans filtre (v1), le MaxDD explose (42.4%). Avec filtre (v2), le MaxDD tombe a 14.6%. C’est la différence entre une stratégie viable et une stratégie dangereuse.

  3. Le stop-loss est contre-productif en mean reversion : Les actifs achetes en survente ont besoin de temps pour se retourner. Le stop-loss coupe les positions avant le rebond.

  4. Le mean reversion bat le Risk Parity (Sharpe 0.307 vs 0.278) mais reste loin du Dual Momentum et du trend following multi-asset. L’edge est marginal et depend entierement du regime filter.

6. Code source (v2 — meilleur compromis)

Le code est disponible sur QC Cloud (projet 30822855). 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/30822855
# Approche : RSI(14) mean reversion + SMA200 regime filter
# Univers : 11 ETFs sectoriels GICS
# Filtre : RSI < 40 (achat), RSI > 60 (vente), prix > SMA200 (regime)
# Positions : Top 4 equal-weight, 15 jours max hold
#
# Points cles :
# 1. Le regime filter (SMA200) protege contre les bear markets
# 2. 4 positions simultanees = diversification suffisante
# 3. Pas de stop-loss (contre-productif en mean reversion)

7. Pour aller plus loin

  1. Volatility-adjusted RSI : Normaliser le RSI par la volatilite recente. Un RSI de 35 en periode de haute volatilite n’a pas la même signification qu’en periode calme.

  2. Mean reversion multi-signal : Combiner RSI avec Bollinger Bands et MACD pour confirmer le signal de survente.

  3. Adaptive oversold threshold : Ajuster le seuil RSI selon le regime de marche (plus agressif en bull, plus conservateur en bear).

  4. Pairs trading sectoriel : Au lieu d’acheter un secteur en survente, acheter le secteur en survente et vendre le secteur en surachat (long/short).

Reference : De Bondt, W. & Thaler, R. (1985) — “Does the Stock Market Overreact?”, Journal of Finance. Jegadeesh, N. (1990) — “Evidence of Predictable Behavior of Security Returns”, Journal of Finance.

Retour au sommet