Des graphiques pour l'analyse : prix avec indicateurs, graphiques de capital et de drawdown, distributions de rendements et export des figures
Utilisez l'interface figure-et-axes de matplotlib pour construire les quatre graphiques dont tout rapport de backtest a besoin, lisez-les correctement et exportez-les en qualité impression.
Ce que vous allez apprendre
- Le schéma
fig, ax = plt.subplots()et pourquoi il est préférable au raccourci rapideseries.plot()pour tout ce que vous réutiliserez. - Comment empiler des panneaux de prix, d'indicateur et de capital partageant un même axe temporel, et quand passer l'axe du capital en échelle logarithmique.
- Comment tracer un graphique de drawdown et un histogramme des rendements, et ce qu'il faut rechercher dans chacun.
- Comment la taille de la figure, le DPI et le format de fichier déterminent l'aspect de l'image exportée.
Explication
En recherche, les graphiques ne sont pas de la décoration ; ils sont le moyen le plus rapide de vérifier que vos chiffres sont justes. Une courbe de capital qui bondit de 30 % en une journée signale généralement une erreur de données, et non un trade exceptionnel. Cette leçon utilise matplotlib, que pandas appelle en coulisses, via son interface orientée objet.
Figure, axes et axe temporel partagé
Une figure est la toile entière ; un objet axes est une zone de tracé à l'intérieur de celle-ci. fig, axes = plt.subplots(3, 1, figsize=(10, 8), sharex=True, height_ratios=[3, 1, 1]) crée trois panneaux empilés de hauteurs différentes qui zooment ensemble. Le schéma est le même pour chaque panneau : appelez ax.plot(x, y, label=...), puis ax.set_ylabel, ax.legend() et ax.grid(True, alpha=0.3). Donnez à chaque panneau un titre court et indiquez les unités (€, %, points).
Le prix avec ses indicateurs
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6), sharex=True, height_ratios=[3, 1])ax1.plot(df.index, df.close, lw=1, label='Clôture')ax1.plot(df.index, df.sma50, lw=1, label='SMA 50')ax1.fill_between(df.index, df.bb_lo, df.bb_hi, alpha=0.15, label='Bollinger')ax1.legend(loc='upper left'); ax1.set_ylabel('Prix (€)')ax2.plot(df.index, df.rsi, lw=1); ax2.axhline(70, ls='--'); ax2.axhline(30, ls='--')ax2.set_ylabel('RSI'); fig.autofmt_xdate(); fig.tight_layout()
fill_between ombre une bande ; axhline trace des niveaux de référence ; autofmt_xdate fait pivoter les dates pour qu'elles ne se chevauchent pas. Pour marquer les trades de la liste de la leçon 8, utilisez ax1.scatter(entries.index, entries.price, marker='^') pour les entrées et un triangle pointant vers le bas pour les sorties.
Capital et drawdown
Tracez le capital avec ax.set_yscale('log') dès que le compte fait plus que doubler sur la période. Sur un axe linéaire, un passage de €10,000 à €11,000 paraît minuscule à côté d'un passage ultérieur de €40,000 à €44,000, alors que les deux représentent +10 %. Le panneau de drawdown trace dd = equity / equity.cummax() - 1 et le remplit : ax.fill_between(dd.index, dd, 0, alpha=0.4). Lisez-y trois choses : le point le plus bas (drawdown maximal), la plus longue période sous zéro (le temps passé sous l'eau, souvent plus pénible que la profondeur), et si les drawdowns se concentrent dans un même régime.
Distributions de rendements
ax.hist(returns, bins=50, density=True) montre la forme des rendements journaliers ou par trade. Superposez une courbe normale de même moyenne et de même écart-type pour voir les queues épaisses (fat tails) : les rendements réels comptent plus de journées extrêmes que ne le prévoit la courbe en cloche. Pour une liste de trades, tracez plutôt les R-multiples : un système de suivi de tendance sain présente de nombreuses petites pertes autour de −1R et une longue queue à droite ; un système vendeur de volatilité présente l'image inverse, ce qui est un signal d'alerte. Indiquez l'asymétrie (skewness) et le kurtosis avec returns.skew() et returns.kurt() (pandas renvoie l'excès de kurtosis, excess kurtosis, donc 0 signifie des queues proches de la loi normale).
Exporter
fig.savefig('equity.png', dpi=150, bbox_inches='tight') écrit une image matricielle ; taille en pixels = pouces × DPI, donc une figure de 10 × 6 pouces à 150 DPI fait 1,500 × 900 pixels. Utilisez .svg ou .pdf pour une sortie vectorielle qui reste nette dans un rapport, et bbox_inches='tight' pour rogner les marges blanches. Appelez toujours plt.close(fig) après l'enregistrement dans une boucle, sinon un script qui produit 40 graphiques de watchlist (leçon 12) gardera 40 figures en mémoire. Définissez les valeurs par défaut une seule fois avec plt.rcParams['figure.dpi'] = 110 plutôt qu'à chaque appel.
Exemple commenté
Exemple hypothétique : une série de capital issue d'un backtest (en euros, inventée) et son graphique. Frais et impôts exclus des valeurs de capital.
- Capital en fin d'année : €10,000, €13,000, €11,700, €16,000, €24,000. Série des drawdowns : pics 10,000 ; 13,000 ; 13,000 ; 16,000 ; 24,000 → drawdowns 0 ; 0 ; 11,700 / 13,000 − 1 = −10.0 % ; 0 ; 0. Drawdown maximal de −10 %, temps passé sous l'eau d'environ un an.
- Sur un axe linéaire, le dernier segment (+€8,000) domine l'image ; sur un axe logarithmique, les étapes +30 %, −10 %, +36.8 %, +50 % apparaissent avec leurs vraies tailles relatives, et l'année à −10 % est visible au lieu d'être écrasée.
- Rendements journaliers : moyenne de 0.06 %, écart-type de 1.1 %, excès de kurtosis de 4.2. Une loi normale avec cet écart-type placerait une journée à −3.3 % (trois écarts-types) à environ une sur 740 jours ; l'histogramme en montre sept sur 1,000. Cet écart, c'est la queue épaisse, et c'est la raison pour laquelle des stops peuvent être franchis en gap (leçon 8).
- Export :
figsize=(8, 5)àdpi=200donne 1,600 × 1,000 pixels, suffisant pour une diapositive ; la même figure enregistrée en SVG est indépendante de la résolution et pèse souvent moins de 100 kB.
Erreur fréquente
Exercice pratique
Sur papier : (a) une courbe de capital évolue de 20,000 → 26,000 → 19,500 → 28,000 (en euros, quatre points). Calculez le drawdown à chaque point. (b) Vous voulez une figure de exactement 1,200 × 800 pixels à 100 DPI ; quel figsize passez-vous ? (c) L'histogramme des R-multiples d'une stratégie a sa barre la plus haute entre +0.2R et +0.4R et une fine queue gauche qui atteint −6R. Écrivez une phrase sur ce que cette forme suggère de la stratégie et sur le risque qu'un ratio de Sharpe ne montrerait pas.
Afficher la solution
(a) Pics : 20,000 ; 26,000 ; 26,000 ; 28,000. Drawdowns : 0 ; 0 ; 19,500 / 26,000 − 1 = −25.0 % ; 0.
(b) figsize = (1,200 / 100, 800 / 100) = (12, 8) pouces.
(c) De nombreux petits gains et de rares pertes très importantes constituent le profil d'une stratégie qui vend du risque (par exemple la vente d'options ou la moyenne à la baisse) ; le ratio de Sharpe, construit à partir d'une moyenne et d'un écart-type, est tiré vers le haut par les petits gains fréquents et sous-estime la probabilité d'une journée à −6R qui efface des mois de gains.
Limites : un histogramme de moins d'environ 100 observations est trop bruité pour juger de la forme des queues ; indiquez plutôt les pires valeurs réelles.
Points clés à retenir
- Utilisez
plt.subplotsavec des axes x partagés pour les panneaux de prix, d'indicateur, de capital et de drawdown ; indiquez les unités. - Le capital en échelle logarithmique montre honnêtement les variations en pourcentage ; les graphiques de drawdown montrent la profondeur et le temps passé sous l'eau.
- Les histogrammes des rendements ou des R-multiples révèlent les queues épaisses et l'asymétrie que masquent les statistiques résumées.
- Pixels = pouces × DPI ; privilégiez le SVG ou le PDF pour les rapports et fermez les figures dans les boucles.
Étape suivante
La leçon 11 passe d'un seul instrument à plusieurs : matrices de corrélation et de covariance, volatilité d'un portefeuille à partir des pondérations, et simulation de rééquilibrage dans pandas.
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.