Reconstruire 20 ans de Volatilité : GARCH, SVI et VRP — Un Guide Pratique pour le Backtest d'Options

Quant Trading

Comment reconstruire une surface de volatilité historique complète from scratch en utilisant uniquement des données de prix journaliers — sans abonnement données options. Nous couvrons la Variance Risk Premium (VRP), l'estimation de vol conditionnelle GARCH(1,1) avec innovations Student-t, et la paramétrisation SVI pour des sourires de volatilité sans arbitrage. Inclut la calibration du skew dépendante du régime (crise vs calme), la classe Python QuantSkewEngine complète, et une visualisation timeline du skew sur 20 ans de régimes de marché.

Skew Modelisation
Antoine Perrin Profile Picture

Antoine

CEO - CodeMarketLabs

2026-04-28

Reconstruire 20 ans de Volatilité : GARCH, SVI et VRP — Un Guide Pratique pour le Backtest d'Options

Backtester une stratégie d'options semble simple jusqu'à ce qu'on se heurte au vrai problème : il faut des données de volatilité implicite pour chaque strike, chaque jour, sur 20 ans. Les fournisseurs professionnels font payer plusieurs milliers de dollars par an pour ça. Les historiques de chaînes d'options du CBOE ou d'OptionMetrics coûtent encore plus cher. Pour la plupart des quants indépendants et des traders systématiques, ces données n'existent tout simplement pas. Cet article présente une approche complète et reproductible pour reconstruire une surface de volatilité from scratch — en utilisant uniquement les données de prix journaliers de Yahoo Finance — et explique les fondements théoriques de chaque étape : ce qu'est la Variance Risk Premium, pourquoi le GARCH capture mieux la volatilité réalisée qu'une fenêtre glissante, et comment la paramétrisation SVI produit un sourire de volatilité réaliste sur tous les strikes et tous les régimes.

Ce que couvre cet article

  • Ce qu'est la Variance Risk Premium (VRP) et pourquoi elle est le fondement théorique des stratégies short-volatilité.
  • Pourquoi la volatilité réalisée seule ne suffit pas à pricer des options — et ce qu'ajoute la vol implicite.
  • GARCH(1,1) avec innovations Student-t : le modèle standard pour estimer la volatilité conditionnelle sur les indices actions.
  • La paramétrisation SVI (Stochastic Volatility Inspired) : un modèle à 5 paramètres qui produit des sourires de vol sans arbitrage.
  • Skew dépendant du régime : comment calibrer sigma_smooth, rho, skew_strength et m dynamiquement selon le niveau de vol.
  • La classe QuantSkewEngine complète : des données de prix brutes à une surface interpolée pour chaque jour de trading.
  • Visualisation : un chart timeline du skew montrant comment le sourire se déforme entre les régimes de crise et de calme.
  • Prochaine étape : à quoi ressemblerait une calibration sur données de vol implicite réelles, et pourquoi la surface synthétique est une approximation défendable.

1. La Variance Risk Premium : Pourquoi la Vente de Volatilité Fonctionne

La Variance Risk Premium (VRP) est la différence entre la volatilité implicite et la volatilité réalisée sur la même période. Sur les indices actions, la vol implicite — la vol que le marché intègre dans le prix des options — a historiquement été plus élevée que la vol qui s'est effectivement matérialisée. Le VIX, par exemple, a tourné en moyenne autour de 19–20% sur les 30 dernières années, tandis que la vol réalisée du S&P 500 a plutôt été de l'ordre de 15–16%. Cet écart — environ 3 à 5 points de vol en moyenne — c'est la VRP. Il représente la prime de risque que les acheteurs d'options paient pour leur protection, et que les vendeurs encaissent en contrepartie du risque de queue qu'ils portent.

La VRP n'est pas constante. Elle se comprime dans les régimes calmes (2013–2017) et explose lors des stress — en mars 2020, le VIX a atteint 85 alors que la vol réalisée sur les mêmes 30 jours était plutôt autour de 60%. L'écart entre les deux est ce qui pilote le P&L des stratégies short-vol systématiques. Quand la VRP est positive et stable, la vente d'options collecte du premium de façon régulière. Quand la VRP se contracte ou s'inverse — comme cela peut arriver lors de dislocations rapides et violentes — les positions short-vol saignent.

Dans un backtest sans données de vol implicite, la VRP est le paramètre clé à modéliser. Le paramètre vrp_bps dans le QuantSkewEngine fait exactement ça : il ajoute un spread en points de base sur la vol réalisée estimée par GARCH pour approximer le niveau de vol implicite que le marché aurait pricé. Mettre vrp_bps=0 revient à supposer qu'il n'y a pas de VRP — une hypothèse conservatrice. vrp_bps=300 ajoute 3 points de vol, proche de la moyenne historique long terme. C'est le levier le plus honnête de tout le moteur : il contrôle l'écart entre ce que le modèle pense être la vol réalisée et ce qu'il suppose que le marché aurait facturé.

2. Du Réalisé à l'Implicite : Pourquoi un Modèle est Nécessaire

La volatilité réalisée — l'écart-type des log-returns journaliers sur une fenêtre glissante — est rétrospective par construction. Elle dit ce qui s'est passé. Les options sont pricées sur ce que le marché anticipe. Cette distinction compte pour le backtest. Si on price les options avec une vol réalisée glissante sur 20 ou 30 jours, on va systématiquement sous-pricer les options dans les régimes calmes (quand la vol réalisée est basse mais que le marché facture quand même une prime de peur) et sur-pricer après une crise (quand la vol réalisée est haute mais que le marché a déjà repricé à la baisse).

Un modèle de volatilité conditionnelle — spécifiquement le GARCH — résout partiellement ce problème. Le GARCH(1,1) estime la volatilité comme une moyenne pondérée de la variance long terme, du carré du return de la période précédente, et de la variance estimée à la période précédente. Il mean-reverts. Après un spike, il décroît vers la moyenne inconditionnelle plus vite qu'une fenêtre glissante. Après une période de calme, il reste bas plutôt que d'être tiré vers le haut par une fenêtre 30 jours qui inclut une crise lointaine. Ça fait du GARCH un meilleur proxy de ce que le marché aurait pricé — pas parfait, mais dans la bonne direction.

La distribution Student-t pour les innovations compte sur les indices actions. Les returns journaliers ont des queues épaisses — les mouvements extrêmes arrivent plus souvent qu'un modèle gaussien ne le prédit. Fitter le GARCH avec des innovations Student-t produit un meilleur fit in-sample et surtout des estimations de vol mieux calibrées pendant les événements de queue qui pilotent l'essentiel du P&L dans les stratégies d'options. Le paramètre de degrés de liberté de la distribution t est estimé conjointement avec les paramètres GARCH pendant le fit.

3. Le Modèle SVI : Un Sourire de Volatilité Réaliste

Black-Scholes suppose une volatilité constante sur tous les strikes. Le marché non. Les puts OTM sur les indices actions se tradent à des vols implicites significativement plus élevées que les options ATM — c'est le skew de volatilité. Les calls OTM lointains se tradent à des vols plus basses que l'ATM. Le résultat est un sourire (ou plus précisément un smirk) quand on trace la vol implicite contre le strike ou la log-moneyness.

La paramétrisation SVI, introduite par Gatheral (2004), décrit la variance totale implicite w(k) = σ²(k) × T comme une fonction de la log-moneyness k = log(K/F) : w(k) = a + b × (ρ × (k − m) + √((k − m)² + σ²)). Les cinq paramètres ont des interprétations intuitives : a contrôle le niveau global de variance (le point ATM), b contrôle la pente et la courbure, ρ est la corrélation entre spot et vol (négative pour les indices actions — l'effet levier), m décale le minimum du sourire loin de l'ATM, et σ (sigma_smooth ici) contrôle la douceur de la transition entre le wing put et le wing call. Un sigma_smooth petit produit une forme en V sharp ; un grand produit une forme en U lissé.

La propriété clé du SVI est qu'il est sans arbitrage par construction pour un large espace de paramètres — il satisfait spécifiquement la condition de no-butterfly-arbitrage qui empêche qu'un arbitrage de calendar spread ou de butterfly n'apparaisse dans la surface. Ça le rend approprié pour un moteur de pricing : on ne va pas générer de prix d'options négatifs ou de spreads inversés en évaluant la surface à différents strikes.

4. Paramètres Dépendants du Régime : Calibrer le Skew à la Réalité du Marché

Un seul jeu de paramètres SVI ne peut pas capturer le comportement du sourire de vol sur tous les régimes de marché. Dans les marchés calmes (VIX < 15), le skew est peu marqué — la différence entre la vol implicite à 90% et 100% de moneyness peut être de 3 à 5 points de vol. Dans une crise (VIX > 40), la même distance peut atteindre 20 à 30 points. Le sourire se resserre aussi — sigma_smooth diminue — et le minimum se décale davantage vers les calls OTM quand la demande de protection puts submerge le marché.

Le QuantSkewEngine gère ça via get_skew_params, qui mappe la vol ATM estimée par GARCH vers un jeu de paramètres SVI. Trois régimes sont définis : crise (atm_vol > 40%), stress modéré (25–40%), et calme (< 25%). En régime de crise, rho est poussé à −0,99 (corrélation quasi entièrement négative entre les mouvements spot et vol), skew_strength est à 1,2 (wing put raide), m décale le minimum à 0,08 en log-moneyness (bien dans le territoire call OTM), et sigma_smooth reste à 0,10 (transition serrée mais non singulière). En régime calme, tous les paramètres se relaxent vers un sourire peu marqué et centré.

C'est une calibration synthétique — les paramètres ne sont pas fittés sur des données de marché mais fixés manuellement pour correspondre à la forme qualitative du sourire dans chaque régime. C'est une simplification. Mais c'est une simplification fondée : le sens de chaque ajustement de paramètre est ancré dans ce à quoi ressemblent réellement les surfaces de vol des indices actions. Une surface SPX de crise en mars 2020 avait un rho proche de −1, un wing put raide et un minimum bien au-dessus de l'ATM. La surface synthétique capture ce comportement qualitatif même sans données de marché pour la calibrer précisément.

5. Le QuantSkewEngine Complet

Le moteur prend un DataFrame avec une colonne Close et construit une surface de volatilité complète pour chaque jour de trading. Le workflow est : fitter un modèle GARCH sur la série complète de returns pour extraire la vol conditionnelle, puis générer une surface SVI pour chaque date en utilisant la vol ATM du GARCH et les paramètres SVI dépendants du régime. Le résultat est un dictionnaire d'interpolateurs — un par date — qu'on peut interroger à n'importe quel strike avec get_vol_at_date.

python
import numpy as np
import pandas as pd
from arch import arch_model
from scipy.interpolate import interp1d
from datetime import datetime
import bisect


class QuantSkewEngine:
    def __init__(self, df):
        self.df = df
        self.surfaces = {}
        self.returns = 100 * np.log(self.df['Close'] / self.df['Close'].shift(1)).dropna()

    def get_skew_params(self, atm_vol):
        """Paramètres SVI dépendants du régime.
        Crise  : skew put raide, transition sharp, skew_strength élevé
        Stress : skew modéré
        Calme  : sourire peu marqué et centré
        """
        if atm_vol > 0.40:       # Crise
            return dict(sigma_smooth=0.10, rho=-0.99, skew_strength=1.2, m=0.08)
        elif atm_vol > 0.25:     # Stress modéré
            return dict(sigma_smooth=0.12, rho=-0.90, skew_strength=0.8, m=0.06)
        else:                    # Calme
            return dict(sigma_smooth=0.15, rho=-0.75, skew_strength=0.4, m=0.04)

    def generate_surface(self, atm_vol, spot, vrp_bps, skew_strength):
        """Construit un interpolateur SVI pour une date donnée.
        vrp_bps : points de base ajoutés à la vol ATM pour approximer la VRP
        """
        atm_vol_q = atm_vol + (vrp_bps / 10000)  # ajout de la VRP
        ratios = np.linspace(0.70, 1.30, 101)
        k = np.log(ratios)                         # grille de log-moneyness

        p = self.get_skew_params(atm_vol)
        a = atm_vol_q ** 2
        b = p['skew_strength'] * atm_vol_q

        def svi_curve(k_val):
            k_shifted = k_val - p['m']
            total_var = a + b * (
                p['rho'] * k_shifted
                + np.sqrt(k_shifted ** 2 + p['sigma_smooth'] ** 2)
            )
            return np.sqrt(max(0.0025, total_var))  # floor à 5% de vol

        vols = np.array([svi_curve(val) for val in k])
        return interp1d(spot * ratios, vols, kind='cubic', fill_value='extrapolate')

    def run_backtest_interpolation(self, vrp_bps=0, skew_strength=0.20):
        """Fit GARCH une fois sur la série complète, puis génère une surface par date.
        Note : le fit GARCH global utilise les données futures pour l'estimation
        des paramètres. C'est une simplification connue — les paramètres sont
        stables et l'impact sur les estimations de vol conditionnelle est faible.
        """
        model = arch_model(self.returns, p=1, q=1, vol='GARCH', dist='t')
        res = model.fit(disp='off')

        # Vol conditionnelle annualisée
        vols_annuelles = (res.conditional_volatility / 100) * np.sqrt(252)

        for date, atm_vol in vols_annuelles.items():
            clean_date = date.to_pydatetime()
            spot = float(self.df.loc[date, 'Close'])
            interp = self.generate_surface(atm_vol, spot, vrp_bps, skew_strength)
            self.surfaces[clean_date] = {
                'spot':         spot,
                'atm_vol':      atm_vol,
                'interpolator': interp
            }

        print(f'Surface générée pour {len(self.surfaces)} jours.')
        return self.surfaces

    def get_vol_at_date(self, target_date, strike):
        """Interroge la surface à un strike donné. Retourne la date disponible
        la plus proche si la date exacte est manquante."""
        if hasattr(target_date, 'to_pydatetime'):
            target_date = target_date.to_pydatetime()

        if target_date in self.surfaces:
            vol = float(self.surfaces[target_date]['interpolator'](strike))
            return max(0.01, vol)

        available = sorted(self.surfaces.keys())
        if not available:
            return 0.15
        idx = bisect.bisect_right(available, target_date) - 1
        vol = float(self.surfaces[available[max(0, idx)]]['interpolator'](strike))
        return max(0.01, vol)

6. Visualiser la Surface : Un Timeline du Skew

Le diagnostic le plus utile pour le moteur est un timeline du skew : tracer le sourire de vol sur plusieurs dates clés sur le même chart, avec la série de vol ATM en panel supérieur pour le contexte. Ça montre immédiatement si la calibration dépendante du régime fonctionne — les dates de crise doivent avoir des wings put raides, les dates calmes des sourires peu marqués et symétriques.

python
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker


def plot_skew_timeline(skew_engine, dates_of_interest, figsize=(16, 8)):
    """Trace la série de vol ATM + les courbes de sourire aux dates sélectionnées.

    Paramètres
    ----------
    skew_engine        : instance QuantSkewEngine déjà fittée
    dates_of_interest  : liste de datetime
    """
    # ── Série de vol ATM depuis les surfaces du moteur ────────────────────
    atm_vols = pd.Series(
        {date: surface['atm_vol'] * 100
         for date, surface in skew_engine.surfaces.items()}
    ).sort_index()

    colors = ['cyan', '#FF6B6B', '#FFD93D', '#6BCB77', '#A78BFA', '#F97316']

    fig, (ax_vol, ax_skew) = plt.subplots(
        2, 1, figsize=figsize, facecolor='#0d0d0d',
        gridspec_kw={'height_ratios': [2, 3]}
    )

    # ── Panel 1 : vol ATM (échelle log) ──────────────────────────────────
    ax_vol.set_facecolor('#0d0d0d')
    ax_vol.plot(atm_vols.index, atm_vols.values,
                color='white', linewidth=1, alpha=0.8)
    ax_vol.fill_between(atm_vols.index, atm_vols.values,
                        alpha=0.15, color='white')
    ax_vol.set_yscale('log')
    ax_vol.set_ylabel('Vol ATM — GARCH (%)', color='white', fontsize=10)
    ax_vol.tick_params(colors='white', labelsize=9)
    ax_vol.yaxis.set_major_formatter(
        mticker.FuncFormatter(lambda x, _: f'{x:.0f}%')
    )
    for spine in ax_vol.spines.values():
        spine.set_edgecolor('#333333')
    ax_vol.grid(True, color='#1a1a1a', linewidth=0.5)

    for i, d in enumerate(dates_of_interest):
        col = colors[i % len(colors)]
        ax_vol.axvline(d, color=col, linewidth=1, linestyle='--', alpha=0.8)

    # ── Panel 2 : courbes de skew ─────────────────────────────────────────
    ax_skew.set_facecolor('#0d0d0d')

    for i, d in enumerate(dates_of_interest):
        available = sorted(skew_engine.surfaces.keys())
        closest   = min(available, key=lambda x: abs((x - d).days))
        surface   = skew_engine.surfaces[closest]
        spot      = surface['spot']
        interp    = surface['interpolator']

        strikes   = np.linspace(spot * 0.75, spot * 1.25, 300)
        vols      = np.array([max(0.01, float(interp(k))) for k in strikes])
        moneyness = (strikes / spot - 1) * 100

        col   = colors[i % len(colors)]
        label = closest.strftime('%b %Y')
        ax_skew.plot(moneyness, vols * 100, color=col,
                     linewidth=1.8, label=label)

    ax_skew.axvline(0, color='white', linewidth=0.5,
                    linestyle='--', alpha=0.3)
    ax_skew.set_xlim(-25, 10)
    ax_skew.set_xlabel('Moneyness (%)', color='white', fontsize=10)
    ax_skew.set_ylabel('Vol Implicite (%)', color='white', fontsize=10)
    ax_skew.tick_params(colors='white', labelsize=9)
    for spine in ax_skew.spines.values():
        spine.set_edgecolor('#333333')
    ax_skew.grid(True, color='#1a1a1a', linewidth=0.5)
    ax_skew.yaxis.set_major_formatter(mticker.FormatStrFormatter('%.0f%%'))
    ax_skew.xaxis.set_major_formatter(mticker.FormatStrFormatter('%+.0f%%'))
    ax_skew.legend(facecolor='#1a1a1a', edgecolor='#333333',
                   labelcolor='white', fontsize=9, loc='upper right')

    fig.suptitle('Sourire de Volatilité par Régime',
                 color='white', fontsize=13, y=1.01)
    plt.tight_layout()
    plt.savefig('skew_timeline.png', dpi=150,
                bbox_inches='tight', facecolor='#0d0d0d')
    plt.show()


# ── Usage ────────────────────────────────────────────────────────────────────
dates_cles = [
    datetime(2006, 6,  1),   # régime calme, vol basse
    datetime(2008, 10, 10),  # Lehman
    datetime(2011, 8,  5),   # Downgrade US
    datetime(2020, 3,  20),  # Crash COVID
    datetime(2022, 6,  15),  # pivot hawkish Fed
    datetime(2024, 8,  5),   # flash crash JPY
]

plot_skew_timeline(bt.skew, dates_cles)
Skew Modelisation
Skew Modelisation

7. Limites et Chemin vers une Surface Correctement Calibrée

La surface synthétique a trois limites honnêtes. Premièrement, les paramètres SVI ne sont pas fittés sur des données de marché — ils sont fixés manuellement pour correspondre au comportement qualitatif du sourire dans chaque régime. La forme du sourire est plausible mais pas précise. Sur une date donnée, le skew réel du marché à un strike spécifique peut différer significativement de ce que le moteur produit. Deuxièmement, il n'y a pas de structure par terme : la surface ne varie pas selon l'échéance. Une surface à 7 DTE devrait être plus raide qu'à 30 DTE ; le moteur produit le même sourire pour les deux. Troisièmement, le modèle GARCH est fitté sur la série historique complète — un fit global qui utilise techniquement les données futures pour l'estimation des paramètres.

La prochaine étape vers une surface correctement calibrée serait : obtenir des données historiques d'options (CBOE DataShop, OptionMetrics, ou les données historiques Interactive Brokers pour les périodes récentes), extraire les vols implicites à chaque strike et échéance via une inversion Black-Scholes numérique, et fitter les paramètres SVI sur chaque date en minimisant l'erreur quadratique entre les vols du modèle et du marché. Ça remplacerait la calibration synthétique de get_skew_params par une calibration data-driven, et exposerait immédiatement la structure par terme. Pour un premier backtest exploratoire, l'approche synthétique est défendable. Pour un déploiement en production ou une attribution précise du P&L, la surface calibrée est indispensable.

Ce que contient le Notebook

  • Classe QuantSkewEngine complète avec fit GARCH, génération de surface SVI dépendante du régime, et interpolation par strike.
  • Fonction plot_skew_timeline : série de vol ATM (échelle log) + courbes de sourire aux dates définies par l'utilisateur.
  • Exemple d'intégration : comment passer le moteur au BSOptionPricingEngine pour le repricing live d'options pendant un backtest.
  • Analyse de sensibilité VRP : lancer le moteur à vrp_bps = 0, 150, 300 et comparer les prix d'options résultants.
  • Prêt à tourner sur n'importe quel ticker actions ou futures Yahoo Finance — changer la colonne Close et relancer.
Pourquoi utiliser le GARCH plutôt qu'une volatilité glissante sur 30 jours ?

Une fenêtre glissante pondère toutes les observations de façon égale sur la fenêtre et ignore tout ce qui est en dehors. Le GARCH pondère les observations récentes plus fortement via sa structure autorégressive, et il mean-reverts — après un spike, il décroît plus vite qu'une fenêtre 30 jours qui gardera le spike dans la moyenne pendant un mois entier. Pour le pricing d'options, le GARCH produit aussi des transitions plus douces entre les régimes, ce qui évite les discontinuités artificielles quand une observation de crise entre ou sort d'une fenêtre glissante.

Que fait exactement le paramètre vrp_bps ?

Il ajoute un nombre fixe de points de base à la vol ATM estimée par GARCH avant de générer la surface SVI. vrp_bps=0 signifie que le modèle suppose que la vol implicite est égale à la vol réalisée — pas de prime de risque. vrp_bps=300 ajoute 3 points de vol, approximant la VRP long terme historique moyenne sur les indices actions US. Ce paramètre affecte directement les prix d'options : un vrp_bps plus élevé signifie plus de premium collecté sur les options short et plus de premium payé sur les options long. C'est le paramètre le plus sensible du moteur en termes de P&L.

Pourquoi le skew se pentifie-t-il en crise ?

La demande de puts OTM explose lors des stress de marché. Les investisseurs et les fonds achètent des puts pour hedger leur exposition long actions, et les dealers qui vendent ces puts demandent des primes plus élevées pour compenser le risque de gap accru. Ce déséquilibre de la demande pousse les vols implicites des puts OTM bien au-dessus de la vol ATM, pentifiant le côté gauche du sourire. Simultanément, la demande de calls OTM diminue quand la spéculation à la hausse chute, aplatissant le côté droit. Le résultat est le smirk asymétrique caractéristique des surfaces des indices actions en crise.

Que contrôle le paramètre m dans le SVI ?

m décale le minimum de la courbe de variance loin du point ATM (k=0 en log-moneyness). Sur les indices actions, le minimum du sourire est typiquement légèrement au-dessus de l'ATM — autour de 5 à 10% OTM call — parce que le skew call est positif tandis que le skew put est négatif. Fixer m=0,06 à 0,08 décale le minimum au niveau des strikes approximatifs 106–108%, ce qui correspond bien aux surfaces SPX observées.

Le fit GARCH global est-il un problème pour le backtest ?

En principe, oui — fitter le GARCH sur la série complète utilise des données futures pour estimer les paramètres. En pratique, les paramètres GARCH (omega, alpha, beta) sont stables et convergent rapidement sur 2 à 3 ans de données. La différence entre un fit global et un fit sur fenêtre expanding est faible pour la série de vol conditionnelle. Ça compterait davantage pour une stratégie qui trade explicitement les changements de paramètres GARCH. Pour un backtest Iron Condor où le driver principal est la collecte de premium, l'approximation est acceptable.

Comment calibrerait-on la surface sur de vraies données de vol implicite ?

Le processus est : pour chaque date historique, collecter les vols implicites de marché à plusieurs strikes depuis des chaînes d'options réelles. Convertir chaque paire (strike, vol implicite marché) en variance totale implicite w = σ² × T. Puis minimiser la somme des erreurs quadratiques entre le modèle SVI w(k) et les valeurs w du marché, par rapport aux cinq paramètres SVI (a, b, rho, m, sigma). C'est un problème de moindres carrés non linéaire que scipy.optimize.minimize gère bien avec une bonne initialisation. Les paramètres résultants remplacent les valeurs calibrées manuellement de get_skew_params par des valeurs data-driven.

Articles Similaires

Long/Short Thumbnail

Le Long/Short expliqué par un trader pro : trade peu importe si le marché monte ou baisse

Un tour complet des stratégies long/short equity telles qu'utilisées en institution : mean reversion, relative value, divergence, beta hedging, et deux backtests Python — JPMorgan vs Goldman Sachs et SPY vs FEZ. Inclut l'exécution sur IBKR et une analyse honnête des risques que personne ne mentionne.

Quant Trading
miniature video Iron condor

Backtest Iron Condor sur ES Futures : +1539% en 20 ans — VRP, Greeks et Limites Honnêtes

Un backtest complet Iron Condor sur ES Futures de 2005 à 2026 : comment reconstruire une surface de volatilité sans données options, comment modéliser la VRP, et ce que les cinq Greeks signifient concrètement pour une position short-vol. Inclut cinq scénarios de réinvestissement avec métriques réelles (CAGR, Sharpe 1,68, Sortino 1,46, drawdown max −9,4%), une analyse honnête des limites du modèle (skew plat, VRP fixe), et une description de la stratégie en production avec delta hedging dynamique, vega hedging et monitoring du charm.

Quant Trading
Skew Modelisation

Reconstruire 20 ans de Volatilité : GARCH, SVI et VRP — Un Guide Pratique pour le Backtest d'Options

Comment reconstruire une surface de volatilité historique complète from scratch en utilisant uniquement des données de prix journaliers — sans abonnement données options. Nous couvrons la Variance Risk Premium (VRP), l'estimation de vol conditionnelle GARCH(1,1) avec innovations Student-t, et la paramétrisation SVI pour des sourires de volatilité sans arbitrage. Inclut la calibration du skew dépendante du régime (crise vs calme), la classe Python QuantSkewEngine complète, et une visualisation timeline du skew sur 20 ans de régimes de marché.

Quant Trading
Tous les articles ont été chargés