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
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_hc | hedged K_full | benefit 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 |
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:
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.