FXForwards#
- class rateslib.fx.FXForwards(fx_rates, fx_curves, base=NoInput.blank)#
Bases:
_WithState
,_WithCache
[tuple
[str
,datetime
],Dual | Dual2 | Variable | float
]Class for storing and calculating FX forward rates.
- Parameters:
fx_rates (FXRates, or list of such) – An
FXRates
object with an associated settlement date. If multiple settlement dates are relevant, e.g. GBPUSD (T+2) and USDCAD(T+1), then a list ofFXRates
object is allowed to create a no arbitrage framework.fx_curves (dict) – A dict of DF
Curve
objects defined by keys of two currency labels. First, by the currency in which cashflows occur (3-digit code), combined with the currency by which the future cashflow is collateralised in a derivatives sense (3-digit code). There must also be a curve in each currency for local discounting, i.e. where the cashflow and collateral currency are the same. See examples.base (str, optional) – The base currency (3-digit code). If not given defaults to the base currency of the first
fx_rates
object.
Notes
\[\begin{split}f_{DOMFOR,i} &= \text{Forward domestic-foreign FX rate fixing on maturity date, }m_i \\ F_{DOMFOR,0} &= \text{Immediate settlement market domestic-foreign FX rate} \\ v_{dom:dom,i} &= \text{Local domestic-currency DF on maturity date, }m_i \\ w_{dom:for,i} &= \text{XCS adjusted domestic-currency DF on maturity date, }m_i \\\end{split}\]Examples
The most basic
FXForwards
object is created from a spotFXRates
object and two local currency discount curves.In [1]: from rateslib.fx import FXRates, FXForwards In [2]: from rateslib.curves import Curve
In [3]: fxr = FXRates({"eurusd": 1.1}, settlement=dt(2022, 1, 3)) In [4]: eur_local = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.91}) In [5]: usd_local = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.95}) In [6]: fxf = FXForwards(fxr, {"usdusd": usd_local, "eureur": eur_local, "eurusd": eur_local})
Note that in the above the
eur_local
curve has also been used as the curve for EUR cashflows collateralised in USD, which is necessary for calculation of forward FX rates and cross-currency basis. With this assumption the cross-currency basis is implied to be zero at all points along the curve.- fx_curves#
- Type:
dict
- immediate#
- Type:
datetime
- currencies#
- Type:
dict
- q#
- Type:
int
- currencies_list#
- Type:
list
- transform#
- Type:
ndarray
- base#
- Type:
str
Attributes Summary
A dict of cached
ProxyCurve
associated with this object.Methods Summary
convert
(value, domestic[, foreign, ...])Convert an amount of a domestic currency, as of a settlement date into a foreign currency, valued on another date.
convert_positions
(array[, base])Convert an input of currency cash positions into a single base currency value.
copy
()An FXForwards copy creates a new object with copied references.
curve
(cashflow, collateral[, id])Return a cash collateral Curve.
from_json
(fx_forwards, **kwargs)Loads an FXForwards object from JSON.
plot
(pair[, right, left, fx_swap])Plot given forward FX rates.
positions
(value[, base, aggregate])Convert a base value with FX rate sensitivities into an array of cash positions by settlement date.
rate
(pair[, settlement])Return the fx forward rate for a currency pair.
swap
(pair, settlements)Return the FXSwap mid-market rate for the given currency pair.
to_json
()update
([fx_rates])Update the FXForward object with the latest FX rates and FX curves values.
Attributes Documentation
- fx_proxy_curves#
A dict of cached
ProxyCurve
associated with this object.
Methods Documentation
- convert(value, domestic, foreign=NoInput.blank, settlement=NoInput.blank, value_date=NoInput.blank, collateral=NoInput.blank, on_error='ignore')#
Convert an amount of a domestic currency, as of a settlement date into a foreign currency, valued on another date.
- Parameters:
value (float or Dual) – The amount of the domestic currency to convert.
domestic (str) – The domestic currency (3-digit code).
foreign (str, optional) – The foreign currency to convert to (3-digit code). Uses instance
base
if not given.settlement (datetime, optional) – The date of the assumed domestic currency cashflow. If not given is assumed to be
immediate
settlement.value_date (datetime, optional) – The date for which the domestic cashflow is to be projected to. If not given is assumed to be equal to the
settlement
.collateral (str, optional) – The collateral currency to project the cashflow if
value_date
is different tosettlement
. If they are the same this is not needed. If not given defaults todomestic
.on_error (str in {"ignore", "warn", "raise"}) – The action taken if either
domestic
orforeign
are not contained in the FX framework. “ignore” and “warn” will still return None.
- Return type:
Dual or None
Examples
In [1]: fxr1 = FXRates({"eurusd": 1.05}, settlement=dt(2022, 1, 3)) In [2]: fxr2 = FXRates({"usdcad": 1.1}, settlement=dt(2022, 1, 2)) In [3]: fxf = FXForwards( ...: fx_rates=[fxr1, fxr2], ...: fx_curves={ ...: "usdusd": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: "eureur": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: "cadcad": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: "usdeur": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: "cadusd": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: } ...: ) ...: In [4]: fxf.convert(1000, "usd", "cad") Out[4]: <Dual: 1100.000000, (fx_usdcad), [1000.0]>
- convert_positions(array, base=NoInput.blank)#
Convert an input of currency cash positions into a single base currency value.
- Parameters:
array (list, 1d ndarray of floats, or Series, or DataFrame) – The cash positions to simultaneously convert to base currency value. If a DataFrame, must be indexed by currencies (3-digit lowercase) and the column headers must be settlement dates. If a Series, must be indexed by currencies (3-digit lowercase). If a 1d array or sequence, must be ordered by currency as defined in the attribute
FXForward.currencies
.base (str, optional) – The currency to convert to (3-digit code). Uses instance
base
if not given.
- Return type:
Examples
In [1]: fxr = FXRates({"usdnok": 8.0}, settlement=dt(2022, 1, 1)) In [2]: usdusd = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.99}) In [3]: noknok = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.995}) In [4]: fxf = FXForwards(fxr, {"usdusd": usdusd, "noknok": noknok, "nokusd": noknok}) In [5]: fxf.currencies Out[5]: {'usd': 0, 'nok': 1} In [6]: fxf.convert_positions([0, 1000000], "usd") Out[6]: <Dual: 125000.000000, (fx_usdnok), [-15625.0]>
In [7]: fxr.convert_positions(Series([1000000, 0], index=["nok", "usd"]), "usd") Out[7]: <Dual: 1000000.000000, (fx_usdnok), [0.0]>
In [8]: positions = DataFrame(index=["usd", "nok"], data={ ...: dt(2022, 6, 2): [0, 1000000], ...: dt(2022, 9, 7): [0, -1000000], ...: }) ...: In [9]: fxf.convert_positions(positions, "usd") Out[9]: <Dual: 166.054676, (fx_usdnok), [-20.8]>
- copy()#
An FXForwards copy creates a new object with copied references.
- curve(cashflow, collateral, id=NoInput.blank)#
Return a cash collateral Curve.
- Parameters:
cashflow (str) – The currency in which cashflows are represented (3-digit code).
collateral (str, or list/tuple of such) – The currency of the CSA against which cashflows are collateralised (3-digit code). If a list or tuple will return a CompositeCurve in multi-CSA mode.
id (str, optional) – The identifier attached to any constructed
ProxyCurve
.
- Return type:
Notes
If the
Curve
already exists within the attributefx_curves
that Curve will be returned directly.If a
ProxyCurve
already exists with the attributefx_proxy_curves
that Curve will be returned.Otherwise, creates and returns a
ProxyCurve
which determines rates and DFs via the chaining method and the below formula,\[w_{dom:for,i} = \frac{f_{DOMFOR,i}}{F_{DOMFOR,0}} v_{for:for,i}\]For multiple collateral currencies returns a
MultiCsaCurve
.The
_CurveMeta
inherits values from the local cashCurve
, and thecollateral
value is set as the defined collateral currency.
- classmethod from_json(fx_forwards, **kwargs)#
Loads an FXForwards object from JSON.
- Parameters:
fx_forwards (str) – JSON string describing the FXForwards class. Typically constructed with
to_json()
.- Return type:
Notes
This method also creates new
FXRates
andCurve
objects from JSON. These new objects can be accessed from the attributes of theFXForwards
instance.
- plot(pair, right=NoInput.blank, left=NoInput.blank, fx_swap=False)#
Plot given forward FX rates.
- Parameters:
pair (str) – The FX pair to determine rates for (6-digit code).
right (datetime or str, optional) – The right bound of the graph. If given as str should be a tenor format defining a point measured from the initial node date of the curve. Defaults to the terminal date of the FXForwards object.
left (datetime or str, optional) – The left bound of the graph. If given as str should be a tenor format defining a point measured from the initial node date of the curve. Defaults to the immediate FX settlement date.
fx_swap (bool) – Whether to plot as the FX rate or as FX swap points relative to the initial FX rate on the left side of the chart. Default is False.
- Returns:
(fig, ax, line)
- Return type:
Matplotlib.Figure, Matplotplib.Axes, Matplotlib.Lines2D
- positions(value, base=NoInput.blank, aggregate=False)#
Convert a base value with FX rate sensitivities into an array of cash positions by settlement date.
- Parameters:
value (float or Dual) – The amount expressed in base currency to convert to cash positions.
base (str, optional) – The base currency in which
value
is given (3-digit code). If not given assumes thebase
of the object.aggregate (bool, optional) – Whether to aggregate positions across all settlement dates and yield a single column Series.
- Return type:
DataFrame or Series
Examples
In [1]: fxr1 = FXRates({"eurusd": 1.05}, settlement=dt(2022, 1, 3)) In [2]: fxr2 = FXRates({"usdcad": 1.1}, settlement=dt(2022, 1, 2)) In [3]: fxf = FXForwards( ...: fx_rates=[fxr1, fxr2], ...: fx_curves={ ...: "usdusd": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: "eureur": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: "cadcad": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: "usdeur": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: "cadusd": Curve({dt(2022, 1, 1):1.0, dt(2022, 2, 1): 0.999}), ...: } ...: ) ...: In [4]: fxf.positions( ...: value=Dual(100000, ["fx_eurusd", "fx_usdcad"], [-100000, -150000]), ...: base="usd", ...: ) ...: Out[4]: 2022-01-01 2022-01-02 2022-01-03 cad 0.0 181500.0 0.0 eur 0.0 0.0 -100000.0 usd 100000.0 -165000.0 105000.0
- rate(pair, settlement=NoInput.blank)#
Return the fx forward rate for a currency pair.
- Parameters:
pair (str) – The FX pair in usual domestic:foreign convention (6 digit code).
settlement (datetime, optional) – The settlement date of currency exchange. If not given defaults to immediate settlement.
- Return type:
Notes
Uses the formula,
\[f_{DOMFOR, i} = \frac{w_{dom:for, i}}{v_{for:for, i}} F_{DOMFOR,0} = \frac{v_{dom:dom, i}}{w_{for:dom, i}} F_{DOMFOR,0}\]where \(v\) is a local currency discount curve and \(w\) is a discount curve collateralised with an alternate currency.
If required curves do not exist in the relevant currencies then forwards rates are chained using those calculable from available curves. The chain is found using a search algorithm.
\[f_{DOMFOR, i} = f_{DOMALT, i} ... f_{ALTFOR, i}\]
- swap(pair, settlements)#
Return the FXSwap mid-market rate for the given currency pair.
- Parameters:
pair (str) – The FX pair in usual domestic:foreign convention (6-digit code).
settlements (list of datetimes,) – The settlement date of currency exchanges.
- Return type:
- to_json()#
- update(fx_rates=NoInput.blank)#
Update the FXForward object with the latest FX rates and FX curves values.
The update method is primarily used to allow synchronous updating within a
Solver
.- Parameters:
fx_rates (list of dict, optional) – A list of dictionaries with new rates to update the associated
FXRates
objects associated with the FXForwards object.- Return type:
None
Notes
An FXForwards object contains associations to external objects, those being
FXRates
andCurve
, and its purpose is to be able to combine those objects to yield FX forward rates.When those external objects have themselves been updated the FXForwards class will detect this via rateslib’s cache management and will automatically update the FXForwards object. Manually calling this update on the FXForwards class also allows those associated FXRates classes to be updated with new market data.
In [1]: fxr = FXRates({"eurusd": 1.05}, settlement=dt(2022, 1, 3), base="usd") In [2]: fx_curves = { ...: "usdusd": Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.965}), ...: "eureur": Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.985}), ...: "eurusd": Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.985}), ...: } ...: In [3]: fxf = FXForwards(fxr, fx_curves) In [4]: fxf.rate("eurusd", dt(2022, 8, 15)) Out[4]: <Dual: 1.063302, (fx_eurusd), [1.0]>
In [5]: fxr.update({"eurusd": 2.0}) # <-- update the associated FXRates object. In [6]: fxf.rate("eurusd", dt(2022, 8, 15)) # <-- rate has changed, fxf has auto-updated. Out[6]: <Dual: 2.025337, (fx_eurusd), [1.0]>
It is possible to update an FXRates object directly from the FXForwards object, via the
fx_rates
argument.In [7]: fxf.update([{"eurusd": 1.50}]) In [8]: fxf.rate("eurusd", dt(2022, 8, 15)) Out[8]: <Dual: 1.519003, (fx_eurusd), [1.0]>
The
Solver
also automatically updates FXForwards objects when it mutates and solves the Curves.