FXRates#
- class rateslib.fx.FXRates(fx_rates, settlement=NoInput.blank, base=NoInput.blank)#
Bases:
_WithState
Object to store and calculate FX rates for a consistent settlement date.
- Parameters:
fx_rates (dict[str, float]) – Dict whose keys are 6-character currency pairs, and whose values are the relevant rates.
settlement (datetime, optional) – The settlement date for the FX rates.
base (str, optional) –
The base currency (3-digit code). If not given defaults to either:
the base currency defined in defaults, if it is present in the list of currencies,
the first currency detected.
Notes
Note
When this class uses
Dual
numbers to represent sensitivities of values to certain FX rates the variable names are called “fx_cc1cc2” where “cc1” is left hand currency and “cc2” is the right hand currency in the currency pair. See the examples contained in class methods for clarification.Examples
An FX rates market of n currencies is completely defined by n-1 independent FX pairs.
Below we define an FX rates market in 4 currencies with 3 FX pairs,
In [1]: fxr = FXRates({"eurusd": 1.1, "gbpusd": 1.25, "usdjpy": 100}) In [2]: fxr.currencies Out[2]: {'usd': 0, 'eur': 1, 'gbp': 2, 'jpy': 3} In [3]: fxr.rate("gbpjpy") Out[3]: <Dual: 125.000000, (fx_gbpusd, fx_usdjpy), [100.0, 1.2]>
Ill defined FX markets will raise
ValueError
and are either overspecified,In [4]: try: ...: FXRates({"eurusd": 1.1, "gbpusd": 1.25, "usdjpy": 100, "gbpjpy": 125}) ...: except ValueError as e: ...: print(e) ...: FX Array cannot be solved. `fx_rates` is overspecified.
or are underspecified,
In [5]: try: ...: FXRates({"eurusd": 1.1, "gbpjpy": 125}) ...: except ValueError as e: ...: print(e) ...: FX Array cannot be solved. `fx_rates` is underspecified.
or use redundant, co-dependent information,
In [6]: try: ...: FXRates({"eurusd": 1.1, "usdeur": 0.90909, "gbpjpy": 125}) ...: except ValueError as e: ...: print(e) ...: FX Array cannot be solved. There are degenerate FX rate pairs. For example ('eurusd' + 'usdeur') or ('usdeur', 'eurjpy', 'usdjpy').
Attributes Summary
The assumed base currency of the object which may be used as the default
base
currency innpv
calculations when otherwise omitted.A dict whose keys are the currencies contained in the object and the value is the ordered index of that currencies in other attributes such as
fx_array
andcurrencies_list
.An list of currencies available in the object.
An array containing all of the FX pairs/crosses available on the object.
The dict of currency pairs and their FX rates that define the object.
A vector of currency FX rates all relative to the stated
base
currency.A list of the currency pairs that define the object.
A dict aggregating each FX pair and its settlement date.
The number of currencies contained in the object.
The settlement date of the FX rates that define the object.
The names of the variables associated with the object for automatic differentiation (AD) purposes.
Methods Summary
convert
(value, domestic[, foreign, on_error])Convert an amount of a domestic currency into a foreign currency.
convert_positions
(array[, base])Convert an array of currency cash positions into a single base currency.
positions
(value[, base])Convert a base value with FX rate sensitivities into an array of cash positions.
rate
(pair)Return a specified FX rate for a given currency pair.
Return a DataFrame of all FX rates in the object.
restate
(pairs[, keep_ad])Create a new
FXRates
class using other (or fewer) currency pairs as majors.to_json
()Return a JSON representation of the object.
update
([fx_rates])Update all or some of the FX rates of the instance with new market data.
Attributes Documentation
- base#
The assumed base currency of the object which may be used as the default
base
currency innpv
calculations when otherwise omitted.The base currency has index 0 in the
currencies
dict and is that which thefx_vector
is defined relative to.
- currencies#
A dict whose keys are the currencies contained in the object and the value is the ordered index of that currencies in other attributes such as
fx_array
andcurrencies_list
.
- currencies_list#
An list of currencies available in the object. Aligns with
currencies
.
- fx_array#
An array containing all of the FX pairs/crosses available on the object.
- fx_rates#
The dict of currency pairs and their FX rates that define the object.
- fx_vector#
A vector of currency FX rates all relative to the stated
base
currency.
- pairs#
A list of the currency pairs that define the object. The number of pairs is one less than
q
.
- pairs_settlement#
A dict aggregating each FX pair and its settlement date. In an FXRates object all pairs settle on the same settlement date.
- q#
The number of currencies contained in the object.
- settlement#
The settlement date of the FX rates that define the object.
- variables#
The names of the variables associated with the object for automatic differentiation (AD) purposes.
Methods Documentation
- convert(value, domestic, foreign=NoInput.blank, on_error='ignore')#
Convert an amount of a domestic currency into a foreign currency.
- 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.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]: fxr = FXRates({"usdnok": 8.0}) In [2]: fxr.convert(1000000, "nok", "usd") Out[2]: <Dual: 125000.000000, (fx_usdnok), [-15625.0]> In [3]: fxr.convert(1000000, "nok", "inr") # <- returns None, "inr" not in fxr.
- convert_positions(array, base=NoInput.blank)#
Convert an array of currency cash positions into a single base currency.
- Parameters:
array (list, 1d ndarray of floats, or Series) – The cash positions to simultaneously convert in the base currency. Must be ordered by currency as defined in the attribute
FXRates.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}) In [2]: fxr.currencies Out[2]: {'usd': 0, 'nok': 1} In [3]: fxr.convert_positions([0, 1000000], "usd") Out[3]: <Dual: 125000.000000, (fx_usdnok), [-15625.0]>
- positions(value, base=NoInput.blank)#
Convert a base value with FX rate sensitivities into an array of cash positions.
- 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.
- Return type:
Series
Examples
In [1]: fxr = FXRates({"usdnok": 8.0}) In [2]: fxr.positions(Dual(125000, ["fx_usdnok"], [-15625]), "usd") Out[2]: usd 0.0 nok 1000000.0 dtype: float64 In [3]: fxr.positions(100, base="nok") Out[3]: usd 0.0 nok 100.0 dtype: float64
- rate(pair)#
Return a specified FX rate for a given currency pair.
- Parameters:
pair (str) – The FX pair in usual domestic:foreign convention (6 digit code).
- Return type:
Examples
In [1]: fxr = FXRates({"usdeur": 2.0, "usdgbp": 2.5}) In [2]: fxr.rate("eurgbp") Out[2]: <Dual: 1.250000, (fx_usdeur, fx_usdgbp), [-0.6, 0.5]>
- rates_table()#
Return a DataFrame of all FX rates in the object.
- Return type:
DataFrame
- restate(pairs, keep_ad=False)#
Create a new
FXRates
class using other (or fewer) currency pairs as majors.- Parameters:
pairs (list of str) – The new currency pairs with which to define the
FXRates
class.keep_ad (bool, optional) – Keep the original derivative exposures defined by
Dual
, instead of redefinition. It is advised against setting this to True, it is mainly used internally.
- Return type:
Notes
This will redefine the pairs to which delta risks are expressed in
Dual
outputs.If
pairs
match the existing object andkeep_ad
is requested then the existing object is returned unchanged as new copy.Examples
Re-expressing an FXRates class with new majors, to which Dual sensitivities are measured.
In [1]: fxr = FXRates({"eurgbp": 0.9, "gbpjpy": 125, "usdjpy": 100}) In [2]: fxr.convert(100, "gbp", "usd") Out[2]: <Dual: 125.000000, (fx_usdjpy, fx_gbpjpy), [-1.2, 1.0]> In [3]: fxr2 = fxr.restate(["eurusd", "gbpusd", "usdjpy"]) In [4]: fxr2.convert(100, "gbp", "usd") Out[4]: <Dual: 125.000000, (fx_gbpusd), [100.0]>
Extracting an FXRates subset from a larger object.
In [5]: fxr = FXRates({"eurgbp": 0.9, "gbpjpy": 125, "usdjpy": 100, "audusd": 0.85}) In [6]: fxr2 = fxr.restate({"eurusd", "gbpusd"}) In [7]: fxr2.rates_table() Out[7]: usd gbp eur usd 1.000 0.8 0.888889 gbp 1.250 1.0 1.111111 eur 1.125 0.9 1.000000
- to_json()#
Return a JSON representation of the object.
- Return type:
str
- update(fx_rates=NoInput.blank)#
Update all or some of the FX rates of the instance with new market data.
- Parameters:
fx_rates (dict, optional) – Dict whose keys are 6-character domestic-foreign currency pairs and which are present in FXRates.pairs, and whose values are the relevant rates to update. An empty dict will be ignored and perform no update.
- Return type:
None
Notes
Warning
Rateslib is an object-oriented library that uses complex associations. Although Python may not object to directly mutating attributes of an FXRates instance, this should be avoided in rateslib. Only use official
update
methods to mutate the values of an existing FXRates instance. This class is labelled as a mutable on update object.Suppose an FXRates class has been instantiated and resides in memory.
In [1]: fxr = FXRates({"eurusd": 1.05, "gbpusd": 1.25}, settlement=dt(2022, 1, 3), base="usd") In [2]: id(fxr) Out[2]: 4703668272
This object may be linked to others, probably an
FXForwards
class. It can be updated with some new market data. This will preserve its memory id and association with other objects. AnyFXForwards
objects referencing this will detect this change and will also lazily update via rateslib’s state management.In [3]: linked_obj = fxr In [4]: fxr.update({"eurusd": 1.06}) In [5]: id(fxr) # <- SAME as above Out[5]: 4703668272 In [6]: linked_obj.rate("eurusd") Out[6]: <Dual: 1.060000, (fx_eurusd), [1.0]>
Examples
In [7]: fxr = FXRates({"usdeur": 0.9, "eurnok": 8.5}) In [8]: fxr.rate("usdnok") Out[8]: <Dual: 7.650000, (fx_usdeur, fx_eurnok), [8.5, 0.9]> In [9]: fxr.update({"usdeur": 1.0}) In [10]: fxr.rate("usdnok") Out[10]: <Dual: 8.500000, (fx_usdeur, fx_eurnok), [8.5, 1.0]>