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

Hedging CVA

A CVA desk buys CDS protection to lower its capital charge. Does a same-sector proxy, not the exact legal entity, still help? Real numbers say no — below a correlation around 0.85, BA-CVA's own hedge-misalignment penalty makes the charge worse than not hedging at all, and even the regulation's own 'legally related name' example already crosses that line.

A CVA desk doesn't just measure counterparty risk — it hedges it, usually by buying CDS protection. Does protection on a similar name, not the exact legal entity you're exposed to, actually lower the capital charge? BA-CVA's own formula has a real answer, and it isn't always yes.

The whole story

BA-CVA reduced sums each counterparty's supervisory-weighted exposure, EAD proxied from the exact expected positive exposure 11.1's own sweep already produced. The full version credits a single-name CDS hedge by its correlation r_hc to the hedged name, but adds a hedge-misalignment penalty that grows as (1-r_hc squared) times the hedge's own magnitude squared. Real numbers: at r_hc=1.0 the hedge saves $0.2643m; at r_hc=0.90, only $0.0543m; at r_hc=0.80 — the regulation's own "legally related name" example — the charge is already $0.1176m worse than no hedge at all, and it keeps getting worse down to r_hc=0. An index CDS hedge of the same notional does even worse, $0.5173m worse than no hedge, because it enters only the aggregate systematic term with no floor at zero and can overshoot past the book's own systematic exposure.

Did you know?

EAD_c in the reduced formula below isn't a separate calculator — it's alpha * expectedPositiveExposure(), read straight off the exact ExposureSimulation sweep 11.1 already ran for this same netting set. One Monte-Carlo run gives the CVA number, its whole risk vector, and the EAD proxy this page's capital charge needs — nothing here re-prices anything.

BA-CVA reduced: no hedge recognition

double scva = riskWeight * exposure.effectiveMaturityYears()
    * exposure.exposureAtDefault() * discount / parameters.alpha();
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 )

Real numbers, two netting sets (NS-CPTY-A, NS-CPTY-B), supervisory rho = 0.5, alpha = 1.4: K_reduced = $1.3575m. Every hedge below is measured against this one number — "benefit" means the hedged charge came in under it.

BA-CVA full: hedge recognition, and a penalty

A single-name CDS gets credit for how well it actually matches the hedged counterparty — r_hc, 1.0 for the same legal entity, ~0.8 for a legally related name, ~0.5 for a same-sector proxy, per CvaHedge's own doc comment:

singleNameHedgeByCounterparty.merge(hedge.referenceId(),
    hedge.correlation() * magnitude, Double::sum);
hedgeMisalignmentByCounterparty.merge(hedge.referenceId(),
    (1.0 - hedge.correlation() * hedge.correlation()) * magnitude * magnitude, Double::sum);

The credit (SNH_c) grows linearly in r_hc. The penalty (HMA_c) grows as (1 - r_hc²) — quadratically worse as correlation falls — and it's added straight into the sum under the square root, never netted against anything. Swept the same $8m, 7-year hedge on counterparty A across r_hc, real numbers each time:

r_hchedged K_fullbenefit vs. no hedge
1.00 (same entity)$1.0932m+$0.2643m
0.90$1.3033m+$0.0543m
0.80 ("legally related")$1.4751m-$0.1176m
0.50 ("same-sector proxy")$1.8796m-$0.5220m
0.00 (uncorrelated)$2.3830m-$1.0254m
Did you know?

Breakeven sits between r_hc = 0.90 and r_hc = 0.80 for this book — and CvaHedge's own doc comment names ~0.8 as the typical correlation for a "legally related name," the very next tier down from a perfect match. That reference case is already on the wrong side of breakeven: buying that hedge produces a higher capital charge than buying no hedge at all. The misalignment penalty isn't a rounding error at the margins — it dominates for exactly the kind of proxy hedge a desk reaches for when the exact name isn't tradeable.

Try it yourself

Swap the single-name hedge for an index CDS of the same notional, maturity and risk weight — CvaHedge.index(8_000_000.0, 7.0, 0.05) instead of CvaHedge.singleName(...). An index's correlation is fixed at 1.0 by construction, so it looks safe from the misalignment penalty by definition (HMA needs 1 - r_hc², which is 0 here). Real number from doing exactly that: K_full = $1.8749m, a -$0.5173m benefit — worse even than the r_hc = 0.50 single-name proxy above.

The reason is structural, not a fluke: an index hedge only ever enters the systematic term, rho·Σ(SCVA_c - SNH_c) - IH, subtracted once for the whole book, never each counterparty's own idiosyncratic sum-of-squares term individually. That systematic term gets squared with no floor at zero — an index hedge sized past the book's own systematic exposure overshoots to the other side of zero and comes back out larger in magnitude than if it had done nothing. Single-name misalignment and index over-hedging are two different ways the same "full" formula can turn a hedge into a liability; no source edit needed to see either one, CvaHedge.index(...) and Cva.hedge(...) are both public.

▶️ Run it

The same hedge sweep, live, scoped to counterparty A alone (the real page's $1.3575m K_reduced comes from a two-counterparty book this cell doesn't build, so the breakeven point shifts, but the shape — benefit at r_hc=1.0, a misalignment penalty that dominates as correlation falls — holds) — right here. BaCva/BaCvaParameters/CvaHedge run completely unmodified, called once the exposure-at-default proxy exists:

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

CvaShowcase's own hedgeOnA() uses r_hc = 1.0, the best case on the table above — its printed "hedge benefit" is real, but it's the ceiling, not the typical case. Change hedgeOnA()'s last argument to see the rest of the table for real.

⚠️ What this doesn't do

BaCvaParameters.standard()'s rho = 0.5, beta = 0.25 and alpha = 1.4 are explicitly indicative (MAR50.5's table shape, transcribed for a runnable demo) — same standing caveat as every parameter table this Learn section has used since Chapter 10. This page also only covers BA-CVA's hedge recognition; SA-CVA (10.3) has no comparable single-instrument hedge-benefit calculation at all — hedges there just enter as more sensitivities in the same aggregation. And the book here is small on purpose: one hedge, one counterparty pair — a real desk nets dozens of hedges against dozens of counterparties through the identical formula, just with more terms in each sum.

What's next

→ Deeper: BaCva.java has the full formula and its MAR50.6/CRR3 Art. 384 citations in one file. → Next: BA-CVA: the basic approach, for the banks too small for SA-CVA — the one regulatory calculator in this whole chapter that needs no adjoint sweep at all.


Questions or corrections? open an issue