FXSwap#

class rateslib.instruments.FXSwap(*args, pair=NoInput.blank, 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.

  • pair (str, optional) – The FX pair, e.g. “eurusd” as 3-digit ISO codes. If not given, fallsback to the base implementation of XCS which defines separate inputs as currency and leg2_currency. If overspecified, pair will dominate.

  • fx_fixings (float, Variable, FXForwards, optional) – The initial FX fixing where leg 1 is considered the domestic currency. For example for a EURUSD FXSwap in 100mm EUR notional a value of 1.10 implies the notional on leg 2 is 110m USD. If not given 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),
   ...:     pair="usdeur",
   ...:     calendar="nyc",
   ...:     notional=1000000,
   ...:     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),
   ....:     pair="usdeur",
   ....:     calendar="nyc",
   ....:     notional=1000000,
   ....:     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    Payment   Notional        DF      Rate    Cashflow            NPV   FX Rate        NPV Ccy Collateral  Acc Start    Acc End Convention       DCF  Spread
leg1 0     Cashflow  Exchange  USD 2022-01-18 -1000000.0  0.997614       NaN  1000000.00  997613.848644  1.000000  997613.848644        usd        NaT        NaT        NaN       NaN     NaN
     1  FixedPeriod      Stub  USD 2022-04-19  1000000.0  0.984937  0.593407    -1500.00   -1477.406099  1.000000   -1477.406099        usd 2022-01-18 2022-04-19     Act360  0.252778     NaN
     2     Cashflow  Exchange  USD 2022-04-19  1000000.0  0.984937       NaN -1000000.00 -984937.399186  1.000000 -984937.399186        usd        NaT        NaT        NaN       NaN     NaN
leg2 0     Cashflow  Exchange  EUR 2022-01-18   900000.0  0.998630       NaN  -900000.00 -898767.253786  1.099868 -988525.541382        usd        NaT        NaT        NaN       NaN     NaN
     1  FixedPeriod      Stub  EUR 2022-04-19  -900000.0  0.991330 -1.563670    -3557.35   -3526.508129  1.099868   -3878.694226        usd 2022-01-18 2022-04-19     Act360  0.252778     NaN
     2     Cashflow  Exchange  EUR 2022-04-19  -900000.0  0.991330       NaN   900000.00  892197.089417  1.099868  981299.226379        usd        NaT        NaT        NaN       NaN     NaN

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.0
2022-04-19      896442.65 -1001500.0

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

Aggregate the values derived from a cashflows() method on an Instrument.

delta(*args, **kwargs)

Calculate the delta of the Instrument.

exo_delta(*args, **kwargs)

Calculate the delta of the Instrument, measured against user defined Variable s.

fixings_table([curves, solver, fx, base, ...])

Return a DataFrame of fixing exposures on any FloatLeg or FloatLegMtm associated with the XCS.

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.250000  1.000000e+09  0.943382       None  5.000000     NaN -1.250000e+07 -1.179228e+07     1.25 -1.474035e+07
     1  FixedPeriod  Regular  GBP 2022-04-01 2022-07-01 2022-07-03     Act360  0.252778  1.000000e+09  0.932497       None  5.000000     NaN -1.263889e+07 -1.178572e+07     1.25 -1.473215e+07
leg2 0  FloatPeriod  Regular  GBP 2022-01-01 2022-04-01 2022-04-03     Act360  0.250000 -1.000000e+09  0.943382       None  4.617734     0.0  1.154434e+07  1.089072e+07     1.25  1.361340e+07
     1  FloatPeriod  Regular  GBP 2022-04-01 2022-07-01 2022-07-03     Act360  0.252778 -1.000000e+09  0.932497       None  4.618029     0.0  1.167335e+07  1.088536e+07     1.25  1.360670e+07
cashflows_table(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, base=NoInput.blank, **kwargs)#

Aggregate the values derived from a cashflows() method on an Instrument.

Parameters:
  • curves (CurveType, str or list of such, optional) – Argument input to the underlying cashflows method of the Instrument.

  • solver (Solver, optional) – Argument input to the underlying cashflows method of the Instrument.

  • fx (float, FXRates, FXForwards, optional) – Argument input to the underlying cashflows method of the Instrument.

  • base (str, optional) – Argument input to the underlying cashflows method of the Instrument.

  • kwargs (dict) – Additional arguments input the underlying cashflows method of the Instrument.

Return type:

DataFrame

delta(*args, **kwargs)#

Calculate the delta of the Instrument.

For arguments see Sensitivities.delta().

exo_delta(*args, **kwargs)#

Calculate the delta of the Instrument, measured against user defined Variable s.

For arguments see Sensitivities.exo_delta().

fixings_table(curves=NoInput.blank, solver=NoInput.blank, fx=NoInput.blank, base=NoInput.blank, approximate=False, right=NoInput.blank)#

Return a DataFrame of fixing exposures on any FloatLeg or FloatLegMtm associated with the XCS.

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

    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.

    Note

    The arguments fx and base are unused and results are returned in local currency of each Leg.

  • approximate (bool, optional) – Perform a calculation that is broadly 10x faster but potentially loses precision upto 0.1%.

  • right (datetime, optional) – Only calculate fixing exposures upto and including this date.

Return type:

DataFrame

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()