Class FrtbSa

java.lang.Object
com.quantfinlib.risk.FrtbSa

public final class FrtbSa extends Object
FRTB standardised approach, sensitivities-based method (SBM), styled after BCBS d457 (January 2019) chapter MAR21. Not certified.

Plain idea. Each risk factor sensitivity is multiplied by a supervisory risk weight. Weighted sensitivities are netted inside a bucket with a correlation, the bucket results are netted across buckets with a second correlation, and the whole calculation is run three times with the correlations scaled up, left alone and scaled down. The capital is the worst of the three totals.

Formal statement (per MAR21). With weighted sensitivities WSk = RWk·sk:

  K_b = √max(0, Σ WS_k² + Σ_{k≠l} ρ_kl WS_k WS_l)
 S_b = max(min(Σ WS_k, K_b), −K_b)
 Δ   = √(Σ K_b² + Σ_{b≠c} γ_bc S_b S_c)
For delta and vega the first pass uses Sb = Σ WSk unclamped (MAR21.4(5)(a)); only if that radicand is negative is the calculation repeated with the clamped Sb above, the alternative specification of MAR21.4(5)(b). If that is still negative this class returns 0. Curvature (MAR21.5) uses Sb = Σ CVR of the selected scenario, the ψ rule (cross term dropped when both terms are negative) and floors the radicand at 0; the bucket takes the larger of the up and down scenario (MAR21.5(3)(a)), see curvature(List, List, double[][], Scenario). Curvature correlations are the squared delta correlations, and the high and low scenarios are applied to the squared value (MAR21.100, MAR21.101). Correlation scenarios (MAR21.6): high = min(1.25ρ, 1), low = max(2ρ − 1, 0.75ρ), applied to ρ and γ alike.

Worked example (independent recomputation, not a BCBS worked number: MAR21 prints no capital example; own tests FrtbSaTest and FrtbSaTableTest, the latter from the printed Table 1 and Table 2): two GIRR sensitivities of 100 and −50 at tenors 1y and 2y in one currency, RW 1.6% and 1.3%: WS = 1.6, −0.65; ρ = exp(−0.03·1/1) = 0.97045; K = √(2.56 + 0.4225 − 2·0.97045·1.04) = 0.98182.

Correlation matrices are supplied by the caller; the supervisory parameter helpers FrtbSa.Girr, FrtbSa.Fx, FrtbSa.Equity, FrtbSa.Commodity and FrtbSa.Csr build the ones this library can take from d457 MAR21, each value checked against the text and cited on the constant (published reference, BCBS d457 January 2019). FrtbSa.SecNonCtp covers CSR securitisation (non-CTP). Bucketing decisions (sector, rating, market cap) stay with the caller.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final record 
    One bucket: weighted sensitivities and the medium-scenario intra-bucket correlation matrix (diagonal ignored).
    static final record 
    Bucket-level result.
    static final class 
    Commodity parameters, buckets 1-11.
    static final class 
    Credit spread risk, non-securitisation (MAR21.51 to MAR21.57).
    static final class 
    Equity (spot) parameters, buckets 1-13.
    static final class 
    FX parameters.
    static final class 
    General interest rate risk parameters.
    static final record 
    One risk class: delta, vega and curvature inputs (any may be empty).
    static enum 
    Correlation scenarios of MAR21.
    static final class 
    CSR securitisation (non-CTP), buckets 1-25 (MAR21.62 to MAR21.71).
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
     
    static final int
     
    static final int
     
    static final int
     
    static final int
     
    static final int
    Vega liquidity horizons, days (MAR21.92 Table 13, verified; CSR securitisation also 120).
  • Method Summary

    Modifier and Type
    Method
    Description
    K_b and clamped S_b of one bucket (delta or vega).
    static double[][]
    constant(int n, double rho)
    Matrix with constant off-diagonal value.
    static double
    curvature(List<FrtbSa.Bucket> buckets, double[][] gamma, FrtbSa.Scenario sc)
    Curvature capital of one risk class under one scenario.
    static double
    curvature(List<FrtbSa.Bucket> up, List<FrtbSa.Bucket> down, double[][] gamma, FrtbSa.Scenario sc)
    Curvature capital with both shock directions (MAR21.5(3) and (4)).
    static double
    cvr(double vUp, double vBase, double vDown, double deltaPnlUp)
    Curvature risk charge CVR_k = −min(V⁺ − V₀ − RW·s, V⁻ − V₀ + RW·s), where V± are values after an up/down shift of size RW (the curvature risk weight) and s is the delta sensitivity per unit of that shift, so RW·s is the delta-implied P&L of the up shift.
    static double
    deltaVega(List<FrtbSa.Bucket> buckets, double[][] gamma, FrtbSa.Scenario sc)
    Delta or vega capital of one risk class under one scenario.
    static double
    deltaVega(List<FrtbSa.Bucket> buckets, double[][] gamma, FrtbSa.Scenario sc, Set<Integer> otherSector)
    Delta or vega capital where some buckets are "other sector" buckets (equity 11, CSR non-securitisation 16, securitisation non-CTP 25): their K_b is Σ|WS_k| with no correlation (MAR21.56(1), MAR21.69(1), MAR21.79(1)).
    static double
    otherSectorCurvatureK(double[] cvrUp, double[] cvrDown)
    Other-sector bucket curvature K_b = max(Σ max(CVR⁺, 0), Σ max(CVR⁻, 0)) (MAR21.56(2), MAR21.79(2)).
    static double
    otherSectorK(double[] weighted)
    Other-sector bucket delta or vega K_b = Σ|WS_k| (MAR21.56(1), MAR21.79(1)).
    static double
    SBM capital: the maximum of the three scenario totals.
    static double
    Total SBM charge of a set of risk classes under one scenario.
    static double
    vegaMaturityCorrelation(double tk, double tl)
    Vega option-maturity correlation exp(−1%·|T_k − T_l|/min(T_k, T_l)) (MAR21.93(1), verified).
    static double
    vegaRiskWeight(int liquidityHorizonDays)
    Vega risk weight min(RW_σ·√(LH/10), 1) with RW_σ = 0.55 (MAR21.92 footnote 24).

    Methods inherited from class Object

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

    • VEGA_LH_GIRR

      public static final int VEGA_LH_GIRR
      Vega liquidity horizons, days (MAR21.92 Table 13, verified; CSR securitisation also 120).
      See Also:
    • VEGA_LH_CSR

      public static final int VEGA_LH_CSR
      See Also:
    • VEGA_LH_EQUITY_LARGE_CAP

      public static final int VEGA_LH_EQUITY_LARGE_CAP
      See Also:
    • VEGA_LH_EQUITY_SMALL_CAP

      public static final int VEGA_LH_EQUITY_SMALL_CAP
      See Also:
    • VEGA_LH_COMMODITY

      public static final int VEGA_LH_COMMODITY
      See Also:
    • VEGA_LH_FX

      public static final int VEGA_LH_FX
      See Also:
  • Method Details

    • bucket

      public static FrtbSa.BucketResult bucket(FrtbSa.Bucket b, FrtbSa.Scenario sc)
      K_b and clamped S_b of one bucket (delta or vega).
    • deltaVega

      public static double deltaVega(List<FrtbSa.Bucket> buckets, double[][] gamma, FrtbSa.Scenario sc)
      Delta or vega capital of one risk class under one scenario.
      Parameters:
      gamma - medium-scenario inter-bucket correlation, nb x nb
    • curvature

      public static double curvature(List<FrtbSa.Bucket> buckets, double[][] gamma, FrtbSa.Scenario sc)
      Curvature capital of one risk class under one scenario. Each bucket's weighted entries are CVR_k (see cvr(double, double, double, double)); ρ and γ are the delta correlations, squared internally.
    • deltaVega

      public static double deltaVega(List<FrtbSa.Bucket> buckets, double[][] gamma, FrtbSa.Scenario sc, Set<Integer> otherSector)
      Delta or vega capital where some buckets are "other sector" buckets (equity 11, CSR non-securitisation 16, securitisation non-CTP 25): their K_b is Σ|WS_k| with no correlation (MAR21.56(1), MAR21.69(1), MAR21.79(1)). otherSector holds zero-based indices into buckets.
    • otherSectorK

      public static double otherSectorK(double[] weighted)
      Other-sector bucket delta or vega K_b = Σ|WS_k| (MAR21.56(1), MAR21.79(1)).
    • otherSectorCurvatureK

      public static double otherSectorCurvatureK(double[] cvrUp, double[] cvrDown)
      Other-sector bucket curvature K_b = max(Σ max(CVR⁺, 0), Σ max(CVR⁻, 0)) (MAR21.56(2), MAR21.79(2)).
    • curvature

      public static double curvature(List<FrtbSa.Bucket> up, List<FrtbSa.Bucket> down, double[][] gamma, FrtbSa.Scenario sc)
      Curvature capital with both shock directions (MAR21.5(3) and (4)). up.get(b) and down.get(b) hold CVR⁺_k and CVR⁻_k of bucket b with the delta ρ (squared internally). Each bucket takes the larger of K⁺ and K⁻; on a tie the up scenario is chosen if Σ CVR⁺ > Σ CVR⁻. S_b is Σ CVR of the selected scenario, and the selection is made afresh under each correlation scenario.
    • cvr

      public static double cvr(double vUp, double vBase, double vDown, double deltaPnlUp)
      Curvature risk charge CVR_k = −min(V⁺ − V₀ − RW·s, V⁻ − V₀ + RW·s), where V± are values after an up/down shift of size RW (the curvature risk weight) and s is the delta sensitivity per unit of that shift, so RW·s is the delta-implied P&L of the up shift.
    • total

      public static double total(List<FrtbSa.RiskClass> classes, FrtbSa.Scenario sc)
      Total SBM charge of a set of risk classes under one scenario.
    • sbmCapital

      public static double sbmCapital(List<FrtbSa.RiskClass> classes)
      SBM capital: the maximum of the three scenario totals.
    • vegaRiskWeight

      public static double vegaRiskWeight(int liquidityHorizonDays)
      Vega risk weight min(RW_σ·√(LH/10), 1) with RW_σ = 0.55 (MAR21.92 footnote 24). Verified: gives 100% for every class except equity large cap and indices, 0.55·√2 = 77.78% (MAR21.92 Table 13).
    • vegaMaturityCorrelation

      public static double vegaMaturityCorrelation(double tk, double tl)
      Vega option-maturity correlation exp(−1%·|T_k − T_l|/min(T_k, T_l)) (MAR21.93(1), verified).
    • constant

      public static double[][] constant(int n, double rho)
      Matrix with constant off-diagonal value.