Skip to content
All library documents

Constructing and Plotting Cross-Currency CSA Discount Curves

Article Quant Q&A · Author: BankWorkerBMA

Summary

The document explains how to obtain discount factors for cash flows in one currency collateralized in another. It gives a relationship linking the cross-currency collateral discount curve to FX spot and forward rates and the discount curve for the collateral currency, under an assumption that FX forwards do not depend on collateralization. The original question asks how to build and plot such a curve in QuantLib.

The detailed answer demonstrates a related workflow in rateslib: define local-currency overnight curves and a cross-currency curve, associate them with FX rates, then calibrate them to interest-rate swaps and cross-currency swaps. The resulting framework can return local, foreign-collateral, and multi-collateral curves, calculate discount factors or rates, and plot comparisons. A separate answer points to a QuantLib example but does not reproduce its implementation. The worked setup is illustrative and uses simplified curve instruments; results depend on market conventions, collateral assumptions, calibration instruments, and the validity of the FX-forward assumption.

Key ideas

  • Cross-currency collateral discount factors can be related to FX forwards and discounting in the collateral currency.
  • The stated relationship assumes FX forwards are independent of the collateralization arrangement.
  • The example calibrates local and cross-currency curves using interest-rate swaps and cross-currency swaps.
  • A curve framework can produce discount factors and rates for local, foreign-collateral, and multi-collateral cases.
  • The detailed implementation uses rateslib, while the QuantLib answer only directs readers to a separate example.

Tags

Full text
# Plotting a CSA curve in QuantLib


# Plotting a CSA curve in QuantLib












#### IRS under a CSA

Let's consider an example of Interest Rate Swap under a CSA. To calculate discount factors that can be used to discount cashflows in one currency, $C_{1}$, collateralized in another currency, $C_{2}$, all we need are the FX spot and forward rates from $C_{1}$ to $C_{2}$ and the discount factors in $C_{2}$. Let

$FX_{C1\rightarrow C2}^{FWD}(T)$ = $FX\: forward\: rate\: to\: convert\: from$ $C_{1}$ $to$ $C_{1}$ $at\: time\: T$

$FX_{C1\rightarrow C2}^{SPOT}$ = $FX_{C1\rightarrow C2}^{FWD}(0)$ = $FX\: spot\: rate\: to\: convert\: from$ $C_{1}$ $to$ $C_{1}$

$DF_{C2}(T)$ = $discount\: factor\:at\: time\: T\: for\: currency$ $C_{2}$,

Then under the assumption that FX forwards are independent of collateralization we conclude that

$\Large\frac{FX_{C1\rightarrow\:C2}^{CSA}(T)}{DF_{C2}(T)}$ $\Large=$ $\Large\frac{FX_{C1\rightarrow\:C2}^{FWD}(T)}{FX_{C1\rightarrow\:C2}^{FWD}(0)}$

#### Question

Is it possible to find such functions in QuantLib that will directly find the discount factors of the CSA curve (And we know how to build an ZeroRate Curve here)? Please guide me in the right direction.

Thank you!

## Answer by Attack68 (score 3)

https://quant.stackexchange.com/a/78347

You can also validate the `QuantLib` implementation with `rateslib`.

To define local currency EUR and USD you need to specify two RFR curves:

```
from rateslib import *

eureur = Curve({dt(2024, 2, 16): 1.0, dt(2024, 8, 16): 1.0, dt(2025, 2, 19): 1.0}, calendar="tgt", convention="act360", interpolation="log_linear")
usdusd = Curve({dt(2024, 2, 16): 1.0, dt(2024, 8, 16): 1.0, dt(2025, 2, 19): 1.0}, calendar="nyc", convention="act360", interpolation="log_linear")
```

To define cross-currency or FXswap markets you need a CSA curve for EUR cashflows collateralised with USD.

```
eurusd = Curve({dt(2024, 2, 16): 1.0, dt(2024, 8, 16): 1.0, dt(2025, 2, 19): 1.0}, convention="act360", interpolation="log_linear")
```

The discount factor points are placed at the 6m and 1Y points on all curves.

Now we will associate these objects together in an `FXForwards` framework with prevailing `FXRates`

```
fxf = FXForwards(
    fx_rates=FXRates({"eurusd": 1.080}, settlement=dt(2024, 2, 20)),
    fx_curves={"usdusd": usdusd, "eureur": eureur, "eurusd": eurusd}
)
```

Now solve and update these Curves according to market instrument rates as of 16th Feb 2024, aligning with 6m and 1Y instruments for simplicity.

```
solver = Solver(
    curves=[eureur, usdusd, eurusd],
    instruments=[
        IRS(dt(2024, 2, 16), "6m", spec="usd_irs", curves=usdusd),
        IRS(dt(2024, 2, 16), "1y", spec="usd_irs", curves=usdusd),
        IRS(dt(2024, 2, 16), "6m", spec="eur_irs", curves=eureur),
        IRS(dt(2024, 2, 16), "1y", spec="eur_irs", curves=eureur),
        XCS(dt(2024, 2, 16), "6m", spec="eurusd_xcs", curves=[eureur, eurusd, usdusd, usdusd]),
        XCS(dt(2024, 2, 16), "1y", spec="eurusd_xcs", curves=[eureur, eurusd, usdusd, usdusd]),
    ],
    s=[5.205, 5.00, 3.72, 3.40, -6.1, -11.9],
    instrument_labels=["6mUS", "1yUS", "6mEU", "1yEU", "6mUS/EU", "1yUS/EU"],
    fx=fxf,
)
SUCCESS: `func_tol` reached after 3 iterations (levenberg_marquardt) , `f_val`: 4.884e-12, `time`: 0.0580s
```

The updated `FXForwards` object can now return Curves for any of the following:



- EUR cashflows with USD collateral: `fxf.curve("eur", "usd") # type: Curve` EUR collateral: `fxf.curve("eur", "eur") # type: Curve` USD+EUR collateral: `fxf.curve("eur", ["usd", "eur"]) # type: MultiCsaCurve`

`ProxyCurves` take discount factors from the relevant underlying `Curves` and perform cross multiplications (similar to your formulae). They are objects capable of calculating discount factors or rates, etc.

`MultiCsaCurves` combine collateral curves to calculate intrinsic multi-collateral curves (without optionality). Again they are curve objects capable of producing discount factors and rates.

They can also `plot`.

```
fxf.curve("usd", "usd").plot("1b", 
    comparators=[fxf.curve("usd", "eur"), fxf.curve("usd", ["usd", "eur"])],
    labels=["local", "eur", "local+eur"],
)
```

## Answer by Denys Usynin (score 1)

https://quant.stackexchange.com/a/78326

Yes this is supported in QuantLib - see the answer in https://quant.stackexchange.com/a/78325/70402

The example linked there is modeling the use case you describe.

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.