Class VarBacktest

java.lang.Object
com.quantfinlib.risk.VarBacktest

public final class VarBacktest extends Object
VaR model validation: do the exceptions (losses beyond VaR) occur at the promised rate, and independently?
  • Kupiec POF — likelihood-ratio test that the exception frequency matches 1 - confidence (two-sided: both too many and too few exceptions reject). χ²(1).
  • Christoffersen independence — LR test that exceptions do not cluster (a model that is right on average but wrong in crises fails here). χ²(1).
  • Conditional coverage — the joint test (POF + independence), χ²(2), with the exact p-value e^{-LR/2}.
A p-value below the chosen significance (e.g. 0.05) rejects the model.

trafficLight(int, int) is the Basel supervisory zone test on the exception count (MAR32, MAR99).

acerbiSzekelyZ2(double[], double[], double[], double) backtests expected shortfall, which FRTB makes the capital measure and which an exception count alone cannot validate.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final record 
    Result of the Basel traffic-light test.
    static final record 
     
    static enum 
    Backtesting zones of the Basel internal models approach (MAR32.8).
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final double
    Acerbi-Szekely (2014) Z2 at the 0.01% level, T = 250, 97.5% ES.
    static final double
    Acerbi-Szekely (2014) Z2 at the 5% level, T = 250, 97.5% ES.
  • Method Summary

    Modifier and Type
    Method
    Description
    static double
    acerbiSzekelyZ2(double[] returns, double[] varForecasts, double[] esForecasts, double confidence)
    The Acerbi-Szekely (2014, "Backtesting expected shortfall", Risk, December) unconditional ES test statistic
    test(double[] returns, double[] varForecasts, double confidence)
    Backtests a VaR forecast series.
    test(double[] returns, double constantVar, double confidence)
    Backtests a constant VaR (positive loss fraction) against realized returns.
    trafficLight(int exceptions, int observations)
    Basel traffic light for 99 % VaR, the supervisory backtest of the bank-wide model (Basel Framework MAR32.8-32.9 and MAR99.17, Table 2).
    trafficLight(int exceptions, int observations, double coverage)
    Traffic light at another VaR coverage, with the same 95 % / 99.99 % zone boundaries (the Basel text fixes 99 %; other levels are an extension for internal desk monitoring).

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • Z2_THRESHOLD_5PCT

      public static final double Z2_THRESHOLD_5PCT
      Acerbi-Szekely (2014) Z2 at the 5% level, T = 250, 97.5% ES.
      See Also:
    • Z2_THRESHOLD_001PCT

      public static final double Z2_THRESHOLD_001PCT
      Acerbi-Szekely (2014) Z2 at the 0.01% level, T = 250, 97.5% ES.
      See Also:
  • Method Details

    • test

      public static VarBacktest.VarBacktestResult test(double[] returns, double constantVar, double confidence)
      Backtests a constant VaR (positive loss fraction) against realized returns.
    • test

      public static VarBacktest.VarBacktestResult test(double[] returns, double[] varForecasts, double confidence)
      Backtests a VaR forecast series.
      Parameters:
      returns - realized periodic returns
      varForecasts - VaR forecast for each period as a positive loss fraction, aligned with returns
      confidence - the VaR confidence level (e.g. 0.95, 0.99)
    • acerbiSzekelyZ2

      public static double acerbiSzekelyZ2(double[] returns, double[] varForecasts, double[] esForecasts, double confidence)
      The Acerbi-Szekely (2014, "Backtesting expected shortfall", Risk, December) unconditional ES test statistic
        Z2 = 1 − Σ_t L_t·1{L_t > VaR_t} / (T·(1−c)·ES_t)
      with losses L_t = −r_t. Under a correct ES forecast E[Z2] = 0; a negative value means realised tail losses exceed the forecast ES. The paper's simulations give thresholds that are nearly independent of the return distribution for T = 250 and c = 97.5%: Z2_THRESHOLD_5PCT = −0.70 and Z2_THRESHOLD_001PCT = −1.80 (the analogue of the Basel amber and red zones). For other settings the p-value must be simulated under the model.
      Parameters:
      returns - realised returns
      varForecasts - VaR forecasts, positive loss fractions
      esForecasts - ES forecasts at the same confidence, positive
      confidence - e.g. 0.975
    • trafficLight

      public static VarBacktest.TrafficLight trafficLight(int exceptions, int observations)
      Basel traffic light for 99 % VaR, the supervisory backtest of the bank-wide model (Basel Framework MAR32.8-32.9 and MAR99.17, Table 2).

      Plain idea. With a correct 99 % VaR the exception count in a year of 250 days is Binomial(250, 1 %), about 2.5 on average. A count you would reach or exceed with a correct model at most about 5 % of the time puts the model in the amber zone; about 0.01 % of the time, the red zone.

      Formal statement. With F the Binomial(n, 1 - coverage) CDF, the zone is GREEN if F(x) < 0.95, AMBER if 0.95 <= F(x) < 0.9999 and RED otherwise (MAR99.17: the amber zone begins where the cumulative probability equals or exceeds 95 %, the red zone where it equals or exceeds 99.99 %).

      Worked example. n = 250: F(4) = 89.22 % and F(5) = 95.88 %, so 0-4 exceptions are green and 5 amber; F(9) = 99.97 % and F(10) = 99.99 %, so 10 or more are red. Those are the boundaries and cumulative probabilities of MAR99 Table 2 (tested). Seven exceptions give AMBER with multiplier 1.83.

      Parameters:
      exceptions - exceptions observed, 0 ≤ exceptions ≤ observations
      observations - sample size, > 0 (250 for the regulatory test)
      Returns:
      zone, cumulative probability and, for 250 observations, the multiplier
    • trafficLight

      public static VarBacktest.TrafficLight trafficLight(int exceptions, int observations, double coverage)
      Traffic light at another VaR coverage, with the same 95 % / 99.99 % zone boundaries (the Basel text fixes 99 %; other levels are an extension for internal desk monitoring). The multiplier is set only for 250 observations at 99 % coverage.
      Parameters:
      exceptions - exceptions observed, 0 ≤ exceptions ≤ observations
      observations - sample size, > 0
      coverage - VaR confidence level in (0, 1), e.g. 0.99
      Returns:
      zone and cumulative probability