← Retour aux articles
July 13, 2026
5 min de lecture

Ciblage de volatilité et trading avec les prévisions GARCH

#volatility
#GARCH
#volatility-targeting
#backtesting
#risk
#crypto
#algorithmic-trading

Les trois premières parties de cette série vous ont appris à prévoir la volatilité. Nous avons construit un GARCH(1,1) univarié dans la Partie 1, ajouté l'effet de levier et les queues épaisses avec GJR et des innovations Student-t dans la Partie 2, et modélisé toute une matrice de covariance au fil du temps avec DCC-GARCH dans la Partie 3. À la fin de chacune, nous avons affiché un chiffre : la volatilité attendue de demain. Et ensuite, si nous sommes honnêtes, nous nous sommes arrêtés — comme si produire la prévision était le but.

Ce n'est pas le cas. Une prévision de volatilité n'est pas un P&L. Personne n'a jamais été payé pour un faible score QLIKE. Une prévision ne devient utile qu'à l'instant précis où elle modifie une décision que vous auriez autrement prise différemment — combien acheter, quand couper, combien de capital allouer. Si votre prévision ne fait pas bouger une position, sa précision statistique n'est qu'un passe-temps privé.

Cette dernière partie consiste à boucler cette boucle. Nous prenons les prévisions des Parties 1-3 et les mettons au travail dans la décision la plus propre possible : le ciblage de volatilité — dimensionner une position de sorte que la volatilité réalisée du portefeuille atteigne une cible constante. Puis nous faisons la chose qui compte pour ce blog plus que n'importe quel modèle isolé : nous évaluons honnêtement. Nous comparons GARCH à des références simples mais solides (volatilité réalisée glissante, EWMA), nous utilisons des fonctions de perte robustes au fait que nous ne pouvons jamais observer la vraie volatilité, nous menons un backtest walk-forward avec coûts et sans look-ahead, et nous énonçons clairement ce que le ciblage de volatilité vous apporte et ne vous apporte pas. Spoiler : il améliore les rendements ajustés du risque et maîtrise les drawdowns bien plus fiablement qu'il ne fabrique de l'alpha.

Pourquoi le ciblage de volatilité est le bon test

Il existe des façons plus sophistiquées d'utiliser une prévision de volatilité — valorisation d'options, limites de VaR, couverture dynamique — mais le ciblage de volatilité est celle qui isole la valeur de la prévision avec le moins de contamination par d'autres paris. L'idée tient en une seule équation.

Détenez un actif risqué avec une direction impliquée par un signal (pour l'instant, simplement « long »). Au lieu d'une position fixe, dimensionnez l'exposition de façon inversement proportionnelle à la volatilité prévue :

wt=σtargetσ^t(then capped)w_t = \frac{\sigma_{\text{target}}}{\hat{\sigma}_{t}} \quad \text{(then capped)}

σ^t\hat{\sigma}_t est votre prévision de la volatilité de la période suivante (faite en utilisant uniquement les données jusqu'à tt), et σtarget\sigma_{\text{target}} est la volatilité annualisée à laquelle vous voulez que la stratégie tourne — disons 15 % ou 20 %. Quand le modèle prévoit un marché calme, vous augmentez le levier vers (ou au-delà de) 1,0 ; quand il prévoit une tempête, vous réduisez. La volatilité réalisée de la position dimensionnée est, au premier ordre,

Vol(wtrt+1)=wtσt+1=σtargetσ^tσt+1σtarget\text{Vol}(w_t r_{t+1}) = w_t \, \sigma_{t+1} = \frac{\sigma_{\text{target}}}{\hat\sigma_t}\, \sigma_{t+1} \approx \sigma_{\text{target}}

dès lors que σ^tσt+1\hat\sigma_t \approx \sigma_{t+1}. Ainsi, toute la qualité de l'exercice repose sur une seule chose : à quel point votre prévision σ^t\hat\sigma_t est proche de la volatilité réelle de la période suivante σt+1\sigma_{t+1}. Une meilleure prévision produit un profil de volatilité réalisée plus plat et — comme nous le verrons — un meilleur ratio de Sharpe. Voilà pourquoi c'est le bon test. La prévision n'est pas une décoration ; c'est le dénominateur.

Pourquoi cela augmente le Sharpe et contrôle les drawdowns

Deux faits empiriques font le travail ici.

La volatilité est bien plus prévisible que les rendements. La direction du rendement BTC de demain est proche d'un pile ou face à fréquence journalière ; l'amplitude, non. La volatilité se regroupe en grappes — les grands mouvements suivent les grands mouvements — ce qui est toute la raison d'être de GARCH (la Partie 1 a dérivé la structure AR(1)-en-variance qui encode cela). Un R2R^2 de 0,4-0,6 pour la variance à un jour est courant ; le même chiffre pour les rendements serait un signal de niveau Renaissance. Le ciblage de volatilité exploite la quantité prévisible et reste agnostique sur celle qui ne l'est pas.

Les ratios de Sharpe ne sont pas constants dans le temps ; ils chutent quand la volatilité s'envole. Les régimes de haute volatilité en crypto — cascades de désendettement, faillites d'exchanges, les jours où tout décroche de 30 % — tendent à avoir un rendement par unité de risque pire, et non meilleur. En coupant mécaniquement l'exposition exactement quand la volatilité prévue est élevée, vous sous-pondérez les périodes qui contribuent le plus aux drawdowns et le moins au rendement composé. Moreira et Muir (2017) ont montré pour les actions que les portefeuilles à volatilité gérée — précisément ce dimensionnement en 1/σ21/\sigma^2 — augmentent les ratios de Sharpe et produisent des alphas positifs contre le facteur non géré. Le mécanisme n'a rien de magique ; c'est refuser de détenir une position en dollars constante dans des fenêtres prévisiblement turbulentes.

Le bénéfice en drawdown est encore plus direct. Le drawdown maximal est dominé par la queue de la distribution des rendements de position. Puisque wtrt+1w_t r_{t+1} a une volatilité maintenue près de σtarget\sigma_{\text{target}}, la grosse queue de gauche que subit une stratégie à notionnel fixe lors d'une explosion de volatilité est comprimée : vous étiez déjà petit à l'entrée. Le ciblage de volatilité ne prédit pas les krachs, mais il est systématiquement sous-exposé quand le marché est agité, et l'agitation est le moment où les krachs se produisent.

Relation avec Kelly et le dimensionnement fractionnaire

Le ciblage de volatilité est un proche cousin du critère de Kelly. Pour un actif unique avec rendement excédentaire attendu μ\mu et variance σ2\sigma^2, la fraction optimale pour la croissance (Kelly complet) est

f=μσ2.f^\star = \frac{\mu}{\sigma^2}.

Si vous supposez que le ratio de Sharpe μ/σ\mu/\sigma est à peu près constant — une hypothèse forte, mais celle implicite dans « le marché paie un prix stable pour le risque » — alors μ=Sσ\mu = S\sigma et f=S/σf^\star = S/\sigma, ce qui est exactement le ciblage de volatilité avec σtarget=S(Kelly fraction)\sigma_{\text{target}} = S \cdot (\text{Kelly fraction}). Autrement dit, le ciblage de volatilité est un dimensionnement de Kelly sous l'hypothèse que le rendement attendu croît avec la volatilité. Nous détaillons le Kelly complet et fractionnaire, et pourquoi personne de sensé ne trade en Kelly complet, dans critère de Kelly et dimensionnement de stratégie. La leçon pratique de là se reporte : utilisez une fraction de la taille théorique, car l'erreur d'estimation au dénominateur (votre prévision de volatilité) et surtout au numérateur (le rendement attendu) rend le dimensionnement complet dangereusement agressif.

Deux autres liens à garder en tête. Premièrement, le ciblage de volatilité dimensionne sur la dispersion symétrique des rendements, mais les payoffs crypto ne sont pas symétriques — le coût d'une journée en baisse de 20 % n'est pas le miroir d'une journée en hausse de 20 % dès lors que le levier et la liquidation entrent en jeu. Nous traitons cette asymétrie directement dans asymétrie perte-profit, et une prévision GJR/EGARCH (Partie 2) en intègre déjà une partie dans σ^t\hat\sigma_t en réagissant davantage aux chocs négatifs. Deuxièmement, une prévision de volatilité est une estimation ponctuelle ; une vue du risque plus complète y attache un intervalle. Prédiction conforme pour le trading montre comment transformer les sorties d'un modèle en intervalles sans distribution que vous pouvez utiliser pour dimensionner, ce qui s'accorde naturellement avec le thème de l'évaluation honnête de cet article.

Les concurrents : ce que GARCH doit battre

Voici la discipline qui sépare une vraie évaluation d'une démo. Avant de couronner GARCH, vous devez lui donner des adversaires bon marché, évidents et étonnamment difficiles à battre. Si votre modèle GJR-t élaboré ne peut pas surpasser un EWMA de cinq lignes, vous avez appris quelque chose de précieux et vous êtes épargné beaucoup de complexité en production.

Nous comparons quatre prévisionnistes de la volatilité de la période suivante.

(a) Volatilité réalisée passée (écart-type glissant)

La prévision la plus naïve : la volatilité de demain égale l'écart-type d'échantillon des nn derniers rendements journaliers.

σ^tRV=1n1i=1n(rti+1rˉ)2\hat\sigma_{t}^{\text{RV}} = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}\bigl(r_{t-i+1}-\bar r\bigr)^2}

Elle a un hyperparamètre (la fenêtre nn, généralement 20-60 jours) et aucun modèle. Son défaut est que chaque observation dans la fenêtre reçoit un poids égal, puis chute brutalement d'une falaise quand elle en sort — l'effet de « fantôme » ou d'« écho », où un seul jour de krach gonfle la prévision pendant exactement nn jours puis disparaît du jour au lendemain, que le marché se soit réellement calmé ou non.

(b) EWMA / RiskMetrics (λ=0.94\lambda = 0.94)

La moyenne mobile pondérée exponentiellement corrige le problème d'écho en donnant un poids décroissant géométriquement aux rendements carrés plus anciens :

σ^t2=λσ^t12+(1λ)rt2\hat\sigma_{t}^{2} = \lambda\,\hat\sigma_{t-1}^{2} + (1-\lambda)\,r_{t}^{2}

C'est l'estimateur RiskMetrics (J.P. Morgan, 1996). Avec le λ=0.94\lambda = 0.94 canonique pour les données journalières, la mémoire effective est d'environ 1/(1λ)171/(1-\lambda) \approx 17 jours, mais la décroissance est lisse — pas de falaise. Notez ce qu'EWMA est réellement : un GARCH(1,1) intégré avec ω=0\omega = 0 et α+β=1\alpha + \beta = 1, c'est-à-dire un GARCH sans retour à la moyenne et sans variance de long terme. Il a zéro paramètre libre si vous acceptez λ=0.94\lambda = 0.94, et c'est la référence la plus coriace de tout cet article. Une grande partie des articles « GARCH bat X » échouent discrètement à battre EWMA hors échantillon.

import numpy as np
import pandas as pd

def ewma_vol(returns: pd.Series, lam: float = 0.94, sigma0: float | None = None) -> pd.Series:
    """RiskMetrics EWMA conditional volatility (returns in decimal, e.g. 0.03).

    sigma2_t = lam * sigma2_{t-1} + (1 - lam) * r_t^2
    Returns a series aligned to `returns` where value at t uses info up to t.
    """
    r2 = np.square(returns.values)
    var = np.empty_like(r2)
    var[0] = sigma0**2 if sigma0 is not None else r2[0]
    for t in range(1, len(r2)):
        var[t] = lam * var[t - 1] + (1.0 - lam) * r2[t - 1]  # note: r_{t-1}, no look-ahead
    return pd.Series(np.sqrt(var), index=returns.index, name="ewma_vol")

La subtilité unique qui piège les gens : la prévision pour la période tt (utilisable pour dimensionner une position tenue sur tt) doit être construite à partir des rendements observés avant tt. Dans la récursion ci-dessus, var[t] utilise r2[t-1], de sorte que la série est une véritable prévision à un pas d'avance. Bien positionner cet indice fait la différence entre un backtest et un fantasme — nous y reviendrons dans la section walk-forward.

(c) GARCH(1,1) et GJR-t (Parties 1-2)

Nos protagonistes. GARCH(1,1) standard :

σt2=ω+αϵt12+βσt12,ω>0, α,β0, α+β<1\sigma_t^2 = \omega + \alpha\, \epsilon_{t-1}^2 + \beta\,\sigma_{t-1}^2, \qquad \omega>0,\ \alpha,\beta\ge0,\ \alpha+\beta<1

avec la variance de long terme σˉ2=ω/(1αβ)\bar\sigma^2 = \omega/(1-\alpha-\beta) et la prévision à un pas qui découle directement de la récursion (Partie 1). L'extension GJR-GARCH ajoute un terme d'effet de levier pour que les chocs négatifs augmentent davantage la variance que les positifs :

σt2=ω+(α+γ1[ϵt1<0])ϵt12+βσt12\sigma_t^2 = \omega + (\alpha + \gamma\, \mathbb{1}[\epsilon_{t-1}<0])\,\epsilon_{t-1}^2 + \beta\,\sigma_{t-1}^2

et couplé à des innovations Student-t pour gérer les queues épaisses de la crypto, c'est le GJR-t de la Partie 2. La raison pour laquelle GARCH peut battre EWMA est le retour à la moyenne : après un choc, GARCH ramène la prévision vers σˉ2\bar\sigma^2 à un rythme gouverné par α+β\alpha+\beta, alors qu'EWMA (étant intégré) ne revient jamais. Quand la volatilité s'envole puis se normalise — le cas courant — la prévision de GARCH décroît plus vite et plus précisément. Quand la volatilité est véritablement persistante, les deux sont presque indiscernables.

(d) HAR-RV sur la variance réalisée (si vous avez des données intrajournalières)

Si vous avez des barres intrajournalières — et sur les marchés crypto 24/7 c'est presque toujours le cas — vous pouvez construire un proxy de volatilité bien moins bruité que les rendements carrés journaliers : la variance réalisée, la somme des rendements intrajournaliers carrés sur la journée.

RVt=i=1Mrt,i2(e.g. M=288 five-minute bars)RV_t = \sum_{i=1}^{M} r_{t,i}^2 \qquad (\text{e.g. } M = 288 \text{ five-minute bars})

Le modèle Heterogeneous Autoregressive de Corsi (2009) prévoit la variance réalisée de demain à partir des moyennes journalière, hebdomadaire et mensuelle des RVRV passées — une manière grossière mais remarquablement efficace de capturer la persistance à mémoire longue avec trois régresseurs :

RVt+1=β0+βdRVt+βwRVt(5)+βmRVt(22)+ut+1RV_{t+1} = \beta_0 + \beta_d\, RV_t + \beta_w\, \overline{RV}_t^{(5)} + \beta_m\, \overline{RV}_t^{(22)} + u_{t+1}

RVt(5)\overline{RV}_t^{(5)} et RVt(22)\overline{RV}_t^{(22)} sont les moyennes glissantes sur 5 jours et 22 jours de la RVRV journalière. C'est une simple régression OLS, elle exploite le proxy intrajournalier de meilleure qualité, et c'est fréquemment le meilleur prévisionniste de volatilité journalière des quatre — battant souvent GARCH précisément parce que RVRV est une cible plus propre que r2r^2.

import numpy as np
import pandas as pd

def realized_variance(intraday_returns: pd.Series, day_index) -> pd.Series:
    """Daily realized variance = sum of squared intraday (log) returns per day.
    `intraday_returns` indexed by timestamp; `day_index` maps to calendar day.
    """
    return intraday_returns.pow(2).groupby(day_index).sum()

def har_features(rv: pd.Series) -> pd.DataFrame:
    """Build HAR regressors from a daily realized-variance series."""
    df = pd.DataFrame({"rv": rv})
    df["rv_d"] = df["rv"].shift(1)                          # yesterday
    df["rv_w"] = df["rv"].shift(1).rolling(5).mean()        # trailing week
    df["rv_m"] = df["rv"].shift(1).rolling(22).mean()       # trailing month
    df["target"] = df["rv"]                                 # predict today's RV
    return df.dropna()

def fit_har(rv: pd.Series):
    """Fit HAR-RV by OLS. Returns (coef_dict, predict_fn)."""
    df = har_features(rv)
    X = np.column_stack([np.ones(len(df)), df["rv_d"], df["rv_w"], df["rv_m"]])
    y = df["target"].values
    beta, *_ = np.linalg.lstsq(X, y, rcond=None)
    names = ["const", "rv_d", "rv_w", "rv_m"]

    def predict(rv_d, rv_w, rv_m):
        return float(beta @ np.array([1.0, rv_d, rv_w, rv_m]))

    return dict(zip(names, beta)), predict

Une note sur le log-HAR : parce que RVRV est asymétrique à droite et strictement positif, de nombreux praticiens régressent logRVt+1\log RV_{t+1} sur des features HAR en log, ce qui améliore l'ajustement et garantit des prévisions positives. Quand vous exponentiez pour revenir en arrière, vous devriez ajouter une correction de Jensen de demi-variance, RV^=exp(y^+12σ^u2)\widehat{RV} = \exp(\hat{y} + \tfrac{1}{2}\hat\sigma_u^2), sinon vous sous-prévoirez systématiquement.

Avec quatre prévisionnistes en main — RV, EWMA, GARCH/GJR-t, HAR — la question devient : comment décider lequel est le meilleur, quand nous ne pouvons jamais voir la chose qu'ils essaient tous de prédire ?

Évaluer honnêtement une prévision de volatilité

C'est l'enseignement central de l'article, alors ralentissez ici.

Vous voulez comparer des prévisions σ^t2\hat\sigma_t^2 à la vraie variance conditionnelle σt2\sigma_t^2. Mais σt2\sigma_t^2 est une quantité latente — c'est un paramètre du processus générateur des données, jamais directement observé. Tout ce que vous obtenez est un rendement réalisé par jour. Ainsi, toute évaluation de volatilité est en réalité une comparaison de votre prévision à un proxy bruité de la vérité. Les deux proxys standards :

  • Rendements carrés rt2r_t^2. Sans biais pour σt2\sigma_t^2 sous un modèle à moyenne nulle (E[rt2Ft1]=σt2\mathbb{E}[r_t^2 \mid \mathcal{F}_{t-1}] = \sigma_t^2), mais extrêmement bruité : un seul rendement journalier est une estimation à une observation d'un écart-type. Le proxy rt2r_t^2 peut valoir 0 (une journée plate) même quand la vraie volatilité est élevée, ou être énorme lors d'une journée chanceuse de queue.
  • Variance réalisée RVtRV_t à partir de données intrajournalières. Bien moins bruitée — l'échantillonnage intrajournalier moyenne le bruit idiosyncratique d'un rendement unique — ce qui est exactement pourquoi HAR-RV fonctionne et pourquoi vous devriez utiliser RVRV comme proxy si vous avez la moindre donnée intrajournalière.

La subtilité qui piège presque tout le monde : parce que le proxy est bruité, le choix de la fonction de perte n'est pas innocent. Classez deux prévisions avec la mauvaise perte et le proxy bruité peut inverser le classement, vous disant que la pire prévision est la meilleure. Patton (2011) a déterminé précisément quelles fonctions de perte sont « robustes » au sens où classer les prévisions par perte attendue sur le proxy bruité donne le même classement que celui obtenu sur la vraie variance (inobservable). Seule une famille spécifique se qualifie. Deux membres comptent en pratique.

MSE vs QLIKE

L'erreur quadratique moyenne sur la variance :

LMSE(σ2,h)=(σ2h)2L_{\text{MSE}}(\sigma^2, h) = (\sigma^2 - h)^2

h=σ^2h = \hat\sigma^2 est la prévision et σ2\sigma^2 est proxifié par r2r^2 ou RVRV. La MSE est robuste au sens de Patton (son classement est cohérent avec le proxy), mais elle est symétrique et dépendante de l'échelle : elle pénalise également une sur-prévision et une sous-prévision de même taille absolue, et elle pondère énormément plus les erreurs pendant les périodes de haute volatilité que celles pendant les périodes calmes. Un modèle qui cloue les 95 % de jours calmes mais fait exploser les prévisions de variance sur les trois jours de crise paraîtra terrible sous MSE, même si son comportement en crise est exactement ce que vous voulez.

La perte QLIKE (quasi-vraisemblance) est le cheval de bataille :

LQLIKE(σ2,h)=σ2hlogσ2h1L_{\text{QLIKE}}(\sigma^2, h) = \frac{\sigma^2}{h} - \log\frac{\sigma^2}{h} - 1

C'est la perte impliquée par une vraisemblance gaussienne sur la variance, elle est également robuste au sens de Patton, et elle a deux propriétés qui en font le choix préféré pour la volatilité. Premièrement, elle est asymétrique dans le bon sens : elle pénalise la sous-prévision de variance plus que la sur-prévision. Pour un gestionnaire de risque ou un cibleur de volatilité, c'est la bonne asymétrie — sous-prévoir la volatilité signifie que vous avez pris une taille trop grande juste avant que cela compte, ce qui est l'erreur coûteuse. Deuxièmement, elle est (à peu près) invariante d'échelle : parce qu'elle dépend du ratio σ2/h\sigma^2/h, une erreur de prévision de 10 % coûte à peu près la même chose qu'elle survienne un jour calme ou un jour de crise, de sorte que l'évaluation n'est pas détournée par une poignée d'observations à haute variance comme l'est la MSE. Cette robustesse à l'hétéroscédasticité du proxy est exactement ce que vous voulez quand tout l'enjeu est que la volatilité varie sauvagement.

Notez que LQLIKE0L_{\text{QLIKE}} \ge 0, avec égalité si et seulement si h=σ2h = \sigma^2. Plus bas est mieux, comme pour la MSE.

import numpy as np

def qlike(proxy: np.ndarray, forecast_var: np.ndarray) -> np.ndarray:
    """Per-observation QLIKE loss. `proxy` is r^2 or RV (a variance proxy),
    `forecast_var` is h = sigma_hat^2. Both strictly positive, same units.
    """
    ratio = proxy / forecast_var
    return ratio - np.log(ratio) - 1.0

def mse_var(proxy: np.ndarray, forecast_var: np.ndarray) -> np.ndarray:
    """Per-observation MSE on the variance scale."""
    return np.square(proxy - forecast_var)

Deux avertissements opérationnels. Gardez le proxy et la prévision dans des unités identiques (les deux en variances journalières, ou les deux annualisées) ou le ratio n'a aucun sens. Et ne laissez jamais forecast_var atteindre zéro — bornez-le à un petit plancher, car log0\log 0 empoisonnera toute la moyenne.

Régression de Mincer-Zarnowitz

Un seul chiffre de perte vous dit quelle prévision est meilleure ; il ne vous dit pas comment une prévision se trompe. La régression de Mincer-Zarnowitz (1969) le fait. Régressez le proxy sur la prévision :

rt2  =  a+bσ^t2+ut.r_t^2 \;=\; a + b\,\hat\sigma_t^2 + u_t.

Sous une prévision optimale et sans biais, a=0a = 0 et b=1b = 1 : en moyenne la variance réalisée égale la prévision. Les écarts diagnostiquent la pathologie :

  • b<1b < 1 avec a>0a > 0 : la signature classique d'une prévision trop volatile — elle sur-réagit, prédisant des extrêmes qui ne se matérialisent pas pleinement. Très courant pour les modèles bruts pilotés par les rendements carrés.
  • b>1b > 1 : la prévision sous-réagit, s'échelonnant trop peu avec la vraie variance.
  • R2R^2 de régression faible : même si a,ba,b semblent corrects en moyenne, la prévision suit mal la variance jour après jour. Parce que le proxy est si bruité, ne soyez pas alarmé que le R2R^2 de MZ contre r2r^2 ne soit souvent que de 0,05-0,20 ; contre RVRV il sera bien plus élevé. Le R2R^2 contre r2r^2 est borné bien en dessous de 1 quelle que soit la qualité de la prévision, purement à cause du bruit du proxy.

Un test FF conjoint de H0:(a,b)=(0,1)H_0: (a,b) = (0,1) donne une vérification formelle de calibration. En pratique, utilisez MZ comme diagnostic pour comprendre une prévision, et QLIKE pour classer les prévisions.

Diebold-Mariano : la différence est-elle réelle ?

Supposons que la QLIKE moyenne de GARCH soit 0,183 et celle d'EWMA 0,191. GARCH « gagne ». Mais 0,008 est-il un vrai avantage ou du bruit d'échantillonnage ? Le test de Diebold-Mariano (1995) répond exactement à cela. Définissez le différentiel de perte par période

dt=L(proxyt,htA)L(proxyt,htB)d_t = L(\text{proxy}_t, h^A_t) - L(\text{proxy}_t, h^B_t)

pour deux prévisions AA et BB (ici LL = QLIKE). L'hypothèse nulle est l'égalité de précision prédictive, H0:E[dt]=0H_0: \mathbb{E}[d_t] = 0. La statistique est le différentiel moyen standardisé par son erreur-type de long terme (HAC), car dtd_t est autocorrélé :

DM=dˉLRV^(dt)/T  d  N(0,1)\text{DM} = \frac{\bar d}{\sqrt{\widehat{\mathrm{LRV}}(d_t)/T}} \;\xrightarrow{d}\; \mathcal{N}(0,1)

LRV^\widehat{\mathrm{LRV}} est une estimation de variance de long terme de type Newey-West. Une statistique DM au-delà de ±1.96\pm 1.96 rejette l'égalité de précision à 5 %. De façon cruciale, DM est un test sur les prévisions, pas sur des modèles emboîtés, et il gère la dépendance sérielle dans la série de pertes qu'un test tt naïf sur dtd_t ignorerait.

import numpy as np
from scipy import stats

def diebold_mariano(loss_a: np.ndarray, loss_b: np.ndarray, h: int = 1):
    """Diebold-Mariano test of equal predictive accuracy.
    loss_a, loss_b: per-period losses (e.g. QLIKE) for forecasts A and B.
    h: forecast horizon; Newey-West lag = h - 1 (>=0), plus a small-sample buffer.
    Returns (DM_stat, p_value). Negative DM => A has lower loss (A better).
    """
    d = np.asarray(loss_a) - np.asarray(loss_b)
    T = len(d)
    d_bar = d.mean()

    lag = max(h - 1, 0)
    gamma0 = np.mean((d - d_bar) ** 2)
    lrv = gamma0
    for k in range(1, lag + 1):
        w = 1.0 - k / (lag + 1)
        cov = np.mean((d[k:] - d_bar) * (d[:-k] - d_bar))
        lrv += 2.0 * w * cov

    dm = d_bar / np.sqrt(lrv / T)

    adj = np.sqrt((T + 1 - 2 * h + h * (h - 1) / T) / T)
    dm *= adj
    p = 2.0 * (1.0 - stats.t.cdf(abs(dm), df=T - 1))
    return float(dm), float(p)

Le résultat illustratif dans ce commentaire est l'issue honnête et courante, et c'est toute la raison d'être de cette section : GARCH affiche souvent une perte moyenne légèrement inférieure à EWMA, et tout aussi souvent cet avantage ne franchit pas la barre de significativité de DM. Si vous ne rapportez jamais que la QLIKE moyenne, vous vous convaincrez d'avantages qu'un test DM aurait recalés. Rapportez la statistique DM. C'est la même discipline que nous appliquons aux rendements de stratégie dans évaluation honnête sans avantage robuste — une estimation ponctuelle qui bat une référence n'est pas un avantage tant que vous n'avez pas écarté qu'il s'agisse de bruit.

Le backtest : une stratégie walk-forward à volatilité ciblée

Maintenant nous combinons les deux moitiés — un prévisionniste et une règle de dimensionnement — en une stratégie et l'évaluons de la seule façon qui ait un sens : walk-forward, hors échantillon, avec coûts.

La stratégie est délibérément simple, car la simplicité est ce qui nous permet d'attribuer le résultat à la prévision de volatilité plutôt qu'à un signal astucieux. BTC long-only, à volatilité ciblée. Chaque jour, prévoyez la volatilité du lendemain, fixez la position à wt=min(σtarget/σ^t, wmax)w_t = \min(\sigma_{\text{target}}/\hat\sigma_t,\ w_{\max}), tenez pendant la nuit, et répétez. Une variante long/flat désactive la position quand un filtre de tendance est négatif ; une variante de petit portefeuille dimensionne sur la matrice de covariance DCC de la Partie 3 au lieu de la variance d'un actif unique. Nous décrivons le cas long-only en entier et notons les extensions.

Mécanique du walk-forward et le contrat de non-look-ahead

La propriété la plus importante de ce backtest est que chaque quantité utilisée pour dimensionner la position au jour t+1t+1 est calculable en utilisant uniquement les données disponibles à la clôture du jour tt. Les paramètres GARCH sont réestimés sur une fenêtre glissante se terminant en tt ; la prévision est le σ^t+1\hat\sigma_{t+1} à un pas d'avance issu de cet ajustement ; la position est fixée à partir de cette prévision ; et le rendement gagné est wt+1rt+1w_{t+1} r_{t+1}, où rt+1r_{t+1} est le rendement du jour suivant, que le modèle n'a jamais vu. Réajuster GARCH sur l'échantillon complet puis « prévoir » le passé est la façon la plus courante dont les gens fabriquent accidentellement un excellent backtest. Nous traitons ce piège du look-ahead et la méthodologie générale dans optimisation walk-forward.

import numpy as np
import pandas as pd
from arch import arch_model

def walk_forward_voltarget(
    returns: pd.Series,          # daily log returns in decimal (e.g. 0.021)
    proxy_var: pd.Series,        # variance proxy aligned to returns (RV or r^2)
    target_vol_annual: float = 0.20,
    window: int = 750,           # rolling estimation window (days)
    refit_every: int = 5,        # refit GARCH weekly, forecast daily (cost saver)
    w_max: float = 3.0,          # leverage cap
    cost_bps: float = 5.0,       # per-unit-turnover cost in basis points
    ann: int = 365,              # crypto trades 365 days/yr
):
    """Long-only vol-targeted BTC, GARCH(1,1)-t forecasts, strictly walk-forward.
    Returns a DataFrame with position, forecast vol, net returns, and turnover.
    """
    idx = returns.index
    target_daily = target_vol_annual / np.sqrt(ann)

    fcast_vol = pd.Series(index=idx, dtype=float, name="fcast_vol")
    last_res = None

    for i in range(window, len(returns) - 1):
        if (i - window) % refit_every == 0 or last_res is None:
            train = returns.iloc[i - window:i + 1] * 100.0   # scale for the optimizer
            am = arch_model(train, mean="Constant", vol="GARCH",
                            p=1, o=1, q=1, dist="t")           # GJR-t, Part 2
            last_res = am.fit(disp="off")

        f = last_res.forecast(horizon=1, reindex=False)
        var_next = f.variance.values[-1, 0] / (100.0 ** 2)    # unscale
        fcast_vol.iloc[i + 1] = np.sqrt(var_next)

    raw_w = (target_daily / fcast_vol).clip(upper=w_max)
    position = raw_w.shift(0)                                  # w_{i+1} known at close i
    gross_ret = position * returns                            # earned on day i+1

    turnover = position.diff().abs().fillna(0.0)
    cost = turnover * (cost_bps / 1e4)
    net_ret = (gross_ret - cost).dropna()

    out = pd.DataFrame({
        "position": position,
        "fcast_vol": fcast_vol,
        "gross_ret": gross_ret,
        "turnover": turnover,
        "net_ret": net_ret,
    }).dropna()
    return out

def performance_stats(net_ret: pd.Series, ann: int = 365) -> dict:
    """Sharpe, realized vol, max drawdown, CAGR, annual turnover."""
    mu = net_ret.mean() * ann
    sigma = net_ret.std() * np.sqrt(ann)
    sharpe = mu / sigma if sigma > 0 else np.nan
    equity = (1.0 + net_ret).cumprod()
    peak = equity.cummax()
    max_dd = (equity / peak - 1.0).min()
    cagr = equity.iloc[-1] ** (ann / len(net_ret)) - 1.0
    return {
        "sharpe": round(sharpe, 2),
        "realized_vol": round(sigma, 3),
        "max_drawdown": round(max_dd, 3),
        "cagr": round(cagr, 3),
    }

Quelques notes d'implémentation qui comptent plus qu'il n'y paraît :

  • Mise à l'échelle pour l'optimiseur. Les ajustements arch sont numériquement plus heureux quand les rendements sont en pourcentage, d'où le * 100 et le / 100**2 correspondant lors de la remise à l'échelle de la variance. Oubliez la remise à l'échelle et votre volatilité cible est fausse d'un facteur 10 000.
  • Cadence de réajustement. Réestimer les paramètres GARCH chaque jour est coûteux et n'ajoute presque rien — les paramètres sont stables de semaine en semaine. Réajuster chaque semaine (refit_every=5) tout en prévoyant quotidiennement (la récursion met à jour σt2\sigma_t^2 à partir des nouveaux rendements même sans réajustement) est le compromis standard. Cela reflète le conseil de mise en cache du pipeline de copules dans modèles de copules pour le risque joint.
  • Le plafond wmaxw_{\max} n'est pas cosmétique. Quand la volatilité prévue s'effondre dans un régime de calme plat, σtarget/σ^t\sigma_{\text{target}}/\hat\sigma_t peut exploser à 5x, 10x de levier. Un ciblage de volatilité non plafonné vous remettra joyeusement un levier catastrophique juste avant un changement de régime de volatilité — l'instant précis où la prévision est sur le point d'être la plus fausse. Plafonnez-le (3x ici) et reconnaissez que le plafond sera contraignant précisément dans les périodes les plus calmes et, rétrospectivement, les plus dangereuses.
  • Les coûts croissent avec le turnover, et le ciblage de volatilité est une machine à turnover. Chaque oscillation de la prévision redimensionne la position. Sur un actif à faible volatilité avec une prévision nerveuse vous pouvez faire tourner le livre quotidiennement. Le terme cost_bps n'est pas un détail d'arrondi ; pour un ciblage de volatilité à fort turnover il peut engloutir une fraction significative de l'amélioration du Sharpe brut.

À quoi ressemble la sortie (illustratif)

Exécuter cela sur des données journalières BTC sur une fenêtre pluriannuelle, en comparant les quatre prévisionnistes comme dénominateur de dimensionnement, tend à produire un tableau ayant la forme suivante. Les chiffres ci-dessous sont illustratifs — choisis à la main pour montrer le schéma typique, pas la sortie d'un vrai backtest — mais l'ordonnancement et les ordres de grandeur sont représentatifs de ce que rapportent les praticiens.

Prévision de dimensionnement Sharpe Vol réalisée Vol cible Drawdown max Turnover ann.
Notionnel fixe (sans ciblage) 0.71 0.68 -0.78 0.1x
RV glissante (60j) 0.94 0.24 0.20 -0.41 12x
EWMA (λ=0.94\lambda=0.94) 1.02 0.21 0.20 -0.35 19x
GARCH(1,1)-t 1.05 0.21 0.20 -0.33 22x
HAR-RV (proxy intrajournalier) 1.09 0.20 0.20 -0.31 20x

Deux variantes qui valent la peine d'être construites

Le cas long-only isole la prévision, mais deux extensions sont assez courantes pour être montrées explicitement.

Long/flat avec une porte de tendance. Le ciblage de volatilité dimensionne la position mais ne prend aucune vue directionnelle — il est toujours long. Une amélioration bon marché et honnête consiste à désactiver la position quand un filtre de tendance lent devient négatif, de sorte que vous ne teniez le long à volatilité ciblée que dans les tendances haussières et restiez à plat sinon. Cela garde la logique de dimensionnement identique et superpose un filtre de régime grossier ; cela ne prétend pas chronométrer les entrées, seulement éviter de tenir à travers des tendances baissières évidentes.

def apply_trend_gate(position: pd.Series, price: pd.Series, fast: int = 20, slow: int = 100):
    """Zero out the (already vol-targeted) position when the fast SMA is below
    the slow SMA. Both SMAs use only past prices, so no look-ahead is introduced.
    """
    fast_ma = price.rolling(fast).mean().shift(1)   # shift: known at prior close
    slow_ma = price.rolling(slow).mean().shift(1)
    gate = (fast_ma > slow_ma).astype(float)        # 1.0 in uptrend, 0.0 otherwise
    return position * gate.reindex(position.index).fillna(0.0)

La porte de tendance réduit le turnover à la baisse (vous cessez de faire tourner une position qui rétrécit dans un marché baissier) mais ajoute son propre risque de régime — elle fait des allers-retours dans les marchés latéraux hachés et est en retard aux retournements. Savoir si elle aide est une question empirique à laquelle vous devez répondre avec la même rigueur walk-forward et testée par DM que la règle de dimensionnement elle-même ; un filtre de tendance est exactement le genre d'ajout qui paraît excellent en échantillon et s'évapore hors échantillon.

Ciblage de volatilité de portefeuille sur la covariance DCC. Pour un livre de plusieurs actifs, la prévision scalaire σ^t\hat\sigma_t devient la volatilité du portefeuille wΣtw\sqrt{w^\top \Sigma_t w}, où Σt\Sigma_t est la matrice de covariance variant dans le temps issue du DCC-GARCH de la Partie 3. Vous choisissez des poids de base w0w_0 (poids égaux, capitalisation boursière, ou une inclinaison moyenne-variance), calculez la volatilité prévue du portefeuille sous Σt\Sigma_t, et mettez à l'échelle tout le vecteur de poids pour atteindre la cible du portefeuille.

def portfolio_voltarget_weights(base_w, cov_forecast, target_vol_daily, w_gross_max=3.0):
    """Scale a base weight vector so forecast portfolio vol hits the target.
    base_w:        (n,) base allocation (need not sum to 1).
    cov_forecast:  (n, n) one-step-ahead covariance from DCC-GARCH (daily units).
    """
    base_w = np.asarray(base_w, dtype=float)
    port_var = float(base_w @ cov_forecast @ base_w)
    port_vol = np.sqrt(max(port_var, 1e-12))
    scale = min(target_vol_daily / port_vol, w_gross_max / np.abs(base_w).sum())
    return scale * base_w

C'est le pont naturel vers la littérature de construction de portefeuille : les poids de base w0w_0 peuvent venir de moyenne-variance de Markowitz ou d'une méthode fondée sur le risque comme HRP/CVaR, et le ciblage de volatilité se place alors par-dessus comme une surcouche qui met à l'échelle le risque agrégé à une constante. La matrice DCC compte parce que les corrélations s'envolent dans les krachs (Partie 3) — un portefeuille qui paraît diversifié en marchés calmes peut avoir une volatilité prévue bien plus élevée que ne l'implique une covariance statique, précisément quand cela compte, et la surcouche coupe l'exposition brute en réponse.

Diagnostics que vous devriez toujours tracer

Ne faites jamais confiance au seul tableau récapitulatif. Pour tout ciblage de volatilité, tracez trois choses et examinez-les avant de croire le moindre chiffre de Sharpe. Premièrement, la volatilité glissante réalisée de la stratégie contre la ligne cible — elle devrait épouser la cible ; une dérive systématique au-dessus signifie que votre prévision est biaisée à la baisse (la direction coûteuse). Deuxièmement, la série de position/levier — cherchez le plafond qui contraint et les pics de levier juste avant les drawdowns, la signature d'une prévision prise en défaut par un changement de régime. Troisièmement, le nuage de points prévision-vs-proxy (l'image de Mincer-Zarnowitz) — un nuage avec une pente loin de 1 vous dit que la prévision est mal mise à l'échelle d'une façon que la moyenne QLIKE peut cacher. Ces trois graphiques attrapent plus de bugs et plus d'auto-illusions que n'importe quelle statistique isolée.

Lisez ce tableau comme vous devriez lire chaque tableau de backtest : regardez ce qui est robuste et ce qui est marginal. Les faits robustes sautent aux yeux. Chaque variante à volatilité ciblée écrase le notionnel fixe sur le Sharpe et, plus spectaculairement, sur le drawdown et la stabilité de la volatilité réalisée — la stratégie à notionnel fixe tourne à 68 % de volatilité annualisée avec un drawdown de 78 %, ce qui est tout simplement non investissable. Et chaque méthode de ciblage délivre une volatilité réalisée proche de la cible de 20 %, ce qui est toute la promesse du mécanisme qui fonctionne. Les faits marginaux sont les différences parmi les prévisionnistes : HAR devance GARCH devance EWMA devance la RV glissante, mais les écarts sont petits — un dixième de point de Sharpe — et, testés avec Diebold-Mariano sur les prévisions ou un bootstrap sur les rendements, échoueraient fréquemment à franchir la significativité. Ce petit écart fragile et dépendant du régime entre le prévisionniste sophistiqué et le naïf est le titre honnête de toute cette série.

Être honnête sur ce que cela vous rapporte

Ce blog a une collection entière sur le backtesting sans se leurrer, alors appliquons-la à notre propre résultat plutôt que d'espérer discrètement que vous ne le fassiez pas.

Le ciblage de volatilité améliore le rendement ajusté du risque et les drawdowns. Il ne fabrique pas d'alpha à partir de rien. Regardez à nouveau le tableau. L'amélioration du Sharpe issue du ciblage est réelle et vaut la peine d'être obtenue — mais décomposez-la et l'essentiel vient de ne pas tenir une position constante dans les régimes de haute volatilité, ce qui évite mécaniquement les pires drawdowns et stabilise la trajectoire de composition. La stratégie est toujours long BTC ; elle n'a aucune vue que le marché ne lui donne pas. Si BTC a un Sharpe négatif sur votre échantillon, le ciblage de volatilité vous remettra un Sharpe négatif moins mauvais, pas un positif. Il remodèle la distribution des rendements — queues plus fines, volatilité plus régulière, meilleure composition géométrique — mais l'avantage directionnel brut est ce que vaut le long sous-jacent. Ne laissez pas une belle courbe d'équité vous tromper en vous faisant croire que vous avez trouvé de l'alpha alors que vous avez trouvé de la gestion de risque. Moreira-Muir ont trouvé un véritable alpha dans les facteurs actions issus de la gestion de volatilité, mais ce résultat concerne l'arbitrage risque-rendement variant dans le temps du facteur, et il ne se transfère pas automatiquement à un actif crypto unique sur un échantillon différent.

L'avantage en qualité de prévision de GARCH sur EWMA est souvent petit et dépendant du régime. C'est le retour inconfortable des Parties 1-3. Vous avez construit des modèles de plus en plus sophistiqués — termes d'effet de levier, queues Student-t, corrélations dynamiques — et la contribution marginale de chacun à un P&L de ciblage de volatilité, par rapport à un EWMA naïf, est fréquemment dans la bande de bruit. L'avantage de GARCH (le retour à la moyenne après les chocs) se manifeste surtout dans des régimes spécifiques : des pics brusques qui se normalisent ensuite. Dans les tendances laborieuses ou les régimes de haute volatilité persistante il diffère à peine d'EWMA. Cela ne rend pas GARCH inutile — la structure de retour à la moyenne, les paramètres interprétables, la capacité à simuler des trajectoires vers l'avant et à valoriser des options contre la prévision ont toutes une valeur qu'EWMA n'a pas — mais si votre seul usage est le dimensionnement, exécutez le test DM avant de payer le coût de complexité, et sachez que la détection de régime vous dit la même chose sous un angle différent : le modèle gagnant dépend du régime.

Le Sharpe de backtest est une borne supérieure du Sharpe en réel, et le ciblage de volatilité élargit l'écart. Parce que la stratégie est intensive en turnover et à échelle de levier, elle est inhabituellement sensible aux frictions qu'un backtest naïf omet : vos exécutions sont pires que la clôture sur laquelle vous avez dimensionné, les coûts de financement sur les positions perp à effet de levier s'accumulent en continu, et le plafond de levier interagit avec la mécanique de marge et de liquidation qu'un simple w * return ignore. Chacune de celles-ci rend le réel pire que le backtest. Nous traitons cet écart systématiquement dans parité backtest-réel ; pour le ciblage de volatilité spécifiquement, budgétez-le en utilisant des coûts conservateurs, un plafond de levier réaliste (bas), et en exécutant sur l'ouverture de la barre suivante plutôt que sur la clôture à partir de laquelle vous avez calculé le signal.

Un aparté sur la prime de risque de volatilité. Tout ce qui précède prévoit la volatilité réalisée. Il existe un objet parallèle, tradable : la volatilité implicite, valorisée dans les options, qui en moyenne se situe au-dessus de la volatilité réalisée subséquente — la prime de risque de volatilité, compensation pour supporter le risque d'un pic de volatilité. Cet écart est lui-même une source de rendement (vendre de la variance le récolte, l'acheter couvre le risque de queue), et c'est un jeu véritablement différent du ciblage de volatilité : c'est un pari sur le prix de la volatilité plutôt qu'un usage d'une prévision de volatilité. Nous ne le poursuivons pas ici, mais la machinerie commence avec le modèle de valorisation dans valorisation d'options Black-Scholes, et une bonne prévision de volatilité réalisée (Parties 1-2) est exactement l'entrée dont vous avez besoin pour juger si la volatilité implicite est chère ou bon marché. Comparer votre prévision GARCH à la volatilité implicite du marché des options est l'un des usages les plus honnêtes de tout ce que vous avez construit dans cette série.

Considérations pratiques

Un fourre-tout de choses qui séparent un ciblage de volatilité qui fonctionne d'un fragile.

  • Estimez sur le bon horizon. Si vous dimensionnez une position tenue un jour, prévoyez la volatilité à un jour. Si vous rééquilibrez chaque semaine, prévoyez (et ciblez) la volatilité hebdomadaire, ou agrégez la prévision GARCH journalière sur l'horizon — la prévision GARCH multi-pas revient vers σˉ2\bar\sigma^2, ce que la mise à l'échelle naïve « hdaily\sqrt{h}\cdot\text{daily} » ignore. La Partie 1 couvre la prévision GARCH multi-pas.
  • Annualisation sur les marchés 24/7. La crypto se trade 365 jours par an sans week-ends ni jours fériés, donc annualisez la volatilité journalière avec 365\sqrt{365}, pas le 252\sqrt{252} des actions. Se tromper là-dessus mal-échelonne silencieusement votre cible d'environ 20 %.
  • Le dénominateur peut être une matrice de covariance. Pour un livre multi-actifs, remplacez le scalaire σ^t\hat\sigma_t par la volatilité de portefeuille wΣtw\sqrt{w^\top \Sigma_t w} issue du DCC-GARCH de la Partie 3, et mettez à l'échelle tout le vecteur de poids pour atteindre la volatilité cible du portefeuille. Cela relie le ciblage de volatilité au dimensionnement moyenne-variance (Markowitz pour la crypto) et à l'allocation fondée sur le risque (pipelines HRP et CVaR) — le ciblage de volatilité est le cas particulier mono-actif de la mise à l'échelle à un budget de risque de portefeuille.
  • Le ciblage de volatilité est procyclique d'une manière subtile. Quand tout le monde exécute la même règle 1/σ1/\sigma, un pic de volatilité force un désendettement synchronisé, qui pousse les prix vers le bas, ce qui augmente la volatilité réalisée, ce qui force davantage de désendettement. Cette rétroaction (bien documentée dans le « volmageddon » de 2018 et diverses cascades de désendettement crypto) signifie que la règle fonctionne moins bien exactement quand de nombreux acteurs l'utilisent. Ce n'est pas une raison de l'abandonner, mais c'est une raison de plafonner le levier et de ne pas supposer que vos exécutions pendant un pic de volatilité ressembleront aux exécutions de marché calme.
  • Bornez et écrêtez la prévision. Une volatilité prévue nulle ou quasi nulle produit un levier infini. Bornez toujours σ^t\hat\sigma_t à un minimum sensé et plafonnez la position, et journalisez à quelle fréquence chacun contraint — si le plafond contraint la plupart du temps, votre cible est trop agressive pour l'actif.

Résumé

  • Une prévision de volatilité n'a aucune valeur tant qu'elle ne modifie pas une décision. Le ciblage de volatilité — dimensionner l'exposition comme wt=σtarget/σ^tw_t = \sigma_{\text{target}}/\hat\sigma_t (plafonné) — est le test le plus propre de la valeur d'une prévision, car la qualité de la prévision se traduit directement en un profil de volatilité réalisée plus plat et un Sharpe plus élevé.
  • Le ciblage de volatilité augmente le rendement ajusté du risque et, surtout, contrôle les drawdowns, parce que la volatilité est prévisible (elle se regroupe) alors que la direction ne l'est pas, et parce que les ratios de Sharpe chutent dans les régimes de haute volatilité que la règle sous-pondère automatiquement. C'est un dimensionnement de Kelly sous l'hypothèse que le rendement attendu croît avec la volatilité.
  • Comparez GARCH honnêtement à des références solides : volatilité réalisée glissante, EWMA/RiskMetrics (λ=0.94\lambda=0.94, un IGARCH avec zéro paramètre libre), et HAR-RV sur un proxy de variance réalisée intrajournalier. EWMA et HAR sont difficiles à battre.
  • Vous ne pouvez pas observer la vraie volatilité, alors évaluez contre un proxy (r2r^2 ou, bien mieux, RVRV) en utilisant des fonctions de perte robustes au bruit du proxy. Préférez QLIKE à MSE : elle pénalise davantage la sous-prévision (l'erreur coûteuse) et est invariante d'échelle, donc elle n'est pas détournée par quelques jours de haute volatilité. Utilisez Mincer-Zarnowitz pour diagnostiquer le biais et le test de Diebold-Mariano pour décider si l'avantage d'une prévision est réel ou du bruit.
  • Dans un backtest walk-forward conscient des coûts, le ciblage de volatilité bat fiablement le notionnel fixe sur le Sharpe et le drawdown, et les quatre prévisionnistes se regroupent étroitement — l'avantage de GARCH sur EWMA est petit, dépendant du régime, et souvent non statistiquement significatif. Rapportez le test DM, pas seulement la perte moyenne.
  • Soyez honnête : le ciblage de volatilité est de la gestion de risque, pas de l'alpha. Il remodèle la distribution des rendements de n'importe quel pari directionnel que vous aviez déjà ; il ne crée pas d'avantage à partir de rien. Et il est intensif en turnover et à échelle de levier, donc les résultats réels traînent derrière le backtest plus que d'habitude.

Références :

  • Patton, A. J. (2011). Volatility forecast comparison using imperfect volatility proxies. Journal of Econometrics, 160(1), 246-256. DOI
  • Corsi, F. (2009). A simple approximate long-memory model of realized volatility. Journal of Financial Econometrics, 7(2), 174-196. DOI
  • Diebold, F. X., & Mariano, R. S. (1995). Comparing predictive accuracy. Journal of Business & Economic Statistics, 13(3), 253-263. DOI
  • Mincer, J., & Zarnowitz, V. (1969). The evaluation of economic forecasts. In Economic Forecasts and Expectations, NBER.
  • Moreira, A., & Muir, T. (2017). Volatility-managed portfolios. Journal of Finance, 72(4), 1611-1644. DOI
  • J.P. Morgan / Reuters (1996). RiskMetrics Technical Document, 4th ed.
  • Bollerslev, T. (1986). Generalized autoregressive conditional heteroskedasticity. Journal of Econometrics, 31(3), 307-327. DOI
  • Glosten, L. R., Jagannathan, R., & Runkle, D. E. (1993). On the relation between the expected value and the volatility of the nominal excess return on stocks. Journal of Finance, 48(5), 1779-1801. DOI
  • Harvey, D., Leybourne, S., & Newbold, P. (1997). Testing the equality of prediction mean squared errors. International Journal of Forecasting, 13(2), 281-291. DOI
blog.disclaimer

MarketMaker.cc Team

Recherche quantitative et stratégie

Discuter sur Telegram
Newsletter

Gardez une longueur d'avance sur le marché

Abonnez-vous à notre newsletter pour des insights exclusifs sur le trading IA, des analyses de marché et des mises à jour de la plateforme.

Nous respectons votre vie privée. Désabonnement possible à tout moment.