Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor · · Updated 2026-08-21

Calcul de la VaR : trois méthodes

Comparez les méthodes historique, paramétrique et Monte Carlo sur une même série de rendements SPY, puis mesurez l’expected shortfall absent de la VaR.

La value at risk, ou VaR, se calcule en fixant un horizon et un niveau de confiance, puis en lisant un percentile dans une série de rendements. Une VaR à un jour et à 99 % de 2 % signifie que la perte reste inférieure à 2 % lors de 99 séances sur 100 et dépasse ce seuil lors de la centième. Trois méthodes classiques répondent à cette question à partir des mêmes données d’entrée. Leurs résultats peuvent toutefois diverger bien davantage que ne le pensent la plupart des observateurs.

Ce que mesure réellement la Value at Risk

La VaR est un quantile d’une distribution de pertes. Classez tous les rendements quotidiens d’un échantillon du plus mauvais au meilleur, avancez de 1 % depuis l’extrémité défavorable, puis exprimez comme une perte positive le rendement atteint : vous obtenez la VaR historique à 99 % sur un jour. Cette construction ne promet en rien un scénario extrême. Elle situe la limite de la zone que l’estimation cesse de décrire.

C’est la propriété la plus souvent mal interprétée. Une VaR à 99 % indique que les 1 % de journées les plus mauvaises se situent au-delà du seuil. Elle ne dit pas jusqu’où. Le drawdown maximal répond à une autre question : la perte entre un point haut et un point bas effectivement subie par un portefeuille. Les deux mesures peuvent donc classer deux portefeuilles dans l’ordre opposé.

Tous les chiffres ci-dessous reposent sur une seule série : les cours de clôture quotidiens de SPY, du début de 2010 à la fin de 2025, convertis en variations en pourcentage d’une clôture à l’autre. La période est fixe, et non glissante. Chaque panneau reconstruit la série à partir des mêmes dates. Les chiffres ne varient donc pas d’une exécution à l’autre.

RequêteSérie de rendements épinglée : rendements journaliers de SPY par année civile, de 2010 à 2025
Le SQL exact derrière chaque chiffre
WITH
px AS
(
    SELECT date, max(toFloat64(close)) AS close_px
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2009-12-01'
      AND date <  '2026-01-01'
    GROUP BY date
),
rets AS
(
    SELECT date, 100 * (close_px / prev_close - 1) AS ret_pct
    FROM
    (
        SELECT date, close_px,
               lagInFrame(close_px, 1) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_close
        FROM px
    )
    WHERE date >= '2010-01-01' AND prev_close > 0
)
SELECT
    toString(toYear(date))        AS year,
    count()                       AS sessions,
    round(avg(ret_pct), 3)        AS mean_return_pct,
    round(stddevSamp(ret_pct), 2) AS daily_sigma_pct
FROM rets
GROUP BY year
ORDER BY year
Run this yourself

La série couvre 16 années civiles, dont 252 séances pour la seule année 2010. Deux caractéristiques sont importantes pour la suite. À cet horizon, le rendement moyen par séance est presque négligeable : 0.054% en 2010, contre un écart-type quotidien, sigma, de 1.13%. Et sigma n’est pas constant. 2020 affichait 2.11% par jour, contre 2017 pour 0.43%. Un seul sigma ne peut pas décrire les deux périodes.

Comment calculer la value at risk, trois méthodes

VaR historique : lire le percentile dans les données observées

Triez les rendements observés, puis prenez le percentile. Aucune distribution n’est supposée, ce qui fait l’intérêt de la méthode. En revanche, elle suppose que l’échantillon contient déjà le type de journée que l’estimation est censée couvrir. Si vous poussez suffisamment loin le niveau de confiance, seuls les quelques pires séances de toute la fenêtre déterminent le résultat.

VaR paramétrique : moyenne moins z multiplié par sigma

Résumez la série par sa moyenne et son sigma, puis supposez que les rendements suivent une loi normale. La VaR correspond à z multiplié par sigma, moins la moyenne, où z est le quantile de la loi normale centrée réduite : 1,645 à 95 %, 2,326 à 99 %, 3,090 à 99,9 %. Le calcul est immédiat, mais l’hypothèse échoue dans une direction précise. Les rendements quotidiens des actions sont plus concentrés qu’une courbe normale au centre et vont beaucoup plus loin dans les extrêmes. Le sigma est ici le dénominateur qui intervient aussi dans le ratio de Sharpe, avec le même angle mort face aux données à queues épaisses.

VaR de Monte Carlo : simuler avec une seed fixe

Générez un vaste échantillon synthétique à partir d’un processus donné, puis lisez le percentile dans les tirages. Le panneau ci-dessous utilise 40 000 tirages selon une loi normale centrée réduite, construits par la transformation de Box-Muller à partir d’une séquence uniforme initialisée par un hash, puis ajustés à la moyenne et au sigma de la série. La seed figure dans le SQL, de sorte que les tirages sont identiques à chaque nouvelle exécution. La simulation apporte de la souplesse, la dépendance au chemin et la corrélation entre plusieurs actifs, mais pas davantage de réalisme : si vous lui fournissez une loi normale, elle renvoie la réponse paramétrique, avec un bruit d’échantillonnage en plus. Rééchantillonner les rendements observés, comme dans les intervalles de confiance bootstrap, permet en revanche de conserver la vraie queue de distribution.

RequêteUne série, trois méthodes : VaR à 1 jour selon six niveaux de confiance
Le SQL exact derrière chaque chiffre
WITH
px AS
(
    SELECT date, max(toFloat64(close)) AS close_px
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2009-12-01'
      AND date <  '2026-01-01'
    GROUP BY date
),
rets AS
(
    SELECT date, 100 * (close_px / prev_close - 1) AS ret_pct
    FROM
    (
        SELECT date, close_px,
               lagInFrame(close_px, 1) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_close
        FROM px
    )
    WHERE date >= '2010-01-01' AND prev_close > 0
),
emp AS
(
    SELECT
        avg(ret_pct)                  AS mu,
        stddevSamp(ret_pct)           AS sd,
        quantileExact(0.100)(ret_pct) AS h90,
        quantileExact(0.050)(ret_pct) AS h95,
        quantileExact(0.025)(ret_pct) AS h975,
        quantileExact(0.010)(ret_pct) AS h99,
        quantileExact(0.005)(ret_pct) AS h995,
        quantileExact(0.001)(ret_pct) AS h999
    FROM rets
),
draws AS
(
    SELECT
        quantileExact(0.100)(z) AS z90,
        quantileExact(0.050)(z) AS z95,
        quantileExact(0.025)(z) AS z975,
        quantileExact(0.010)(z) AS z99,
        quantileExact(0.005)(z) AS z995,
        quantileExact(0.001)(z) AS z999
    FROM
    (
        SELECT sqrt(-2 * log(u1)) * cos(2 * pi() * u2) AS z
        FROM
        (
            SELECT
                (cityHash64('var-seed-u1', i) % 999999937 + 1) / 999999938.0 AS u1,
                (cityHash64('var-seed-u2', i) % 999999937 + 1) / 999999938.0 AS u2
            FROM (SELECT arrayJoin(range(40000)) AS i)
        )
    )
)
SELECT
    tupleElement(lvl, 1)                                                  AS confidence,
    round(-1 * tupleElement(lvl, 2), 2)                                   AS historical_var_pct,
    round(tupleElement(lvl, 3) * sd - mu, 2)                              AS parametric_var_pct,
    round(-1 * (mu + sd * tupleElement(lvl, 4)), 2)                       AS monte_carlo_var_pct,
    round(-1 * tupleElement(lvl, 2) - (tupleElement(lvl, 3) * sd - mu), 2) AS method_spread
FROM
(
    SELECT
        mu,
        sd,
        arrayJoin([
            ('90.0%', h90,  1.281552, z90,  1),
            ('95.0%', h95,  1.644854, z95,  2),
            ('97.5%', h975, 1.959964, z975, 3),
            ('99.0%', h99,  2.326348, z99,  4),
            ('99.5%', h995, 2.575829, z995, 5),
            ('99.9%', h999, 3.090232, z999, 6)
        ]) AS lvl
    FROM emp
    CROSS JOIN draws
)
ORDER BY tupleElement(lvl, 5)
Run this yourself

Au niveau 95.0%, les trois méthodes aboutissent à moins d’un point d’écart : 1.66% pour la méthode historique, 1.74% pour la méthode paramétrique et 1.71% pour la simulation. À 99.9%, elles divergent : 5.85% pour la méthode historique contre 3.31% pour la méthode paramétrique, soit un écart de 2.54 points de pourcentage sur des données identiques. La colonne simulée reste alignée sur la colonne paramétrique à chaque niveau. C’est la conclusion à retenir, et non un défaut. Une simulation reproduit la distribution qui lui est fournie.

Lisez le panneau verticalement : chaque hausse du niveau de confiance élargit le seuil. Lisez-le horizontalement : le choix de la méthode a peu d’incidence au centre de la distribution, mais devient déterminant dans la queue. Une limite de VaR indiquée sans sa méthode ni sa fenêtre d’observation n’est pas un chiffre que quiconque peut reproduire.

Ce que la VaR ne dit pas : l’expected shortfall

L’expected shortfall, également appelé VaR conditionnelle, correspond à la moyenne des pertes enregistrées les jours où la VaR est dépassée. La VaR indique où commence la queue de distribution. L’expected shortfall mesure ce qui se trouve à l’intérieur.

RequêteVaR et expected shortfall : perte moyenne au-delà du seuil
Le SQL exact derrière chaque chiffre
WITH
px AS
(
    SELECT date, max(toFloat64(close)) AS close_px
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2009-12-01'
      AND date <  '2026-01-01'
    GROUP BY date
),
rets AS
(
    SELECT date, 100 * (close_px / prev_close - 1) AS ret_pct
    FROM
    (
        SELECT date, close_px,
               lagInFrame(close_px, 1) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_close
        FROM px
    )
    WHERE date >= '2010-01-01' AND prev_close > 0
),
qs AS
(
    SELECT
        quantileExact(0.100)(ret_pct) AS q90,
        quantileExact(0.050)(ret_pct) AS q95,
        quantileExact(0.025)(ret_pct) AS q975,
        quantileExact(0.010)(ret_pct) AS q99,
        quantileExact(0.005)(ret_pct) AS q995,
        quantileExact(0.001)(ret_pct) AS q999
    FROM rets
),
tails AS
(
    SELECT
        any(q90)                        AS var90,
        any(q95)                        AS var95,
        any(q975)                       AS var975,
        any(q99)                        AS var99,
        any(q995)                       AS var995,
        any(q999)                       AS var999,
        avgIf(ret_pct, ret_pct <= q90)  AS es90,
        avgIf(ret_pct, ret_pct <= q95)  AS es95,
        avgIf(ret_pct, ret_pct <= q975) AS es975,
        avgIf(ret_pct, ret_pct <= q99)  AS es99,
        avgIf(ret_pct, ret_pct <= q995) AS es995,
        avgIf(ret_pct, ret_pct <= q999) AS es999
    FROM rets
    CROSS JOIN qs
    HAVING countIf(ret_pct <= q999) > 0
)
SELECT
    tupleElement(lvl, 1)                                  AS confidence,
    round(-1 * tupleElement(lvl, 2), 2)                   AS historical_var_pct,
    round(-1 * tupleElement(lvl, 3), 2)                   AS expected_shortfall_pct,
    round(tupleElement(lvl, 3) / tupleElement(lvl, 2), 2) AS es_to_var_ratio
FROM
(
    SELECT
        arrayJoin([
            ('90.0%', var90,  es90,  1),
            ('95.0%', var95,  es95,  2),
            ('97.5%', var975, es975, 3),
            ('99.0%', var99,  es99,  4),
            ('99.5%', var995, es995, 5),
            ('99.9%', var999, es999, 6)
        ]) AS lvl
    FROM tails
)
ORDER BY tupleElement(lvl, 4)
Run this yourself

À 99.0%, la VaR de cette série s’élève à 3.09% et l’expected shortfall à 4.43%, soit 1.44 fois le seuil. Dans une distribution normale, ce ratio serait proche de 1,15 au même niveau. Même à 99.9%, lorsque le seuil a déjà atteint 5.85%, la perte moyenne les jours de dépassement s’établit à 8.14%. Une limite fondée uniquement sur la VaR considère chaque dépassement comme un événement identique. La colonne du ratio montre à quel point cette hypothèse est inexacte.

La VaR à un jour et à 99 % a-t-elle le même sens pour une institution et pour un trader ?

Non. L’écart tient surtout à l’horizon. Un trader qui est flat overnight ne porte son risque que pendant quelques heures. Un seuil calculé sur une séance correspond donc à sa période de détention, même si la trajectoire intraday peut largement dépasser une mesure close-to-close. Une institution qui finance des passifs de longue durée détient ses positions pendant des années. Son exposition se matérialise sur plusieurs trimestres. Sa VaR à un jour et à 99 % sert alors surtout d’outil de capital et de suivi, plutôt que de description du risque effectivement porté. Pendant des années, les règles de fonds propres bancaires ont reposé sur une VaR à un jour et à 99 %. Le cadre de Bâle sur le risque de marché a ensuite remplacé cette mesure par un expected shortfall à 97,5 %.

Le passage standard d’un horizon à l’autre consiste à appliquer une règle de mise à l’échelle par la racine carrée du temps : il faut multiplier la mesure sur une séance par la racine carrée du nombre de séances de l’horizon. Cette opération suppose que les rendements sont indépendants et que le sigma reste constant. La colonne du sigma année par année ci-dessus montre déjà que cette hypothèse échoue sur son second volet.

RequêteMise à l’échelle par racine du temps et pertes mesurées sur plusieurs séances, niveau de 99 %
Le SQL exact derrière chaque chiffre
WITH
px AS
(
    SELECT date, max(toFloat64(close)) AS close_px
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2009-11-01'
      AND date <  '2026-01-01'
    GROUP BY date
),
multi AS
(
    SELECT
        date,
        100 * (close_px / p1  - 1) AS r1,
        100 * (close_px / p5  - 1) AS r5,
        100 * (close_px / p10 - 1) AS r10,
        100 * (close_px / p20 - 1) AS r20
    FROM
    (
        SELECT
            date,
            close_px,
            lagInFrame(close_px, 1)  OVER (ORDER BY date ROWS BETWEEN 20 PRECEDING AND CURRENT ROW) AS p1,
            lagInFrame(close_px, 5)  OVER (ORDER BY date ROWS BETWEEN 20 PRECEDING AND CURRENT ROW) AS p5,
            lagInFrame(close_px, 10) OVER (ORDER BY date ROWS BETWEEN 20 PRECEDING AND CURRENT ROW) AS p10,
            lagInFrame(close_px, 20) OVER (ORDER BY date ROWS BETWEEN 20 PRECEDING AND CURRENT ROW) AS p20
        FROM px
    )
    WHERE date >= '2010-01-01' AND p20 > 0
),
q AS
(
    SELECT
        quantileExact(0.01)(r1)  AS q1,
        quantileExact(0.01)(r5)  AS q5,
        quantileExact(0.01)(r10) AS q10,
        quantileExact(0.01)(r20) AS q20
    FROM multi
)
SELECT
    tupleElement(h, 1)                                             AS horizon,
    round(-1 * tupleElement(h, 3), 2)                              AS actual_var_pct,
    round(-1 * q1 * sqrt(tupleElement(h, 2)), 2)                   AS sqrt_scaled_var_pct,
    round(tupleElement(h, 3) / (q1 * sqrt(tupleElement(h, 2))), 2) AS actual_to_scaled_ratio
FROM
(
    SELECT
        q1,
        arrayJoin([
            ('1 session',   1.0,  q1,  1),
            ('5 sessions',  5.0,  q5,  2),
            ('10 sessions', 10.0, q10, 3),
            ('20 sessions', 20.0, q20, 4)
        ]) AS h
    FROM q
)
ORDER BY tupleElement(h, 4)
Run this yourself

La première ligne est un contrôle d’identité : à 1 session, la mesure mise à l’échelle est égale à la mesure observée, avec un ratio de 1. À 20 sessions, les deux mesures divergent. Et pas dans le sens généralement associé à cette approximation : la mise à l’échelle de la mesure sur une séance donne 13.8%, tandis que les rendements mesurés sur cet horizon affichent 10.7%, soit un ratio de 0.78. Sur cette fenêtre, la mesure mise à l’échelle est supérieure à la queue de distribution mesurée sur plusieurs séances. Deux phénomènes s’opposent ici. Une distribution à queue épaisse sur une seule séance s’amincit lorsque les rendements sont agrégés. Le quantile à 99 % ainsi agrégé augmente alors moins vite que la racine carrée de l’horizon. Le clustering de la volatilité produit l’effet inverse en concentrant des séances très agitées dans une même fenêtre. Sur cette série, le premier phénomène domine. Aucun des deux effets n’est garanti sur une autre fenêtre ou pour un autre actif. C’est précisément le point : le multiplicateur est une hypothèse, pas une mesure. C’est aussi sur ce clustering que s’appuie le volatility targeting lorsqu’il redimensionne les positions.

Une autre limite doit être énoncée clairement. Tout ce qui précède concerne la VaR d’un seul actif, calculée sur un fonds indiciel large. Un portefeuille de dix valeurs corrélées comporte un risque de concentration que la VaR de portefeuille prend en compte au moyen d’une estimation des corrélations. Or les corrélations évoluent le plus au moment même où l’estimation devient déterminante.

Notes méthodologiques et conventions
  • Les percentiles proviennent d’un quantile exact, et les tirages Monte Carlo d’une séquence uniforme initialisée par un hash et écrite dans le SQL. Chaque chiffre se recalcule donc à la même valeur.
  • Les rendements correspondent aux variations de cours close-to-close, sans réinvestissement des dividendes. C’est la convention habituelle pour une VaR sur une séance.
  • Le panneau consacré à l’horizon utilise des fenêtres chevauchantes : deux rendements consécutifs sur 20 séances partagent 19 jours. La queue de distribution repose donc sur beaucoup moins d’observations indépendantes que ne le laisse penser le nombre de lignes.

FAQ

Qu’est-ce qu’une VaR à un jour au niveau de confiance de 99 % ?

Il s’agit du niveau de perte dépassé par la pire séance sur 100, mesuré sur une seule séance. Sur la série ci-dessus, l’estimation historique est de 3.09%. Ce chiffre indique un seuil, sans rien dire de l’ampleur des pertes au-delà de ce seuil.

Quelle méthode de calcul de la VaR est la plus précise ?

Aucune des trois n’est précise dans l’absolu, car chacune répond à la question selon des hypothèses différentes. La VaR historique est fidèle à l’échantillon fourni, mais ne dit rien de ce que l’échantillon n’a pas couvert. La VaR paramétrique est peu coûteuse, mais elle sous-estime les queues de distribution des actions. La simulation de Monte Carlo n’est aussi bonne que la distribution qui lui est fournie.

Quelle est la différence entre la VaR et l’expected shortfall ?

La VaR est le seuil correspondant à un niveau de confiance donné. L’expected shortfall calcule la moyenne des pertes observées les jours où ce seuil est dépassé. Sur cette série, l’expected shortfall au niveau de 99 % représente 1.44 fois la VaR, contre environ 1,15 fois avec une distribution normale.

Peut-on convertir une VaR à un jour en VaR à 10 jours ?

La multiplication par la racine carrée de 10 est le raccourci standard. Elle suppose que les rendements sont indépendants et que la volatilité reste constante. Le panneau consacré à l’horizon mesure l’écart : sur 20 séances, le chiffre obtenu par mise à l’échelle était de 13.8%, contre 10.7% mesuré.


Chaque panneau ci-dessus contient la requête SQL qui a produit le résultat. Pour appliquer les trois mêmes calculs à un autre ticker ou à une autre fenêtre, formulez votre demande en anglais courant sur le terminal Strasmore.

#risk#value at risk#expected shortfall#quant#position sizing