I am working on creating a fixed-fixed cross-currency swap pricer in Python for EUR-USD and GBP-USD pairs. Here's my current approach:
- Bootstrap a GBP SONIA curve.
- Bootstrap a SOFR curve.
- Obtain the GBPUSD xccy basis (GBP LIBOR vs USD LIBOR), e.g., y bp for 10 years.
- Compute an adjusted GBP SONIA curve by summing the GBP SONIA Curve and Xccy basis (e.g., the 10-year GBPUSD xccy basis). This is a flat shift in the SONIA curve by the xccy basis.
- Discount the USD fixed leg using the SOFR curve.
- Discount the GBP fixed leg using the adjusted SONIA curve.
- Convert all cashflows to GBP using GBPUSD spot.
- Solving for the fixed rate on one of the legs to get a 0 NPV structure
When comparing our pricing with Bloomberg, there is a 10-20 bp difference, which I assume is mostly driven by:
- Xccy basis referencing LIBOR, but we are applying the shift to the SONIA curve.
- LIBOR fallback used on one/both legs.
- No bootstrapping happening on xccy basis; just applying a pure shift of the SONIA curve.
- We have limited data (only SONIA swaps, SOFR swaps, GBPUSD spot and xccy basis).
- We aim to get as close as possible to Bloomberg's fixed-fixed xccy rates (within 5 bps).
- We are using Quantlib and prefer not to do our bootstrapping.
Any suggestions or insights on how to improve our pricing model while working with these constraints would be greatly appreciated!