Cross-Currency Swap Valuation Under Different Collateral Agreements
Summary
The document explains why market curve calibration and trade valuation can use different collateral assumptions. Its example is a EUR/USD cross-currency swap with basis: the collateral currency affects which discount curves apply to each currency’s cash flows, while quoted market instruments reflect the collateral agreement under which they trade.
The accepted explanation recommends calibrating market curves to the market collateral convention, then valuing a particular transaction using the curves appropriate to that transaction’s own collateral agreement. A newly traded swap can therefore have a nonzero value when revalued under a different CSA; the market trade price was set for its original convention. A second answer sketches a rates-library workflow that calibrates local and cross-currency curves to swap and basis quotes, then prices under alternative curve sets. The code is illustrative and specific to its library setup; the central point is that collateral conventions affect valuation and a market quote does not guarantee zero PV under another CSA.
Key ideas
- Collateral currency changes the discount curves used for cross-currency cash flows.
- Calibrate market curves using the collateral convention reflected in the market quotes.
- Value each transaction using curves that match its own collateral agreement.
- A swap traded at zero value under one CSA can have nonzero value when assessed under another CSA.
Tags
Full text
# XCCY collateralization: do I discount based on MY collateral agreement or the MARKETs?
# XCCY collateralization: do I discount based on MY collateral agreement or the MARKETs?
Say you have a EUR USD XCCY swap with a basis on the EUR leg.
The curves you use for discounting depend on the collateralization. Say the collateralization is in EUR. Then you'd discount the EUR cashflows with the EUR curve but you'd discount the USD cashflows with an adjusted USD curve that takes the basis into account.
However ... the basis on the xccy swap comes from the market, right? Basically the market tells me what the basis is.
But the market may have a different collateral agreement than I do: maybe the market collateralizes in USD, so the market would use the local USD curve for discounting and the modified EUR curve for the EUR cashflows.
So, what do I do?
- If I use the same curves as the market, I am not doing what makes sense vis-a-vis my collateral agreement. This seems wrong.
- If I don't use the same curves as the market, the XCCY swap will not have a PV of zero at inception. This seems wrong.
What seems right to me is to use the curves that correspond to my collateral agreement (so, (2.)), BUT also use the basis that actually makes this have zero value at inception. I don't know this basis, but I guess I could easily calibrate it?
## Answer by dm63 (score 5, accepted)
https://quant.stackexchange.com/a/84047
There’s no contradiction here. The valuation of a given xxxy swap will be slightly different in a USD CSA than a EUR CSA. You need to calibrate your curves using the market CSA (usd) but you need to value each transaction on its actual CSA.
And yes, if you take a xxcy swap which has just been executed in the market, and then you calculate its value on a EUR CSA , it will be non zero. Not a problem. You can’t actually do a trade in the market like that, because the counterparty will insist on a usd CSA or a price adjustment.
## Answer by Attack68 (score 2)
https://quant.stackexchange.com/a/84053
@dm63 has given you the answer. If you want a practical implementation of this for demonstration.
You will calibrate your market curves subject to USD collateral. Set up the local curves and the cross-currency curve:
```
from rateslib import * # Python 3.12, rateslib 2.1
# Uncalibrated discount factor curves:
usdusd = Curve({dt(2025, 9, 23): 1.0, dt(2026, 9, 29): 1.0}, id="usdusd")
eureur = Curve({dt(2025, 9, 23): 1.0, dt(2026, 9, 29): 1.0}, id="eureur")
eurusd = Curve({dt(2025, 9, 23): 1.0, dt(2026, 9, 29): 1.0}, id="eurusd")
```
Now lets create an FX forwards market using these curves a spot FX rate
```
fxr = FXRates({"eurusd": 1.17}, settlement=dt(2025, 9, 25))
fxf = FXForwards(
fx_curves={"eureur": eureur, "usdusd": usdusd, "eurusd": eurusd},
fx_rates=fxr,
)
```
Now you can calibrate these curves to market with market swap and basis prices.
```
solver = Solver(
curves=[eureur, usdusd, eurusd],
instruments=[
IRS(dt(2025, 9, 25), "1y", spec="eur_irs", curves="eureur"),
IRS(dt(2025, 9, 25), "1y", spec="usd_irs", curves="usdusd"),
XCS(dt(2025, 9, 25), "1y", spec="eurusd_xcs", curves=["eureur", "eurusd", "usdusd", "usdusd"]),
],
s=[2.0, 4.0, -19.0],
fx=fxf,
)
```
The USD curve (EUR collateral) is implied by the FX Forwards market.
```
usdeur = fxf.curve("usd", "eur", id="usdeur")
```
You can now price your own market instruments with any discounting regime you need:
```
my_xcs = XCS(
effective=dt(2025, 9, 25),
termination="1y",
spec="eurusd_xcs",
float_spread=-27,
notional=100e6
)
print(my_xcs.npv(curves=[eureur, eurusd, usdusd, usdusd], base="usd")
# 93794.98
print(my_xcs.npv(curves=[eureur, eureur, usdusd, usdeur], base="usd")
# 93642.22
```
Note that the `curves` here are expressed as `[leg1 forecasting, leg1 discounting, leg2 forecasting, leg2 discounting]`Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.