# Cross currency swap valuation in QuantLib

Does QuantLib support valuation of Cross currency swaps ? Eg. SOFR / SONIA cross currency swap.

• With resetting notional? Feb 1 at 18:55
• Yes Dimitri , with resetting Notional. Feb 2 at 3:29
• Have you tried rkapl123.github.io/QLAnnotatedSource/d0/df1/… ? Feb 2 at 4:09
• Unfortunately not possible with quantlib functions directly. You can do some workaround...
– EAK
Mar 1 at 15:44

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],
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)


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.