Série Algo Trading — De 100K au Million — Partie 6 sur 12

Stratégies Momentum Cross-Region

4 stratégies momentum en production : Cross-Section Momentum (CSM), Time-Series Momentum (TSMOM), Post-Earnings Drift (PEAD), et Industry Rotation. Backtest 2010-2025, code complet, et métriques réelles.

4 Stratégies Sharpe 0.9-1.5 US + EU + APAC Code Complet
Algo Trading — De 100K au Million6/12
Vue globaleCross-SectionTime-SeriesPEADIndustry RotBacktests
Vue d'ensemble — Le moteur du portefeuille

Pourquoi le momentum est le facteur le plus rentable

Le momentum est le facteur le mieux documenté en finance (Jegadeesh & Titman, 1993). Les actions qui ont bien performé sur les 3-12 derniers mois tendent à continuer de bien performer sur les 1-6 prochains mois. Ce phénomène persiste depuis 200 ans, sur tous les marchés, toutes les classes d'actifs.

Pourquoi le momentum fonctionne (et continuera de fonctionner)

  • Sous-réaction : Les investisseurs mettent du temps à intégrer les bonnes nouvelles → le prix monte progressivement
  • Herding : Les institutionnels achètent les gagnants → feedback positif auto-renforçant
  • Disposition effect : Les particuliers vendent les gagnants trop tôt, gardent les perdants → les gagnants restent sous-évalués
  • Structurel : Les ETF et les fonds indiciels achètent mécaniquement les actions dont le poids augmente (momentum implicite)

Le momentum a un risque connu : les crashs de momentum (ex : mars 2009, novembre 2020). C'est pourquoi on combine avec mean-reversion et dual momentum (Partie 7 et 8).

Nos 4 stratégies momentum et leur rôle

StratégieUniversHoldingRôleAllocation typique
Cross-Section Momentum1500 actions US+EU+APAC1 moisMoteur principal (stock-picking)20%
Time-Series Momentum50 ETF sectoriels + pays1-3 moisDirection macro16%
Post-Earnings DriftActions post-earnings surprise5-20 joursAlpha événementiel15%
Industry Rotation11 secteurs GICS1 moisRotation cyclique14%
Stratégie 1 — Cross-Section Momentum

Cross-Section Momentum (CSM) — Le classique revisité

CSM est la stratégie la plus classique : acheter les gagnants, éviter les perdants. Notre version l'enrichit avec un momentum composite multi-facteurs et un filtre de qualité pour éviter les "momentum traps".

Signal composite momentum

claude -p "Implémente CSMStrategy dans strategies/csm.py :

class CSMStrategy(BaseStrategy):
    '''Cross-Section Momentum — Buy winners, avoid losers.

    Univers:
    - Fetch les 1500 actions les plus liquides (ADV > $5M) des marchés:
      US (NYSE+NASDAQ), EU (Euronext+Xetra+LSE), APAC (TSE+HKEX+ASX)
    - Exclure: financials, utilities, REITs, biotech pre-revenue
    - Exclure: actions en earnings dans les 5 prochains jours
    - Exclure: actions avec short_interest > 20%

    Signal momentum composite (score 0-100):
      score = 0.40 × rank(MOM_12_1) +     # Momentum 12M excl dernier mois
              0.25 × rank(MOM_6_1) +       # Momentum 6M excl dernier mois
              0.20 × rank(ACCEL_MOM) +     # Accélération (MOM_3M - MOM_6_3)
              0.15 × rank(HIGH_PROX)       # Proximité du 52W High

    Filtre qualité (obligatoire, élimine les momentum traps):
      - ROE > 5% (exclure les zombies qui montent sur du short squeeze)
      - Debt/Equity < 3 (exclure les surendettés)
      - Revenue growth > -20% (exclure les entreprises en déclin)

    Portfolio construction:
    - Top 30 actions par score composite (après filtres)
    - Poids: Kelly fractionnel × HRP (voir Partie 4)
    - Contraintes: max 10% par position, max 30% par secteur
    - Rebalancement: mensuel (premier lundi du mois)
    - Slippage budget: 5 bps US, 15 bps EU, 25 bps APAC

    Anti-overfitting:
    - Walk-forward: 5 ans IS / 1 an OOS, rolling annual
    - CPCV avec 10 splits
    - Deflated Sharpe Ratio > 0.5 requis
    '''

    def generate_signals(self) -> pd.DataFrame:
        '''Retourne un DataFrame avec colonnes [symbol, score, region, sector]
        trié par score décroissant. Top 30 = positions.'''

    def backtest(self, start='2010-01-01', end='2025-12-31') -> BacktestResult:
        '''Backtest walk-forward avec rebalancement mensuel.
        Retourne: CAGR, Sharpe, MaxDD, Calmar, turnover, hit_rate'''
"

Résultats du backtest CSM (2010-2025)

MétriqueCSM Long-OnlySPY (benchmark)Excès
CAGR24.3%13.2%+11.1%
Sharpe Ratio1.350.72+0.63
Max Drawdown-22.1%-33.9%11.8% mieux
Calmar Ratio1.100.39+0.71
Win Rate (mois)64%62%+2%
Turnover annuel180%5%
Nombre positions moy28500+
Hit rate (trades)52%
Avg win / Avg loss1.8

Le momentum crash de mars 2020

CSM a subi un drawdown de -22.1% en mars 2020 (COVID). C'est le talon d'Achille du momentum : quand le marché se retourne violemment, les gagnants récents chutent plus que le marché. C'est exactement pourquoi on combine avec mean-reversion (Partie 7) et un détecteur de régime (Partie 9) qui réduit l'allocation momentum en Risk-Off.

Stratégie 2 — Time-Series Momentum

Time-Series Momentum (TSMOM) — Trend following sur ETF

Contrairement au CSM (relatif : "quoi acheter"), le TSMOM est absolu : "faut-il être investi ?". Si un actif a un trend positif → long. Si négatif → cash (on ne shorte pas, contrainte long-only).

Signal TSMOM

claude -p "Implémente TSMOMStrategy dans strategies/tsmom.py :

class TSMOMStrategy(BaseStrategy):
    '''Time-Series Momentum sur un univers d'ETF.

    Univers (50 ETF):
    US sectoriels: XLK, XLV, XLF, XLE, XLI, XLY, XLP, XLU, XLB, XLRE, XLC
    US thématiques: QQQ, ARKK, ICLN, SMH, XBI, IYR, KRE
    Europe: VGK, EWG, EWQ, EWU, EWI, EWP, EWN, EWL
    APAC: EWJ, EWY, EWH, EWA, EWT, MCHI
    Commodities: GLD, SLV, USO, UNG, DBA, DBC
    Fixed Income: TLT, IEF, SHY, HYG, LQD
    Volatility: SVXY

    Signal par ETF:
    trend_score = (0.5 × sign(r_12m) + 0.3 × sign(r_6m) + 0.2 × sign(r_3m))
    - Si trend_score > 0.3 → LONG (allocation = trend_score × kelly_weight)
    - Si trend_score <= 0.3 → CASH (pas de position)

    Volatility targeting:
    - Chaque ETF est scalé pour contribuer 10% de vol annualisée
    - weight_i = target_vol / realized_vol_i × trend_score_i
    - Cela donne naturellement plus de poids aux ETF calmes (utilities, bonds)
      et moins aux ETF volatils (ARKK, USO)

    Rebalancement: bi-mensuel (1er et 15 de chaque mois)
    '''
"

Résultats TSMOM (2010-2025)

MétriqueTSMOM60/40 (benchmark)
CAGR16.8%8.5%
Sharpe1.100.62
Max DD-14.5%-20.8%
Calmar1.160.41
% en cash (moyen)25%0%
Positions moyennes18/502

Le TSMOM a un drawdown maximum nettement inférieur au 60/40 grâce à sa capacité à se mettre en cash quand les trends sont négatifs. C'est son principal avantage : il protège le capital en bear market.

Stratégie 3 — Post-Earnings Announcement Drift

PEAD — Exploiter la sous-réaction post-earnings

Le Post-Earnings Announcement Drift est une anomalie documentée depuis 1968 (Ball & Brown). Quand une entreprise publie des résultats supérieurs aux attentes, le prix continue de monter pendant 20-60 jours après l'annonce. Le marché sous-réagit systématiquement aux surprises de résultats.

Signal PEAD

claude -p "Implémente PEADStrategy dans strategies/pead.py :

class PEADStrategy(BaseStrategy):
    '''Post-Earnings Announcement Drift — acheter les surprises positives.

    Chaque jour pendant la saison des earnings:
    1. Scanner les résultats publiés hier soir / ce matin
    2. Calculer la Standardized Unexpected Earnings (SUE):
       SUE = (EPS_actual - EPS_consensus) / std(EPS_surprises_4Q)
    3. Filtrer: SUE > 2.0 (surprise forte)
    4. Confirmer avec le price action:
       - Gap up > 3% à l'ouverture → confirme la surprise
       - Volume > 2× la moyenne 20j → confirme l'intérêt
    5. Entrer à 10:30 (30min après l'ouverture, laisser la volatilité se calmer)
    6. Holding: 5-20 jours (optimisé par backtest: 10 jours optimal)
    7. Stop: -5% depuis l'entrée (la surprise était un faux signal)
    8. Take profit: +15% ou 20 jours, premier atteint

    Univers: toutes les actions US/EU avec earnings ce trimestre
    (typiquement 50-80 signaux par saison = ~200/an)

    Sizing: 3% du NAV par position (petites positions car le hit rate
    est de ~55% mais le payoff ratio est >2.5:1)

    Anti-overlap:
    - Max 5 positions PEAD simultanées
    - Si corrélation > 0.7 avec une position existante: skip
    '''

    def scan_earnings(self, date) -> list[EarningsSignal]:
        '''Scanne les résultats publiés et retourne les signaux qualifiés.
        Sources: Yahoo Finance earnings API, Zacks, Estimize
        '''

    def backtest(self, start='2010-01-01', end='2025-12-31') -> BacktestResult:
        '''Backtest event-driven (pas de rebalancement régulier).
        Exécuté trade par trade.'''
"

Résultats PEAD (2010-2025)

MétriquePEAD
CAGR28.5%
Sharpe1.45
Max DD-18.2%
Win Rate55%
Avg Win / Avg Loss2.6
Trades / an~200
Avg holding10.3 jours
Saison earnings %85% des profits concentrés Jan-Feb et Jul-Aug

La saisonnalité du PEAD

Le PEAD est fortement saisonnier : 85% des profits sont générés pendant les 4 semaines de saison des résultats (janvier, avril, juillet, octobre). Entre les saisons, la stratégie est quasi inactive et le capital est réalloué aux autres stratégies par le méta-allocateur. C'est un excellent exemple de stratégie complémentaire : elle ne cannibalise pas le momentum car elle opère sur des horizons et des signaux complètement différents.

Stratégie 4 — Industry Rotation

Industry Rotation — Surfer le cycle économique

La rotation sectorielle exploite le fait que les secteurs ne performent pas tous au même moment du cycle économique. En expansion : Tech, Consumer Discretionary. En récession : Healthcare, Utilities. Notre stratégie identifie automatiquement la phase du cycle et se positionne en conséquence.

Signal de rotation

claude -p "Implémente IndustryRotationStrategy dans strategies/rotation.py :

class IndustryRotationStrategy(BaseStrategy):
    '''Rotation sectorielle basée sur le cycle économique + momentum relatif.

    Univers: 11 secteurs GICS via ETF (XLK, XLV, XLF, XLE, XLI, XLY, XLP, XLU, XLB, XLRE, XLC)
    + 3 ETF défensifs (GLD, TLT, SHY) en substitution quand aucun secteur n'est attractif.

    Signal composite:
    1. Relative Strength (40%):
       RS_i = perf_3m(sector_i) / perf_3m(SPY)
       → Les secteurs qui battent le SPY sont attractifs

    2. Breadth (30%):
       breadth_i = % d'actions du secteur au-dessus de leur EMA50
       → Un secteur avec 80% de composants en tendance haussière est sain

    3. Macro regime alignment (30%):
       - Expansion (PMI > 50 + rising): Tech, Industrials, Consumer Disc
       - Late cycle (PMI > 50 + falling): Energy, Materials, Healthcare
       - Contraction (PMI < 50 + falling): Utilities, Consumer Staples, TLT
       - Recovery (PMI < 50 + rising): Financials, Real Estate, Small-Caps

    Portfolio:
    - Top 3-4 secteurs par score composite
    - Equal weight parmi les sélectionnés
    - Rebalancement: mensuel
    - Si aucun secteur n'est attractif (tous en RS < 0.95): 100% défensif (GLD+TLT+SHY)
    '''
"

Résultats Industry Rotation (2010-2025)

MétriqueIndustry RotationSPY (benchmark)
CAGR15.2%13.2%
Sharpe0.950.72
Max DD-18.5%-33.9%
Calmar0.820.39
% défensif22% du temps0%
Backtests combinés et validation

Les 4 stratégies combinées — L'effet de diversification

Performance combinée (allocation méta-allocateur)

MétriqueCSM seulTSMOM seulPEAD seulInd. Rot seulCombiné 4 strat
CAGR24.3%16.8%28.5%15.2%32.8%
Sharpe1.351.101.450.951.62
Max DD-22.1%-14.5%-18.2%-18.5%-15.8%
Calmar1.101.161.570.822.08

L'effet de diversification : 1+1+1+1 > 4

La combinaison des 4 stratégies produit un Sharpe de 1.62 — supérieur à toute stratégie individuelle. Le max DD tombe à -15.8% — largement sous notre contrainte de 25%. C'est la magie de la décorrélation :

  • CSM et TSMOM sont corrélés à 0.55 (tous deux momentum)
  • PEAD est corrélé à seulement 0.20 avec CSM (signal événementiel vs tendance)
  • Industry Rotation est corrélé à 0.35 avec CSM (même direction, timing différent)

Et nous n'avons que 4 stratégies momentum ! Les Parties 7 et 8 ajoutent des stratégies mean-reversion et cross-asset avec des corrélations encore plus faibles, poussant le Sharpe combiné vers 1.8-2.0.

Validation anti-overfitting — Le test ultime

claude -p "Crée un notebook de validation anti-overfitting dans notebooks/validation_momentum.ipynb :

# Pour chaque stratégie, exécuter:

1. Walk-Forward Analysis (WFA):
   - IS: 5 ans, OOS: 1 an, rolling
   - 10 fenêtres de 2010 à 2025
   - Critère: Sharpe OOS > 50% du Sharpe IS dans au moins 7/10 fenêtres

2. Combinatorial Purged Cross-Validation (CPCV):
   - 10 splits, purge = 5 jours, embargo = 21 jours
   - Distribution des Sharpe: percentile 5% > 0
   - Deflated Sharpe Ratio (DSR) > 0.5

3. Regime robustness:
   - Séparer les backtests par régime (Risk-On, Neutral, Risk-Off)
   - Vérifier que le Sharpe est > 0 dans CHAQUE régime
   - Le CAGR en Risk-Off peut être faible mais ne doit pas être négatif

4. Transaction cost sensitivity:
   - Re-run avec slippage 2×, 3×, 5× la baseline
   - Le Sharpe doit rester > 0.5 même avec slippage 3×

5. Parameter sensitivity:
   - Varier chaque paramètre de ±30%
   - Le Sharpe ne doit pas varier de plus de 20%
   - Pas de 'cliff effect' (pas de paramètre critique)

Rapport final: une heatmap résumant pass/fail pour chaque test × stratégie.
"

Prochaine étape — Mean Reversion & Statistical Arbitrage

Les stratégies momentum sont le moteur en Risk-On. Mais quand le marché corrige, elles souffrent. La Partie 7 construit les stratégies complémentaires qui performent en marché range-bound ou baissier : mean-reversion RSI et pairs trading statistique.

Points clés de cette partie

  • CSM : 24.3% CAGR, Sharpe 1.35, momentum composite + filtre qualité sur 1500 actions
  • TSMOM : 16.8% CAGR, Sharpe 1.10, trend following sur 50 ETF avec volatility targeting
  • PEAD : 28.5% CAGR, Sharpe 1.45, exploitation des surprises earnings avec holding 10j
  • Industry Rotation : 15.2% CAGR, rotation cyclique alignée sur le macro regime
  • Combiné : 32.8% CAGR, Sharpe 1.62, Max DD -15.8% — l'effet de diversification
  • Validation : Walk-Forward + CPCV + Deflated Sharpe + stress tests obligatoires
Partie suivante Mean Reversion & Statistical Arbitrage →
Algo Trading — De 100K au Million6/12