Building and Valuing Cross-Currency Swaps with Curves and FX Forwards
Summary
The discussion outlines a framework for valuing a cross-currency swap using currency discount curves, FX rates and forwards, calibrated market instruments, and the swap’s cash flows. The example sets up sterling and dollar curves plus a cross-currency curve, calibrates them to interest-rate and cross-currency swap quotes, then constructs a historical mark-to-market swap with notionals, spreads, and fixing data. It shows that valuation can report present value by currency and in a chosen base currency, with delta risk and cash-flow inspection also available.
The example uses rateslib and a specific SOFR/SONIA market setup; its inputs and reported valuations are illustrative rather than general results. A separate reply states that QuantLib lacks a dedicated cross-currency swap instrument at the time described, while its cash flows can still be constructed and valued. Library support may change, and practical implementation depends on conventions, collateral, fixings, and market calibration.
Key ideas
- Cross-currency swap valuation requires interest-rate curves, FX rates and forwards, and instrument cash flows.
- Calibrate the curves to market instruments before valuing a trade.
- Historical mark-to-market swaps require relevant FX and floating-rate fixing data.
- Valuation and risk can be reported by currency or translated into a selected base currency.
- QuantLib may require manual cash-flow construction when no dedicated cross-currency instrument is available.
Tags
Full text
# Cross currency swap valuation in QuantLib
# Cross currency swap valuation in QuantLib
Does QuantLib support valuation of Cross currency swaps ? Eg. SOFR / SONIA cross currency swap.
## Answer by Attack68 (score 2)
https://quant.stackexchange.com/a/76825
I trade IRSs and XCSs so this answer is based on my own processes and requirements, as such I have written `rateslib` in Python, which does not have any of the stochastic processes of `quantlib`, but is centred about the delta and gamma metrics of linear multi-currency rate derivatives.
In order to establish a pricing and risk framework for multi-currency derivatives we need Curves, FXRates, Instruments and a trade or portfolio which to value.
Create the Curves first. 3 lines for the USD, GBP and GBPUSD cross currency discounting curve. Their discount factors will be calibrated shortly.
```
from rateslib import *
gbp = Curve({dt(2023, 8, 2): 1.0, dt(2024, 8, 2): 1.0}, id="sonia", calendar="ldn")
usd = Curve({dt(2023, 8, 2): 1.0, dt(2024, 8, 2): 1.0}, id="sofr", calendar="nyc")
gbpusd = Curve(
nodes={dt(2023, 8, 2): 1.0, dt(2024, 2, 2): 1.0, dt(2024, 8, 2): 1.0},
id="gbpusd",
)
```
Now we will create the FXRates and associate it with Curves to define a collateral consistent FXForwards space.
```
fxr = FXRates({"gbpusd": 1.25}, settlement=dt(2023, 8, 4))
fxf = FXForwards(
fx_rates=fxr,
fx_curves={
"usdusd": usd,
"gbpgbp": gbp,
"gbpusd": gbpusd,
}
)
```
Now we will solver everything relative to market data and calibrating Instruments
```
solver = Solver(
curves=[gbp, usd, gbpusd],
instruments=[
IRS(dt(2023, 8, 2), "1y", spec="gbp_irs", curves="sonia"),
IRS(dt(2023, 8, 2), "1y", spec="usd_irs", curves="sofr"),
XCS(dt(2023, 8, 2), "6m", spec="gbpusd_xcs", curves=["sonia", "gbpusd", "sofr", "sofr"]),
XCS(dt(2023, 8, 2), "1y", spec="gbpusd_xcs", curves=["sonia", "gbpusd", "sofr", "sofr"]),
],
s=[4.75, 5.35, -6, -14],
fx=fxf,
instrument_labels=["1y gbp", "1y usd", "6m gbpusd", "1y gbpusd"],
id="solver",
)
SUCCESS: `func_tol` reached after 3 iterations (levenberg_marquardt)
```
Notice these instruments have their parameters pre-configured by a market specification (spec) input.
With this Solver and set of calibrated Curves you can now do quite a lot of things. SOme of those involve constructing an existing cross currency swap and then pricing and risking it.
Here I will create a historical MTM-XCS and attached fixings to it which have valid fixing data upto the last RFR for reference value date 1st Aug 2023.
```
my_xcs=XCS(
dt(2023, 5, 16), "1Y", spec="gbpusd_xcs",
fx_fixings=[1.25],
float_spread=-2.5,
notional=100e6, #GBP
curves=["sonia", "gbpusd", "sofr", "sofr"],
fixings=defaults.fixings.sonia,
leg2_fixings=defaults.fixings.sofr
)
```
We can value and risk this swap:
```
my_xcs.npv(solver=solver, local=True)
{"usd": 126,378,590.04,
"gbp": -101,071,269.19}
my_xcs.npv(solver=solver, base="gbp")
35,487.48
my_xcs.delta(solver=solver)
```
Can also see the cashflows including all the MTM exchanges:
```
my_xcs.cashflows(solver=solver)
```
## Answer by Luigi Ballabio (score 0)
https://quant.stackexchange.com/a/76823
At this time there's not a cross-currency instrument as such (it might take a while) but it's possible to build its cashflows and calculate their value. There's a write-up available at https://www.implementingquantlib.com/2023/09/cross-currency-swaps.html.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.