<< Sommaire QC | Précédent : QC-Py-Cloud-12-SectorRotation-Momentum << | Suivant : QC-Py-Cloud-03-Risk-Parity >>

Precedent : QC-Py-Cloud-12-SectorRotation-Momentum << | Suivant : QC-Py-Cloud-03-Risk-Parity >>

QC-Py-Cloud-14 — Dual Momentum : Asset Sélection Matters

Module: Hands-On AI Trading, Ch.6 — Momentum Stratégies

Objectif: Implementer et comparer des variantes du Dual Momentum (Antonacci, 2014) sur QuantConnect Cloud, en demontrant l’impact critique de la sélection d’actifs defensifs 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 : Dual Momentum

Le Dual Momentum combine deux signaux :

  1. Momentum absolu (time-series) : Un actif a un rendement positif sur une periode donnee (ex: 12 mois). Si oui, il est “en tendance”. Si non, on se refugie en defensif.

  2. Momentum relatif (cross-section) : Parmi les actifs en tendance, on selectionne les meilleurs performers.

Reference : Gary Antonacci, “Dual Momentum Investing” (2014).

Pourquoi c’est pedagogiquement riche

Le Dual Momentum semble simple en théorie, mais sa performance depend massivement de la sélection des actifs defensifs. La “bonne” reponse (BND, TLT, SHY, cash) change selon le regime de taux d’intérêt. C’est un excellent cas d’étude pour comprendre que l’edge d’une stratégie reside souvent dans les details d’implementation, pas dans le signal lui-même.

Exercice 1 : Implementation du filtre de momentum absolu

Le momentum absolu (time-series) verifie si un actif a un rendement positif sur une periode donnee. Si oui, l’actif est en tendance. Si non, on se refugie en defensif.

Objectif : Implementez absolute_momentum(prices, lookback=252) qui retourne True si le rendement est positif, False sinon. Testez sur des series simulees en tendance haussiere et baissiere.

Indices : - Indice : Rendement = prix_actuel / prix_actuel_minus_lookback - 1. - Indice : Un lookback de 252 jours correspond a environ 12 mois de bourse.

# Exercice 1 : Implementation du filtre de momentum absolu
# TODO etudiant : implementer absolute_momentum(prices, lookback=252) -> bool
# Indice : retourne True si le rendement sur lookback jours est > 0

import numpy as np

def absolute_momentum(prices, lookback=252):
    # TODO etudiant : calculer le rendement sur lookback jours
    return None  # TODO etudiant : retourner True ou False

np.random.seed(42)
bull = 100 + np.cumsum(np.random.randn(300) * 0.5 + 0.03)
bear = 100 + np.cumsum(np.random.randn(300) * 0.5 - 0.03)
result_abs_mom = None  # TODO etudiant : tester sur bull et bear
print("Exercice a completer : filtre de momentum absolu")
Exercice a completer : filtre de momentum absolu

2. Les trois variantes

v1 — Original (Antonacci classique)

Paramètre Valeur
Actifs risques SPY, EFA
Actif defensif BND (Vanguard Total Bond)
Sélection Top 1 par momentum 12m
Allocation 100% dans l’actif choisi
Filtre absolu 12m return > 0
Rebalance Mensuel

v2 — NoTLT (diversified defensive)

Paramètre Valeur
Actifs risques SPY, QQQ, IEF, GLD, XLP
Actif defensif Cash (liquidate)
Sélection Top 2 par momentum 12m
Allocation Equal-weight (50% chacun)
Filtre absolu 12m return > 0
Rebalance Mensuel

Changement cle : L’univers inclut déjà des actifs defensifs (IEF, GLD, XLP) qui peuvent etre selectionnes par le momentum relatif. Pas besoin d’un safe asset separé.

v3 — Momentum-Weighted (allocation proportionnelle)

Paramètre Valeur
Actifs risques SPY, QQQ, EFA, GLD
Actif defensif SHY (Treasury 1-3y)
Sélection Top 3 par momentum 12m
Allocation Momentum-weighted (proportionnel au score)
Filtre absolu 12m return > 0
Rebalance Mensuel

3. Résultats QC Cloud

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

Version Univers Allocation Sharpe CAGR MaxDD Net Profit Ordres Win Rate
v1 (Original) SPY, EFA + BND 100% single 0.340 8.08% 33.6% +135.1% 260 67%
v2 (NoTLT) SPY, QQQ, IEF, GLD, XLP Equal top 2 0.392 8.79% 23.6% +152.8% 250 78%
v3 (Weighted) SPY, QQQ, EFA, GLD + SHY Mom-weighted top 3 0.322 7.62% 22.8% +124.4% 369 79%

Benchmark : SPY Buy & Hold

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

4. Analyse : L’impact de l’actif defensif

v1 : Le piege BND (et TLT)

La v1 utilise BND comme refuge defensif. En théorie, les obligations protegent quand les actions chutent. En pratique :

  • 2020 (COVID) : BND a fonctionne comme prevu (+2% quand SPY -34%)
  • 2022 (rate hikes) : BND a perdu ~13%. SPY perdait aussi ~25%. Les deux ont chute ensemble.

Le MaxDD de 33.6% provient principalement de 2022, quand BND ne jouait plus son rôle de refuge.

v2 : La diversification integree

La v2 elimine le besoin d’un actif defensif separe en incluant déjà des actifs defensifs dans l’univers :

  • GLD : or, refuge en crise et inflation
  • IEF : obligations 7-10 ans, moins sensibles aux taux que TLT
  • XLP : biens de consommation de base, defensif en recession

Quand SPY et QQQ ont un momentum negatif, le filtre absolu les elimine. Le portefeuille se tourne naturellement vers GLD, IEF ou XLP, qui ont souvent un momentum positif quand les actions chutent.

Résultat : MaxDD reduit de 33.6% a 23.6%, Sharpe ameliore de 0.340 a 0.392.

v3 : Le piege du momentum-weighting

La v3 pondererait par le score de momentum. Le problème est identique a Cloud-02 : la concentration sur les actifs a momentum eleve augmente le risque de retournement.

Avec 4 actifs et top 3 selectionnes, le portefeuille est souvent fortement concentre sur 1-2 actifs (les poids sont proportionnels aux scores, pas egaux). Le Sharpe (0.322) est inferieur a l’equal-weight v2.

Exercice 2 : Sélection du top N par momentum relatif

Le Dual Momentum combine le filtre absolu (rendement > 0) avec une sélection par momentum relatif (top N par rendement). L’algorithme v2 selectionne le top 2 parmi 5 actifs.

Objectif : Implementez qui filtre les actifs avec momentum absolu > 0, puis selectionne le top N par momentum relatif.

Indices : - Indice : Premier filtre : ne garder que les actifs avec rendement > 0. - Indice : Second filtre : trier par rendement decroissant et prendre les top_n.

# Exercice 2 : Selection du top N par momentum relatif
# TODO etudiant : implementer dual_momentum_select(returns_dict, top_n=2)
# Indice : 1) filtrer rendement > 0, 2) trier et prendre top_n

def dual_momentum_select(returns_dict, top_n=2):
    # returns_dict : {ticker: rendement_12m}
    # TODO etudiant : filtrer les actifs avec rendement > 0
    # TODO etudiant : trier par rendement decroissant
    return None  # TODO etudiant : retourner les top_n tickers

returns = {"SPY": 0.12, "QQQ": 0.18, "IEF": 0.03, "GLD": -0.05, "XLP": 0.06}
result_dual = None  # TODO etudiant : appeler dual_momentum_select
print("Exercice a completer : selection Dual Momentum")
Exercice a completer : selection Dual Momentum

5. Lecon principale : L’edge est dans l’univers, pas le signal

Les trois versions utilisent le même signal (momentum 12 mois) et le même filtre absolu (return > 0). La seule différence est l’univers d’actifs.

Changement Impact Sharpe Impact MaxDD
BND -> diversifie +0.052 -10.0%
Equal-weight -> momentum-weighted -0.070 +0.8% (negligeable)

Conclusion : La sélection de l’univers (quels actifs, quelles classes d’actifs) a un impact plus important que la méthode d’allocation (equal-weight vs momentum-weighted).

C’est coherent avec les recherches academiques : la diversification asset-class explique la majorite de la variance de performance dans les stratégies multi-actifs.

Exercice 3 : Impact de l’actif defensif sur le drawdown

La v1 utilise BND comme defensif (Sharpe 0.340, MaxDD 33.6%). La v2 elimine le defensif separe et inclut des actifs defensifs dans l’univers (Sharpe 0.392, MaxDD 23.6%).

Objectif : Simulez un scénario de bear market ou SPY et QQQ perdent 25% en 6 mois. Comparez la perte du portefeuille dans 3 cas : (a) 100% SPY, (b) 100% BND, (c) 50% IEF + 50% GLD. Calculez le drawdown maximal pour chaque cas.

Indices : - Indice : En bear market, BND peut aussi perdre (correlation non-nulle avec actions en 2022). - Indice : GLD a historiquement une correlation negative avec les actions en periode de crise.

# Exercice 3 : Impact de lactif defensif sur le drawdown
# TODO etudiant : simuler un bear market et comparer 3 allocations defensives
# Indice : en bear, SPY/QQQ perdent 25%, BND perd 5-15%, GLD peut gagner

import numpy as np

def simulate_drawdown(allocation, scenarios):
    # allocation : {ticker: weight}
    # scenarios : {ticker: rendement_6m}
    # TODO etudiant : calculer le rendement pondere du portefeuille
    return None  # TODO etudiant : retourner le drawdown

bear_scenario = {"SPY": -0.25, "QQQ": -0.30, "BND": -0.08, "IEF": -0.03, "GLD": 0.05}
result_defense = None  # TODO etudiant : comparer les 3 allocations
print("Exercice a completer : impact de lactif defensif")
Exercice a completer : impact de lactif defensif

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

Le code est disponible sur QC Cloud (projet 30822524). 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/30822524
# Approche : Dual Momentum NoTLT, top 2 equal-weight
# Univers : SPY, QQQ, IEF, GLD, XLP
# Filtre : 12m absolute momentum > 0
# Rebalance mensuel, pas d'actif defensif separe
#
# Points cles :
# 1. Les actifs defensifs (IEF, GLD, XLP) font partie de l'univers
# 2. Le filtre absolu elimine automatiquement les actifs en bear market
# 3. Top 2 equal-weight = diversification suffisante sans sur-complexite

7. Comparaison avec les autres cloud-native QuantBooks

Stratégie Sharpe CAGR MaxDD Net Profit
Risk Parity v4 (Cloud-01) 0.278 6.17% 20.4% +93.3%
Sector Rotation v3 (Cloud-02) 0.614 10.76% 15.5% +207.8%
Dual Momentum v2 (Cloud-14) 0.392 8.79% 23.6% +152.8%

Le Sector Rotation v3 (trend-following multi-asset) reste le meilleur. Le Dual Momentum v2 offre un bon compromis rendement/risque avec une approche différente (momentum classique sans filtre tendance).

8. Pour aller plus loin

  1. Lookback adaptatif : Tester un lookback variable (6m en bear, 12m en bull) pour s’adapter au regime.

  2. Volatility scaling : Reduire l’exposition quand la volatilite implcite (VIX) est elevee.

  3. Safe asset dynamique : Choisir entre SHY, IEF, GLD selon le regime de taux (taux montants = SHY, taux stables = IEF, inflation = GLD).

  4. Acceleration signal : Combiner momentum 12m avec acceleration du momentum (pente du momentum) pour detecter les retournements plus tot.

Reference : Antonacci, G. (2014) — “Dual Momentum Investing: An Innovative Strategy for Higher Returns with Lower Risk”, McGraw-Hill.

Retour au sommet