Working with Fixings#
The rateslib defaults object lazy loads fixings from CSV files. These files are stored in the rateslib package files under the directory ‘data’. Due to static packaging and licencing issues rateslib cannot be distributed with accurate and upto date RFR or IBOR fixings.
As an example, a small selection of SOFR fixings which are used in some examples within, rateslib documentation are shown below along with the source directory.
In [1]: defaults.fixings.directory
Out[1]: '/home/docs/checkouts/readthedocs.org/user_builds/rateslib/checkouts/latest/rateslib/data'
In [2]: defaults.fixings["usd_rfr"] # an available alias is 'fixings["sofr"]'
Out[2]:
reference_date
2018-04-02 1.80
2018-04-03 1.83
2018-04-04 1.74
2018-04-05 1.75
2018-04-06 1.75
...
2023-07-26 5.06
2023-07-27 5.31
2023-07-28 5.30
2023-07-31 5.31
2023-08-01 5.31
Name: rate, Length: 1333, dtype: float64
It is possible to overwrite these CSV files (provided the template structure is maintained) or to set a new directory and place new CSV files there. Due to lazy loading, this should be done before calling any fixing Series, and all files should be stored in the same folder with the required naming convention.
First we obtain (or create) new fixing for the SEK 3M STIBOR index, and save it to CSV file in the current working directory.
In [3]: df = DataFrame(
...: data=[1.21, 2.75],
...: index=Index(["02-01-2023", "03-01-2023"], name="reference_date"),
...: columns=["rate"]
...: )
...:
In [4]: print(df)
rate
reference_date
02-01-2023 1.21
03-01-2023 2.75
In [5]: df.to_csv("sek_ibor_3m.csv") # Save the DataFrame and create a CSV file
Next we set the directory of the defaults.fixings object and load the fixings.
In [6]: import os
In [7]: defaults.fixings.directory = os.getcwd()
In [8]: defaults.fixings["sek_ibor_3m"]
Out[8]:
reference_date
2023-01-02 1.21
2023-01-03 2.75
Name: rate, dtype: float64
These fixings are entirely user defined in their construction and naming convention. If an attempt is made to call a fixing series that doesn’t exist the user is met with the instructive error.
In [9]: try:
...: defaults.fixings["arbitrary_index"]
...: except ValueError as e:
...: print(e)
...:
Fixing data for the index 'arbitrary_index' has been attempted, but there is no file:
'arbitrary_index.csv' located in the search directory: '/home/docs/checkouts/readthedocs.org/user_builds/rateslib/checkouts/latest/docs/source'
Create a CSV file in the directory with the above name and the exact template structure:
###################
reference_date,rate
26-08-2023,5.6152
27-08-2023,5.6335
##################
For further info see 'Working with Fixings' in the documentation cookbook.
Constructing Instruments with fixings#
These fixings can then be passed to Instrument constructors. For STIBOR the index lag is 2 business days so the fixing for the below IRS effective as of 4th January is taken as the value published on the reference date 2nd January.
In [10]: irs = IRS(
....: effective=dt(2023, 1, 4),
....: termination="6M",
....: spec="sek_irs3",
....: leg2_fixings=defaults.fixings["sek_ibor_3m"],
....: fixed_rate=2.00,
....: )
....:
In [11]: curve = Curve({dt(2023, 1, 3): 1.0, dt(2024, 1, 3): 0.97})
In [12]: irs.cashflows(curve)
Out[12]:
Type Period Ccy Acc Start Acc End Payment Convention DCF Notional DF Collateral Rate Spread Cashflow NPV FX Rate NPV Ccy
leg1 0 FixedPeriod Stub SEK 2023-01-04 2023-07-04 2023-07-04 30e360 0.50 1000000.00 0.98 None 2.00 NaN -10000.00 -9849.27 1.00 -9849.27
leg2 0 FloatPeriod Regular SEK 2023-01-04 2023-04-04 2023-04-04 act360 0.25 -1000000.00 0.99 None 1.21 0.00 3025.00 3002.12 1.00 3002.12
1 FloatPeriod Regular SEK 2023-04-04 2023-07-04 2023-07-04 act360 0.25 -1000000.00 0.98 None 3.06 0.00 7728.72 7612.22 1.00 7612.22
In [13]: irs.leg2.fixings_table(curve)
Out[13]:
notional dcf rates
obs_dates
2023-01-02 1000000.00 None 1.21
2023-04-02 1000000.00 None 3.06
Using fx fixings in multi-currency Instruments#
XCS
typically require MTM payments based on FX fixings. However,
the first FX fixing is usually agreed at trade time as the prevailing FX rate at the instant of
execution. This poses a challenge to the initial construction of these Instruments.
Rateslib handles this by allowing a 2-tuple as an input to fx_fixings
. The first entry is
assigned to the first period and the latter entry is the FX fixings Series.
Consider the example below.
In [14]: df = DataFrame(
....: data=[1.19, 1.21, 1.24],
....: index=Index(["17-01-2023", "17-04-2023", "17-07-2023"], name="reference_date"),
....: columns=["rate"]
....: )
....:
In [15]: print(df)
rate
reference_date
17-01-2023 1.19
17-04-2023 1.21
17-07-2023 1.24
In [16]: df.to_csv("gbpusd.csv") # Save the DataFrame and create a CSV file
In [17]: xcs = XCS(
....: effective=dt(2023, 1, 15),
....: termination="9M",
....: spec="gbpusd_xcs",
....: fx_fixings=(1.20, defaults.fixings["gbpusd"]),
....: )
....:
In [18]: xcs.cashflows(curves=curve, fx=1.25) # arguments here used as a placeholder to display values.
Out[18]:
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 GBP NaT NaT 2023-01-17 None NaN -1000000.00 1.00 NaN NaN 1000000.00 998832.38 1.25 1248540.48 None
1 FloatPeriod Regular GBP 2023-01-17 2023-04-17 2023-04-19 act365f 0.25 1000000.00 0.99 3.12 6.44 -7697.66 -7629.87 1.25 -9537.34 None
2 FloatPeriod Regular GBP 2023-04-17 2023-07-17 2023-07-19 act365f 0.25 1000000.00 0.98 3.12 6.44 -7783.51 -7656.60 1.25 -9570.75 None
3 FloatPeriod Regular GBP 2023-07-17 2023-10-16 2023-10-18 act365f 0.25 1000000.00 0.98 3.12 6.44 -7783.51 -7598.67 1.25 -9498.34 None
4 Cashflow Exchange GBP NaT NaT 2023-10-16 None NaN 1000000.00 0.98 NaN NaN -1000000.00 -976415.89 1.25 -1220519.86 None
leg2 0 Cashflow Exchange USD NaT NaT 2023-01-17 None NaN 1200000.00 1.00 1.20 NaN -1200000.00 -1198598.86 1.25 -1498248.58 None
1 FloatPeriod Regular USD 2023-01-17 2023-04-17 2023-04-19 act360 0.25 -1200000.00 0.99 3.06 0.00 9172.16 9091.39 1.25 11364.23 None
2 Cashflow Mtm USD NaT NaT 2023-04-17 None NaN 10000.00 0.99 1.21 NaN -10000.00 -9913.59 1.25 -12391.98 None
3 FloatPeriod Regular USD 2023-04-17 2023-07-17 2023-07-19 act360 0.25 -1210000.00 0.98 3.06 0.00 9351.75 9199.27 1.25 11499.08 None
4 Cashflow Mtm USD NaT NaT 2023-07-17 None NaN 30000.00 0.98 1.24 NaN -30000.00 -29515.77 1.25 -36894.71 None
5 FloatPeriod Regular USD 2023-07-17 2023-10-16 2023-10-18 act360 0.25 -1240000.00 0.98 3.06 0.00 9583.61 9356.03 1.25 11695.04 None
6 Cashflow Exchange USD NaT NaT 2023-10-16 None NaN -1240000.00 0.98 1.24 NaN 1240000.00 1210755.70 1.25 1513444.63 None
Note how the rate for initial exchange is 1.20 (and not 1.19) and the MTM payments are 1.21 and 1.24, as expected.