Le risque en un seul nombre
La volatilité est l'écart type des rendements, exprimé par an pour pouvoir comparer les actifs : environ 15 à 20 % pour un indice actions, 30 à 60 % pour une action isolée, proche de 0 pour du cash. Elle sert à dimensionner les positions, à valoriser les options et à fixer les limites de risque. L'estimation la plus simple est la volatilité réalisée sur une fenêtre : l'écart type d'échantillon des rendements multiplié par sqrt(périodes par an). Elle traite tous les jours de la fenêtre de la même façon, ce qui fait à la fois sa force (stable) et sa faiblesse (lente).
import math
import numpy as np
# Eight quiet days, one -3% shock, three more days
returns = np.array([0.004, -0.002, 0.001, 0.003, -0.004, 0.002, 0.006, -0.001, -0.030, 0.004, 0.002, -0.003])
print(round(returns[:8].std(ddof=1) * math.sqrt(252), 4)) # 0.0526 before the shock: 5.3% a year
print(round(returns.std(ddof=1) * math.sqrt(252), 4)) # 0.1505 with the shock: 15.1% a yearRéagir plus vite : EWMA
La volatilité se regroupe en grappes : les périodes calmes et les périodes agitées durent un certain temps, donc le choc d'hier en dit plus sur demain qu'une journée tranquille d'il y a un mois. La moyenne mobile exponentielle (EWMA, popularisée par RiskMetrics) met à jour la variance chaque jour : variance_t = lam * variance_(t-1) + (1 - lam) * rendement_t². Avec lam = 0,94, le rendement le plus récent pèse 6 % et les anciens s'estompent géométriquement. L'estimation saute au moment d'un choc puis décroît progressivement, au lieu de rester élevée jusqu'à ce que le choc quitte la fenêtre pour retomber d'un coup.
lam = 0.94
variance = np.empty(len(returns))
variance[0] = returns[0] ** 2
for t in range(1, len(returns)):
variance[t] = lam * variance[t - 1] + (1 - lam) * returns[t] ** 2 # the recursion needs the previous value
ewma = np.sqrt(variance)
print(ewma.round(5).tolist())
# [0.004, 0.00391, 0.0038, 0.00375, 0.00377, 0.00369, 0.00387, 0.00376, 0.0082, 0.00801, 0.00778, 0.00758]
# ^ the shock doubles the estimate, then it fades
print(round(ewma[-1] * math.sqrt(252), 4)) # 0.1204 today's annualised estimateUtiliser l'amplitude, et cibler une volatilité
Les cours de clôture ignorent ce qui s'est passé pendant la journée. Le plus haut et le plus bas du jour portent davantage d'information : l'estimateur de Parkinson sqrt(mean(ln(high/low)²) / (4 ln 2)) est plusieurs fois plus efficace que l'estimation clôture à clôture, c'est-à-dire qu'il atteint la même précision avec bien moins de jours (il suppose l'absence de grands écarts entre les jours). Un usage pratique de toute estimation de volatilité est le ciblage de volatilité : si vous voulez 10 % de risque et que la volatilité réalisée est de 15 %, détenez 10 / 15 = 0,67 de la position. Le levier diminue dans la tempête et augmente dans le calme.
high = np.array([101.5, 102.0, 103.2, 102.8, 104.0])
low = np.array([99.8, 100.9, 101.7, 101.1, 102.4])
parkinson = math.sqrt(np.mean(np.log(high / low) ** 2) / (4 * math.log(2)))
print(round(parkinson, 5)) # 0.00905 per-day volatility from the daily ranges
target = 0.10
realized = returns.std(ddof=1) * math.sqrt(252)
print(round(target / realized, 3)) # 0.664 hold two thirds of the position to run at 10% risk# Close-to-close versus range: the same five days
close = np.array([100.0, 101.2, 102.5, 101.9, 103.4])
print(round(float(np.diff(np.log(close)).std(ddof=1)), 5)) # 0.00955 from the closes only
print(round(parkinson, 5)) # 0.00905 from the high-low ranges of the same days- Volatilité réalisée : écart type d'échantillon fois
sqrt(périodes par an); stable mais lente à réagir. - EWMA :
variance_t = lam * variance_(t-1) + (1 - lam) * rendement_t²; les chocs récents pèsent plus et s'estompent géométriquement. - Parkinson utilise l'amplitude haut/bas du jour ; le ciblage de volatilité ajuste la position par
cible / réalisée.
À suivre : le ratio de Sharpe, la récompense par unité de risque, et jusqu'où lui faire confiance.
Lab : ce qui est noté
- Mesurer la volatilité annuelle avec
realized_volatility25 pts - Donner plus de poids aux chocs récents avec
ewma_volatility25 pts - Utiliser l'amplitude quotidienne avec
parkinson_volatility25 pts - Dimensionner une position selon un budget de risque avec
volatility_target_leverage25 pts