FXSwap#

class rateslib.instruments.FXSwap(*args, fx_fixings=NoInput.blank, points=NoInput.blank, split_notional=NoInput.blank, **kwargs)#

Bases: XCS

Create an FX swap simulated via a Fixed-Fixed XCS.

Parameters:
  • args (dict) – Required positional args to XCS.

  • fx_fixings (float, FXForwards or None) – The initial FX fixing where leg 1 is considered the domestic currency. For example for an ESTR/SOFR XCS in 100mm EUR notional a value of 1.10 for fx0 implies the notional on leg 2 is 110m USD. If None determines this dynamically.

  • points (float, optional) – The pricing parameter for the FX Swap, which will determine the implicit fixed rate on leg2.

  • split_notional (float, optional) – The accrued notional at termination of the domestic leg accounting for interest payable at domestic interest rates.

  • kwargs (dict) – Required keyword arguments to XCS.

Notes

Warning

leg2_notional is determined by the fx_fixings either initialised or at price time and the value of notional. The argument value of leg2_notional does not impact calculations.

FXSwaps are technically complicated instruments. To define a fully priced Instrument they require at least two pricing parameters; fx_fixings and points. If a split_notional is also given at initialisation it will be assumed to be a split notional FXSwap. If not, then it will not be assumed to be.

If fx_fixings is given then the market pricing parameter points can be calculated. This is an unusual partially priced parametrisation, however, and a warning will be emitted. As before, if split_notional is given, or not, at initialisation the FXSwap will be assumed to be split notional or not.

If the FXSwap is not initialised with any parameters this defines an unpriced Instrument and it will be assumed to be split notional, inline with interbank market standards. The mid-market rate of an unpriced FXSwap is the same regardless of whether it is split notional or not, albeit split notional FXSwaps result in smaller FX rate sensitivity.

Other combinations of arguments, just providing points or split_notional or both of those will raise an error. An FXSwap cannot be parametrised by these in isolation. This is summarised in the below table.

Resultant initialisation dependent upon given pricing parameters.#

fx_fixings

points

split_notional

Result

X

X

X

A fully priced instrument defined with split notionals.

X

X

A fully priced instruments without split notionals.

An unpriced instrument with assumed split notionals.

X

X

A partially priced instrument with split notionals. Warns about unconventionality.

X

A partially priced instrument without split notionals. Warns about unconventionality.

X

X

Raises ValueError. Not allowable partially priced instrument.

X

Raises ValueError. Not allowable partially priced instrument.

X

Raises ValueError. Not allowable partially priced instrument.

Examples

To value the FXSwap we create Curves and FXForwards objects.

In [1]: usd = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.95}, id="usd")

In [2]: eur = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.97}, id="eur")

In [3]: eurusd = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.971}, id="eurusd")

In [4]: fxr = FXRates({"eurusd": 1.10}, settlement=dt(2022, 1, 3))

In [5]: fxf = FXForwards(
   ...:     fx_rates=fxr,
   ...:     fx_curves={"usdusd": usd, "eureur": eur, "eurusd": eurusd},
   ...: )
   ...: 

Then we define the FXSwap. This in an unpriced instrument.

In [6]: fxs = FXSwap(
   ...:     effective=dt(2022, 1, 18),
   ...:     termination=dt(2022, 4, 19),
   ...:     calendar="nyc",
   ...:     currency="usd",
   ...:     notional=1000000,
   ...:     leg2_currency="eur",
   ...:     curves=["usd", "usd", "eur", "eurusd"],
   ...: )
   ...: 

Now demonstrate the npv() and rate() methods:

In [7]: fxs.npv(curves=[None, usd, None, eurusd], fx=fxf)
Out[7]: <Dual: -0.000000, (fx_eurusd), [-4957.3]>

In [8]: fxs.rate(curves=[None, usd, None, eurusd], fx=fxf)
Out[8]: <Dual: -49.376656, (fx_eurusd), [44.9]>

In the case of FXSwaps, whose mid-market price is the difference between two forward FX rates we can also derive this quantity using the independent FXForwards.swap method.

In [9]: fxf.swap("usdeur", [dt(2022, 1, 18), dt(2022, 4, 19)])
Out[9]: <Dual: -49.376656, (fx_eurusd), [44.9]>

The following is an example of a fully priced FXSwap with split notionals.

In [10]: fxs = FXSwap(
   ....:     effective=dt(2022, 1, 18),
   ....:     termination=dt(2022, 4, 19),
   ....:     calendar="nyc",
   ....:     currency="usd",
   ....:     notional=1000000,
   ....:     leg2_currency="eur",
   ....:     curves=["usd", "usd", "eur", "eurusd"],
   ....:     fx_fixings=0.90,
   ....:     split_notional=1001500,
   ....:     points=-49.0
   ....: )
   ....: 

In [11]: fxs.npv(curves=[None, usd, None, eurusd], fx=fxf)
Out[11]: <Dual: 94.034131, (fx_eurusd), [-10095.5]>

In [12]: fxs.cashflows(curves=[None, usd, None, eurusd], fx=fxf)
Out[12]: 
               Type    Period  Ccy  Acc Start    Acc End    Payment Convention  DCF    Notional   DF  Rate Spread    Cashflow        NPV  FX Rate    NPV Ccy Collateral
leg1 0     Cashflow  Exchange  USD        NaT        NaT 2022-01-18       None  NaN -1000000.00 1.00   NaN   None  1000000.00  997613.85     1.00  997613.85        usd
     1  FixedPeriod   Regular  USD 2022-01-18 2022-04-19 2022-04-19     ACT360 0.25  1000000.00 0.98  0.59   None    -1500.00   -1477.41     1.00   -1477.41        usd
     2     Cashflow  Exchange  USD        NaT        NaT 2022-04-19       None  NaN  1000000.00 0.98   NaN   None -1000000.00 -984937.40     1.00 -984937.40        usd
leg2 0     Cashflow  Exchange  EUR        NaT        NaT 2022-01-18       None  NaN   900000.00 1.00   NaN   None  -900000.00 -898767.25     1.10 -988525.54        usd
     1  FixedPeriod   Regular  EUR 2022-01-18 2022-04-19 2022-04-19     ACT360 0.25  -900000.00 0.99 -1.56   None    -3557.35   -3526.51     1.10   -3878.69        usd
     2     Cashflow  Exchange  EUR        NaT        NaT 2022-04-19       None  NaN  -900000.00 0.99   NaN   None   900000.00  892197.09     1.10  981299.23        usd

In [13]: fxs.cashflows_table(curves=[None, usd, None, eurusd], fx=fxf)
Out[13]: 
local_ccy             EUR         USD
collateral_ccy        usd         usd
payment                              
2022-01-18     -900000.00  1000000.00
2022-04-19      896442.65 -1001500.00

Attributes Summary

fixed_rate

If set will also set the fixed_rate of the contained leg1.

float_spread

If set will also set the float_spread of contained leg1.

fx_fixings

index_base

If set will also set the index_base of the contained leg1.

leg2_fixed_rate

If set will also set the fixed_rate of the contained leg2.

leg2_float_spread

If set will also set the float_spread of contained leg2.

leg2_index_base

If set will also set the index_base of the contained leg1.

points

Methods Summary

analytic_delta(*args[, leg])

Return the analytic delta of a leg of the derivative object.

cashflows([curves, solver, fx, base])

Return the properties of all legs used in calculating cashflows.

cashflows_table([curves, solver, fx, base])

delta(*args, **kwargs)

Calculate the delta of the Instrument.

gamma(*args, **kwargs)

Calculate the gamma of the Instrument.

npv([curves, solver, fx, base, local])

Return the NPV of the derivative by summing legs.

rate([curves, solver, fx, fixed_rate])

Return the mid-market pricing parameter of the FXSwapS.

spread(*args, **kwargs)

Alias for rate()

Attributes Documentation

fixed_rate#

If set will also set the fixed_rate of the contained leg1.

Note

fixed_rate, float_spread, leg2_fixed_rate and leg2_float_spread are attributes only applicable to certain Instruments. AttributeErrors are raised if calling or setting these is invalid.

Type:

float or None

float_spread#

If set will also set the float_spread of contained leg1.

Type:

float or None

fx_fixings#
index_base#

If set will also set the index_base of the contained leg1.

Note

index_base and leg2_index_base are attributes only applicable to certain Instruments. AttributeErrors are raised if calling or setting these is invalid.

Type:

float or None

leg2_fixed_rate#

If set will also set the fixed_rate of the contained leg2.

Type:

float or None

leg2_float_spread#

If set will also set the float_spread of contained leg2.

Type:

float or None

leg2_index_base#

If set will also set the index_base of the contained leg1.

Note

index_base and leg2_index_base are attributes only applicable to certain Instruments. AttributeErrors are raised if calling or setting these is invalid.

Type:

float or None

points#

Methods Documentation

abstract analytic_delta(*args, leg=1, **kwargs)#

Return the analytic delta of a leg of the derivative object.

Parameters:
  • args – Required positional arguments supplied to BaseLeg.analytic_delta.

  • leg (int in [1, 2]) – The leg identifier of which to take the analytic delta.

  • kwargs – Required Keyword arguments supplied to BaseLeg.analytic_delta().

Return type:

float, Dual, Dual2

Examples

In [14]: curve = Curve({dt(2021,1,1): 1.00, dt(2025,1,1): 0.83}, id="SONIA")

In [15]: fxr = FXRates({"gbpusd": 1.25}, base="usd")
In [16]: irs = IRS(
   ....:     effective=dt(2022, 1, 1),
   ....:     termination="6M",
   ....:     frequency="Q",
   ....:     currency="gbp",
   ....:     notional=1e9,
   ....:     fixed_rate=5.0,
   ....: )
   ....: 

In [17]: irs.analytic_delta(curve, curve)
Out[17]: 47156.00216054951

In [18]: irs.analytic_delta(curve, curve, fxr)
Out[18]: <Dual: 58945.002701, (fx_gbpusd), [47156.0]>

In [19]: irs.analytic_delta(curve, curve, fxr, "gbp")
Out[19]: 47156.00216054951
cashflows(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, base=NoInput.blank)#

Return the properties of all legs used in calculating cashflows.

Parameters:
  • curves (CurveType, str or list of such, optional) –

    A single Curve, LineCurve or id or a list of such. A list defines the following curves in the order:

  • solver (Solver, optional) – The numerical Solver that constructs Curves from calibrating instruments.

  • fx (float, FXRates, FXForwards, optional) – The immediate settlement FX rate that will be used to convert values into another currency. A given float is used directly. If giving a FXRates or FXForwards object, converts from local currency into base.

  • base (str, optional) – The base currency to convert cashflows into (3-digit code). Only used if fx is an FXRates or FXForwards object. If not given defaults to fx.base.

Return type:

DataFrame

Notes

If only one curve is given this is used as all four curves.

If two curves are given the forecasting curve is used as the forecasting curve on both legs and the discounting curve is used as the discounting curve for both legs.

If three curves are given the single discounting curve is used as the discounting curve for both legs.

Examples

In [1]: irs.cashflows([curve], fx=fxr)
Out[1]: 
               Type   Period  Ccy  Acc Start    Acc End    Payment Convention  DCF       Notional   DF Collateral  Rate  Spread     Cashflow          NPV  FX Rate      NPV Ccy
leg1 0  FixedPeriod  Regular  GBP 2022-01-01 2022-04-01 2022-04-03     ACT360 0.25  1000000000.00 0.94       None  5.00     NaN -12500000.00 -11792277.34     1.25 -14740346.67
     1  FixedPeriod  Regular  GBP 2022-04-01 2022-07-01 2022-07-03     ACT360 0.25  1000000000.00 0.93       None  5.00     NaN -12638888.89 -11785723.74     1.25 -14732154.68
leg2 0  FloatPeriod  Regular  GBP 2022-01-01 2022-04-01 2022-04-03     ACT360 0.25 -1000000000.00 0.94       None  4.62    0.00  11544335.50  10890720.47     1.25  13613400.59
     1  FloatPeriod  Regular  GBP 2022-04-01 2022-07-01 2022-07-03     ACT360 0.25 -1000000000.00 0.93       None  4.62    0.00  11673351.69  10885363.37     1.25  13606704.21
cashflows_table(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, base=NoInput.blank)#
delta(*args, **kwargs)#

Calculate the delta of the Instrument.

For arguments see Sensitivities.delta().

gamma(*args, **kwargs)#

Calculate the gamma of the Instrument.

For arguments see Sensitivities.gamma().

npv(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, base=NoInput.blank, local=False)#

Return the NPV of the derivative by summing legs.

Warning

If fx_fixing has not been set for the instrument requires fx as an FXForwards object to dynamically determine this.

See BaseDerivative.npv().

rate(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, fixed_rate=False)#

Return the mid-market pricing parameter of the FXSwapS.

Parameters:
  • curves (list of Curves) –

    A list defines the following curves in the order:

    • Forecasting Curve for leg1 (if floating).

    • Discounting Curve for leg1.

    • Forecasting Curve for leg2 (if floating).

    • Discounting Curve for leg2.

  • solver (Solver, optional) – The numerical Solver that constructs Curve from calibrating instruments.

  • fx (FXForwards, optional) – The FX forwards object that is used to determine the initial FX fixing for determining leg2_notional, if not specified at initialisation, and for determining mark-to-market exchanges on mtm XCSs.

  • fixed_rate (bool) – Whether to return the fixed rate for the leg or the FX swap points price.

Return type:

float, Dual or Dual2

spread(*args, **kwargs)#

Alias for rate()