L'analyse de portefeuille avec pandas : matrices de corrélation et de covariance, volatilité d'un portefeuille pondéré et simulation de rééquilibrage
Calculez des matrices de covariance et de corrélation annualisées à partir des rendements, déduisez avec NumPy la volatilité du portefeuille et les contributions au risque, et simulez la dérive face à un rééquilibrage calendaire.
Ce que vous allez apprendre
- Comment aligner plusieurs séries de prix dans un seul DataFrame de rendements et calculer
.cov()et.corr()avec une annualisation correcte. - La formule matricielle de la volatilité d'un portefeuille,
w.T @ Σ @ w, et comment lire la contribution de chaque actif au risque. - Comment simuler un portefeuille en achat-conservation qui dérive, face à un portefeuille rééquilibré selon un calendrier.
- Quels pièges numériques (dates désalignées, devises mélangées, anticipation dans la fenêtre de covariance) produisent des réponses fausses.
Explication
La corrélation et l'exposition globale du portefeuille (Gestion du risque et des trades, leçon 6), la combinaison de deux systèmes (Trading systématique, leçon 10) et les règles de rééquilibrage (ETF, fonds et investissement à long terme, leçon 10) ont été enseignées ailleurs ; cette leçon les implémente en code pour un nombre quelconque d'actifs.
Des prix à une matrice de rendements
Chargez la clôture ajustée de chaque instrument (leçon 4) dans un seul DataFrame, une colonne par ticker : prices = pd.concat(series_dict, axis=1). Les jours fériés qui diffèrent d'un marché à l'autre créent des lignes NaN ; choisissez explicitement entre prices.dropna() (jours communs uniquement) et prices.ffill() (report du dernier prix). Puis rets = prices.pct_change().dropna(). Convertissez d'abord tout dans une seule devise ; un ETF américain détenu par un investisseur en euros doit être converti avec la série EUR/USD, sinon sa volatilité et ses corrélations décrivent autre chose que ce que vous détenez.
Covariance, corrélation et annualisation
rets.cov() est la matrice de covariance d'échantillon des rendements journaliers ; multipliez-la par 252 pour l'annualiser (la variance évolue avec le temps). rets.corr() est sans unité et ne nécessite aucune mise à l'échelle. La diagonale contient la variance de chaque actif, donc np.sqrt(np.diag(cov_a)) donne les volatilités annualisées. La relation Σ_ij = ρ_ij × σ_i × σ_j permet de construire une matrice à partir de volatilités et de corrélations pour tester un scénario hypothétique tel que « les corrélations montent à 0.8 en cas de crise ».
Volatilité du portefeuille et contributions au risque
w = np.array([0.5, 0.3, 0.2]) # pondérations, somme égale à 1cov_a = rets.cov().values * 252port_var = w @ cov_a @ wport_vol = np.sqrt(port_var)marginal = cov_a @ w # d(var)/d(w)risk_contrib = w * marginal / port_var # parts dont la somme vaut 1
@ est la multiplication matricielle. risk_contrib indique quelle fraction de la variance du portefeuille revient à chaque actif ; elle est généralement très éloignée de la pondération en capital, et cet écart est le point de départ de la budgétisation du risque (cours « Construction de portefeuille en profondeur : budgets de risque, régimes et tests de résistance », leçon 1).
Une simulation de rééquilibrage
L'achat-conservation laisse les pondérations dériver : les gagnants prennent une part croissante. Le rééquilibrage calendaire ramène les pondérations aux cibles à dates fixes. Dans pandas, rééchantillonnez les rendements à la fréquence de rééquilibrage et bouclez sur les périodes :
period_rets = (1 + rets).resample('ME').prod() - 1 # rendements mensuelstarget = np.array([0.6, 0.4]); hold = 10_000 * target; path = []for _, r in period_rets.iterrows():hold = hold * (1 + r.values) # faire croître chaque pochepath.append(hold.sum())hold = hold.sum() * target # rééquilibrer vers les cibles
Pour la version qui dérive, supprimez la dernière ligne. Utilisez 'QE' pour un rythme trimestriel et 'YE' pour un rythme annuel (pandas 2.2 et versions ultérieures ; les versions plus anciennes utilisent 'M', 'Q', 'A'). La rotation d'un rééquilibrage vaut abs(new_hold - old_hold).sum() ; multipliez-la par un taux de coût tel que 0.1 % et soustrayez le résultat. Sur un compte imposable allemand, le rééquilibrage réalise aussi des plus-values ; vérifiez l'effet fiscal avec un Steuerberater (conseiller fiscal).
Exemple commenté
Exemple hypothétique avec des données inventées ; frais, spreads et impôts exclus.
Partie 1 : volatilité de trois actifs. Volatilités annualisées de 20 %, 10 %, 15 % ; corrélations ρ₁₂ = 0.2, ρ₁₃ = 0.6, ρ₂₃ = 0.1 ; pondérations de 50 / 30 / 20 %.
- Covariances : Σ₁₂ = 0.2 × 0.20 × 0.10 = 0.0040 ; Σ₁₃ = 0.6 × 0.20 × 0.15 = 0.0180 ; Σ₂₃ = 0.1 × 0.10 × 0.15 = 0.0015. Diagonale : 0.0400, 0.0100, 0.0225.
- Variance du portefeuille = Σ wᵢ wⱼ Σᵢⱼ = 0.25 × 0.04 + 0.09 × 0.01 + 0.04 × 0.0225 + 2 × (0.5 × 0.3 × 0.004 + 0.5 × 0.2 × 0.018 + 0.3 × 0.2 × 0.0015) = 0.0100 + 0.0009 + 0.0009 + 2 × (0.0006 + 0.0018 + 0.00009) = 0.01678.
- Volatilité du portefeuille = √0.01678 = 12.95 %, contre une moyenne pondérée des volatilités de 16.0 % ; la différence est le bénéfice de la diversification.
- Contributions au risque : l'actif 1 porte 73.9 % de la variance avec 50 % du capital ; l'actif 2 en porte 9.5 % avec 30 % ; l'actif 3 en porte 16.6 % avec 20 %.
Partie 2 : dérive ou rééquilibrage. €10,000 répartis à 60 / 40 entre l'actif A et l'actif B. Rendements annuels : A +20 %, −10 %, +15 % ; B +2 %, +4 %, +1 %.
- Dérive : A : 6,000 × 1.20 × 0.90 × 1.15 = €7,452 ; B : 4,000 × 1.02 × 1.04 × 1.01 = €4,285.63. Total €11,737.63 ; la pondération de A a dérivé jusqu'à 63.5 %.
- Rééquilibrage annuel : total de l'année 1 = 7,200 + 4,080 = €11,280 → retour à 6,768 / 4,512 ; année 2 = 6,091.20 + 4,692.48 = €10,783.68 → retour aux cibles ; année 3 = 7,440.74 + 4,356.61 = €11,797.35.
- Le rééquilibrage a fini €59.72 plus haut parce qu'il a vendu A après +20 % et racheté après −10 %. Avec un actif A en tendance régulière, la dérive l'aurait emporté ; le rééquilibrage contrôle le risque, il ne garantit pas le rendement.
Erreur fréquente
rets.cov() sur 2015–2025 et utilise le résultat pour fixer les pondérations en 2015 exploite des informations venues du futur. Estimez la covariance sur une fenêtre glissante ou cumulative (rets.rolling(252).cov() ou rets.loc[:date].cov()) et appliquez-la uniquement à la période suivante. Les corrélations augmentent aussi en période de crise ; une matrice estimée en période calme sous-estime donc le risque au moment où il compte.Exercice pratique
Sur papier : deux actifs avec des volatilités annualisées de 18 % et 6 %, une corrélation de 0.3, des pondérations de 70 / 30 %. (a) Construisez la matrice de covariance 2 × 2. (b) Calculez la variance et la volatilité du portefeuille. (c) Calculez la contribution de chaque actif au risque en part de la variance. (d) Recalculez la volatilité avec une corrélation de 0.9 et indiquez en une phrase pourquoi c'est important.
Afficher la solution
(a) Σ₁₁ = 0.0324 ; Σ₂₂ = 0.0036 ; Σ₁₂ = 0.3 × 0.18 × 0.06 = 0.00324.
(b) Variance = 0.49 × 0.0324 + 0.09 × 0.0036 + 2 × 0.7 × 0.3 × 0.00324 = 0.015876 + 0.000324 + 0.0013608 = 0.0175608 ; volatilité = 13.25 %.
(c) Marginales : actif 1 : 0.7 × 0.0324 + 0.3 × 0.00324 = 0.023652 ; actif 2 : 0.7 × 0.00324 + 0.3 × 0.0036 = 0.003348. Contributions : 0.7 × 0.023652 / 0.0175608 = 94.3 % ; 0.3 × 0.003348 / 0.0175608 = 5.7 %.
(d) Avec ρ = 0.9 : Σ₁₂ = 0.00972 ; variance = 0.015876 + 0.000324 + 0.0040824 = 0.0202824 ; volatilité = 14.24 %. Le « diversifiant » apporte peu lorsque la corrélation augmente, ce qui est précisément ce qui tend à se produire lors d'une chute des marchés ; un portefeuille doit être jugé sur des corrélations en situation de stress, et pas seulement sur la moyenne historique.
Limites : la covariance d'échantillon estimée sur quelques années de données journalières est bruitée ; de petites modifications de la fenêtre peuvent faire varier les corrélations de 0.1 ou plus.
Points clés à retenir
- Alignez dates et devises avant de calculer les rendements ; décidez explicitement du traitement des jours manquants.
- Annualisez la covariance en la multipliant par le nombre de périodes par an ; la corrélation ne nécessite aucune mise à l'échelle.
- La volatilité du portefeuille vaut √(wᵀ Σ w) ; les contributions au risque w × (Σw) / variance montrent où se situe réellement le risque.
- Simulez le rééquilibrage en rééchantillonnant les rendements et en réinitialisant les positions ; n'estimez la covariance qu'à partir des données disponibles à la date considérée.
Étape suivante
La leçon 12 automatise la routine quotidienne : un script planifié qui récupère les données, calcule les signaux et rédige un rapport, avec une gestion correcte des clés d'API et des limites de requêtes.
Auto-évaluation
Répondez aux questions, puis vérifiez vos réponses. Vous pouvez recommencer autant de fois que vous le souhaitez.
Auto-évaluation automatique pour vos propres révisions. Vos réponses sont vérifiées dans votre navigateur ; nous ne les voyons pas et ne les évaluons pas. Ce n'est ni un examen ni une qualification.
Votre progression
« Terminée » signifie seulement que vous avez marqué la leçon comme lue. Ce n'est pas un test de votre compréhension. La progression et les notes sont enregistrées uniquement dans ce navigateur, sur cet appareil — pas dans un compte.