Building Multi-Currency Discount Curves from Cross-Currency Swaps
Summary
The discussion explains how cross-currency swaps and local overnight-indexed swap markets can help construct discount curves for cash flows collateralized in another currency. In a two-currency setup, the response describes fitting a foreign-currency curve to cross-currency swap quotes, with uniqueness depending on the chosen curve parameterization and its interpolation settings. A parameter set may be uniquely determined under those choices, while changing interpolation can produce a different curve that also reprices the instruments.
For multiple collateral currencies, the answer describes a composite intrinsic curve built by selecting, at each overnight step, the highest rate among the relevant component curves. It characterizes this construction as ignoring the option for the cheapest collateral currency to change over time. The example and calibration outline show how FX rates and curves can support pricing and iterative fitting across instruments. The exchange does not provide a general mathematical uniqueness proof for multi-currency calibration, and the curve construction depends on market instruments, parameterization, and conventions.
Key ideas
- Cross-currency swap quotes can be used with local OIS markets to fit collateral-specific discount curves.
- Curve uniqueness depends on the chosen parameters and interpolation method.
- A multi-CSA intrinsic curve can be formed by selecting the highest component overnight rate at each step.
- The intrinsic construction omits the optionality of switching to the cheapest collateral currency over time.
- FX rates and several currency curves together support pricing and iterative calibration across instruments.
Tags
Full text
# How to build (unique?) multi-currency curve models using cross currency swaps
# How to build (unique?) multi-currency curve models using cross currency swaps
I'm relatively new to cross currency swaps (XCCY swaps) and reading through Pricing and Trading Interest Rate Derivatives - A Practical Guide to Swaps. What I can't get my head around is how these products are used to generate a multi currency curve model for proper discounting. To introduce the notation in the book, CCY:CCY2-CSA denotes the discount curve for currency CCY cashflows collateralised at CCY2 OIS. That means USD:EUR-CSA is the discount curve for USD cashflows collaterised at EUR OIS (assumed).
Two market case
Suppose I have USD OIS as my benchmark CSA curve and interested in finding the right USD:EUR-CSA curve. For the sake of simplicity we don't bother about mark-to-market (MTM) or non-MTM. What I observe in markets
- USD OIS swap market
- EUR OIS swap market
- EURUSD XCCY swap market
- FX market
From the USD OIS swap market I can derive a set of discount factors (leave aside how to achieve this). The same is true for the EUR swap market. However, given the very nature of the XCCY swap market I need to adjust the resulting EUR:EUR-CSA to obtain a EUR:USD-CSA. Simply put, I tweak the EUR:EUR-CSA to reprice the EURUSD XCCY swap market.
$n$ market case
Suppose the above is sorted out, I can repeat this procedure for other currencies. This assumes USD OIS to be my benchmark CSA across markets. That leads to e.g. GBP:USD-CSA and EUR:USD-CSA. Now, if we want to look at consistent Multi-CSA curves, e.g. EUR:USD+EUR+GBP-CSA, USD:USD+EUR+GBP-CSA etc. How is this achieved? Here it is even less clear if the above problem is step-wise executed, e.g. EUR:USD-CSA to EUR:USD+EUR-CSA to EUR:USD+EUR+GBP-CSA or in one go. Questions immediatly arising are
- Does it matter to it step-wise or in one go, i.e. does this lead to the same outcome? Can we prove this mathematically?
- Are we guaranteed to find a unique solution to this problem? Can we prove this mathematically?
Some insights from people more familiar in building these curves / study them from a theoretical point of view is highly appreciated!
EDIT
Additional question: If I'm not wrong the goal of the exercise (using XCCY swaps) is to build relevant discount curves and therefore long dated FX forward curves. However, from the book and on Bloomberg I see that the standard product are MTM XCCY swaps. Then I ask myself what proper FX forward to use for a very long dated XCCY swap, e.g. in a 30y XCCY swap we can use the FX forwards we observe from the market up to a tenor of e.g. 2ys. But which FX forward in the pricing is used to reset e.g. the 20y?
## Answer by Attack68 (score 4, accepted)
https://quant.stackexchange.com/a/80891
Two Market Case
- It depends upon how you parametrise your EUR:USD-CSA curve. If the degrees of freedom are appropriately placed dependent upon what values (tenors) are needed, then there will always be an unique solution.
The most similar proof I can offer in this regard is the Schoenberg-Whitney Theorem, which says the same thing about solving the coefficients of spline curves. Although designed for Spline Interpolation the principle for curve solving, I think, is mirrored (see De Boor Practical Guide to Splines for one Proof).
Note that two curves might have exactly the same parameters (which re-price the XCS instruments), but if they have different hyper-parameters (e.g. interpolation) then they do not reflect the same curve. But it is still true to say that a set of parameters (given the chosen hyper-parameters) will have a unique solution.
Two other posts that discuss overspecified, underspecified and exactly specified curves for reference are here.
https://quant.stackexchange.com/a/79465/29443
https://quant.stackexchange.com/a/80409/29443
n Market Case
A multi-csa curve is a composite construct of other curves. To construct a EUR:USD+EUR+GBP-CSA curve you need the following curves available:
- EUR:USD (created via EURUSD XCS)
- EUR:EUR (created with local OIS rates)
- EUR:GBP (could be created with EURGBP XCS but is typically implied from constant FX Forwards rates, once the GBP:USD curve is constructed from GBPUSD XCSs)
All of the above curves reduce to the two market case. Once these curves are available the multi-csa curve is determined from a successive loop. For any given overnight rate on the multi-csa curve that rate is chosen as the highest rate on any of the three above curves. For example suppose each of the curves just extends to cover four days and the Overnight rates on each curve (expressed in a consistent day count convention e.g. ACT365F) are:
- [1.0% 1.1% 1.2% 1.3%]
- [1.2% 1.2% 1.2% 1.2%]
- [1.3% 1.1% 0.9% 0.7%]
Then the multi-CSA curve has the following 4 rates. There is no clever way to calculate this other than to loop through and compare everything.
- [1.3% 1.2% 1.2% 1.3%]
This curve is called an intrinsic because valuing any derivative asset/liability with it ignores the optionality of any of the collateral currencies becoming the cheapest over time.
Two other links I can point to are:
https://rateslib.readthedocs.io/en/1.5.x/z_dependencychain.html
https://www.linkedin.com/pulse/pricing-trading-irds-difficult-examples-133-hamish-darbyshire/
The last one here shows you how to build MultiCurrencyCurves in rateslib and replicate results from the book. Apologies, if the syntax might have changed in different rateslib versions.
Solving Curves
All of the data for a 2 currency FX Forwards market is defined from one FX rate and 3 curves.
```
from rateslib import * # Python 3.12, rateslib 1.5.0
fxf = FXForwards(
fx_curves={
"eureur": Curve({dt(2024, 10, 15): 1.0, dt(2054, 10, 15): 0.4}),
"usdusd": Curve({dt(2024, 10, 15): 1.0, dt(2054, 10, 15): 0.3}),
"eurusd": Curve({dt(2024, 10, 15): 1.0, dt(2054, 10, 15): 0.42}),
},
fx_rates=FXRates({"eurusd": 1.10}, settlement=dt(2024, 10, 17))
)
```
This object contains all the information to price any RFR based derivative, including swaps, cross-currency swaps, FX-swaps, FX-forwards, via, discount factors, rates and forward FX rates.
```
>>> fxf.rate("eurusd", dt(2034, 10, 15))
<Dual: 1.230470, (fx_eurusd), [1.1]>
```
With fairly simple maths it will also derive other objects. Notice you don't have a USD:EUR-csa curve. But the values of such depend only on the above values:
```
>>> type(fxf.curve("usd", "usd"))
rateslib.curves.curves.Curve
>>> type(fxf.curve("usd", "eur"))
rateslib.curves.curves.ProxyCurve
```
The infomation for any multi-csa curve is also available from the above:
```
>>> type(fxf.curve("usd", ["eur", "usd"]))
rateslib.curves.curves.MultiCsaCurve
```
Since this object can price anything it can also be calibrated by those instruments.
The above FX rate on 15th Oct 2034 was 1.230, suppose the market price happened to be 1.250, your solver would iterate curves to get a closer value.
A much more realistic instrument is a MTM-XCS. These curves currently price a 10y XCS at -16bps
```
>>> xcs = XCS(dt(2024, 10, 15), "10y", spec="eurusd_xcs")
>>> xcs.rate(curves=[fxf.curve("eur", "eur"), fxf.curve("eur", "usd"), fxf.curve("usd", "usd"), fxf.curve("usd", "usd")], fx=fxf)
<Dual: -16.205052, (fx_eurusd), [0.0]>
```
If the market price is -20bps again you just tweak the curves in a solver until you derive the right values, across all your instruments.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.