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 thefx_fixings
either initialised or at price time and the value ofnotional
. The argument value ofleg2_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
andpoints
. If asplit_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 parameterpoints
can be calculated. This is an unusual partially priced parametrisation, however, and a warning will be emitted. As before, ifsplit_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
orsplit_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.# 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()
andrate()
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
If set will also set the
fixed_rate
of the contained leg1.If set will also set the
float_spread
of contained leg1.If set will also set the
index_base
of the contained leg1.If set will also set the
fixed_rate
of the contained leg2.If set will also set the
float_spread
of contained leg2.If set will also set the
index_base
of the contained leg1.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
andleg2_float_spread
are attributes only applicable to certainInstruments
. 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
andleg2_index_base
are attributes only applicable to certainInstruments
. 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
andleg2_index_base
are attributes only applicable to certainInstruments
. 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:
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 constructsCurves
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
orFXForwards
object, converts from local currency intobase
.base (str, optional) – The base currency to convert cashflows into (3-digit code). Only used if
fx
is anFXRates
orFXForwards
object. If not given defaults tofx.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 requiresfx
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:
solver (Solver, optional) – The numerical
Solver
that constructsCurve
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:
- spread(*args, **kwargs)#
Alias for
rate()