← quantChapter 11 · Counterparty credit risk, deep dive5 min read

BA-CVA Explained: The Basic Approach to CVA Capital

Understand the BA-CVA capital formula, reduced vs full hedge treatment, and how it differs from SA-CVA. Follow a worked example and run the calculator.

BA-CVA (the Basic Approach to Credit Valuation Adjustment risk) calculates CVA capital from counterparty exposures, maturities, supervisory risk weights and correlations. The reduced version does not recognise hedges; the full version recognises eligible credit-spread hedges. SA-CVA instead uses CVA sensitivities to market risk factors.

This page walks through the reduced formula, compares the three approaches on one example book, and shows what changes when a counterparty is downgraded. Open the BA-CVA calculator to compare reduced, full and SA-CVA results on two netting sets with an adjustable CDS hedge.

Reduced BA-CVA, full BA-CVA and SA-CVA compared

ApproachMain inputsHedge treatment
Reduced BA-CVAEAD, effective maturity, counterparty risk weightsNo hedge recognition
Full BA-CVAReduced inputs plus eligible credit-spread hedgesPrescribed hedge recognition, with a reduced-charge component
SA-CVACVA sensitivities, risk weights and correlationsEligible hedges reflected in the sensitivity framework

The Basel CVA framework, MAR50 defines these approaches. The parameter tables and exposure proxy used below are teaching inputs; the numerical comparison is specific to this book.

The whole story

BA-CVA reduced needs three lookups per counterparty — a risk weight by rating and sector, a maturity, an EAD proxy — combined with a supervisory correlation, no Monte Carlo or adjoint sweep anywhere. Real risk weights show a two-stage design: FINANCIAL/BBB comes to 5.75%, FINANCIAL/BB to 12.00%, more than double, because BB's sector base is already the higher non-investment-grade tier before any per-rating notch is applied. Timed for real: one million K_reduced calls in 0.209 seconds, 209 nanoseconds each — every other regulatory number in Chapters 10 and 11 needed milliseconds to seconds on the adjoint tape. On the identical book, the three PRA methods give wildly different numbers: Alternative (BA-CVA reduced) $1.358m, Basic (BA-CVA full) $1.093m, Standardised (SA-CVA) $0.054m — 20x to 25x lower, the reward for building the sensitivity infrastructure the rest of this chapter walked through. Downgrading counterparty A one notch, BBB to BB, more than doubles K_reduced to $2.829m, with no re-simulation needed at all.

Did you know?

BaCvaParameters.riskWeight is a two-stage lookup, and reading only the per-rating switch can mislead: BB's own multiplier is base * 1.0 — no adjustment at all — the same as A's. But the base each one multiplies is different: A and BBB are investment-grade, so they share the lower sector base; BB isn't, so it starts from the higher non-investment-grade base before any per-rating notch applies. Real numbers for FINANCIAL: AAA comes to 3.50%, BBB to 5.75%, BB to 12.00% — more than double BBB, entirely from which base tier it starts in, not from a bigger multiplier.

BA-CVA reduced: no simulation, no adjoint sweep

double scva = riskWeight * exposure.effectiveMaturityYears()
    * exposure.exposureAtDefault() * discount / parameters.alpha();
scvaByCounterparty.merge(exposure.counterparty().id(), scva, Double::sum);
SCVA_c    = RW_c * M_c * EAD_c * DF_c / alpha
K_reduced = sqrt( (rho * sum_c SCVA_c)^2 + (1 - rho^2) * sum_c SCVA_c^2 )

Every input is a table lookup or a maturity-based discount — RW_c from the rating/sector table above, DF_c from (1-e^{-0.05M})/(0.05M), and EAD_c (in this demo) from alpha times the expected positive exposure 11.1's own sweep already produced. Nothing here revalues a trade twice, shocks a risk factor, or records a tape.

Did you know?

Timed it directly rather than assumed it from the formula's shape: one million calls to BaCva.charge(...).reduced() on this page's two- counterparty book, 0.209 s total, 209 nanoseconds per call. Every other regulatory number in Chapter 10 and the rest of Chapter 11 needed an adjoint sweep or a Monte-Carlo replay, measured in milliseconds to tens of seconds. This is the one calculator in the whole chapter that doesn't — which is the entire regulatory point of calling it "basic."

Three methods, one book

PraCvaMethods runs the identical CvaCapital through all three PRA standardised routes. Real numbers, same book as 11.1 and 11.2:

methodcharge
Alternative (BA-CVA reduced, no hedge)$1.358m
Basic (BA-CVA full, hedged)$1.093m
Standardised (SA-CVA, 10.3's sensitivity charge)$0.054m

SA-CVA lands 20×–25× lower than either BA-CVA variant on this exact book — the payoff for the sensitivity infrastructure 10.3, 11.1 and 11.2 walked through. The size of that difference depends on the portfolio, hedges and parameter choices; it is not a general BA-CVA-to-SA-CVA ratio. PraCvaMethods.bindingCharge() itself reports max(all three) — its own doc comment calls it "the method a bank on all three would report" — so the incentive to build SA-CVA is eligibility to use it on its own, not blending a small SA-CVA number in with two bigger BA-CVA ones.

Try it yourself

EAD_c doesn't depend on the counterparty's rating at all — only the risk-weight lookup does. Downgrade counterparty A from BBB to BB (one notch) and recompute, keeping every other input, including the Monte-Carlo-derived EAD, exactly as it was. Real number: K_reduced rises from $1.3575m to $2.8291m — more than double, entirely from the risk-weight table's own two-stage jump (5.75% → 12.00%), with no re-simulation of anything. The same downgrade mattering under SA-CVA would need a fresh sensitivity vector; here it's one table lookup away.

▶️ Run it

The same three methods, live, on the same reduced single-counterparty book 11.2's cell used — right here. BaCva and SaCva are the real, unmodified plain-double classes; no adjoint sweep is needed for either charge itself, only for the EPE proxy and the SA-CVA sensitivity vector feeding them:

Java · compile and run in this browser

Or run the real thing:

mvn -o -q install
mvn -o -q -pl nablatensor-examples exec:java \
  -Dexec.mainClass=com.nablatensor.examples.CvaShowcase

[6/8] and [7/8] of the same run print all three methods side by side — no separate command for BA-CVA alone.

⚠️ What this doesn't do

This demo's EAD_c comes from the same Monte-Carlo ExposureSimulation sweep every other page in this chapter has used — alpha × expected positive exposure. That's convenient for a demo that already has the sweep sitting there, but it isn't the point of BA-CVA: docs-reg/cva.md is explicit that a real small bank's EAD comes from SA-CCR, a closed-form notional-and-add-on calculation, not a Monte-Carlo simulation — the whole regulatory idea is that a bank eligible for BA-CVA never needs to build an exposure simulator at all. BaCvaParameters.standard()'s rho = 0.5, beta = 0.25, alpha = 1.4 and the risk-weight table remain explicitly indicative, same standing caveat as every parameter table since Chapter 10.

What's next

→ Deeper: BaCvaParameters.java has the full risk-weight table by every rating and sector this demo supports. → Chapter 11 (Counterparty credit risk, deep dive) is complete. Next: What a "generated bytecode kernel" actually looks like, opening Chapter 12 — Under the hood.


Questions or corrections? open an issue