Implementation of the SmithWilson yield curve fitting algorithm in Python for interpolations and extrapolations of zerocoupon bond rates
Project description
smithwilson
Overview
This Python package implements the SmithWilson yield curve fitting algorithm. It allows for interpolations and extrapolations of zerocoupon bond rates. This algorithm is used for the extrapolation of EIOPA riskfree term structures in the Solvency II framework. Details are available in the Technical Paper QIS 5 Riskfree interest rates. Examples of extrapolated yield curves including the parameters applied can be found here.
How to use the package

Install the package with
pip install smithwilson

To use the SmithWilson fitting algorithm, first import the Python package and specify the inputs. In the example below the inputs are zerocoupon rates with annual frequency up until year 25. The UFR is 2.9% and the convergence parameter alpha is 0.128562. The
terms
list defines the list of maturities, in this case[1.0, 2.0, 3.0, ..., 25.0]
import smithwilson as sw # Input  Switzerland EIOPA spot rates with LLP of 25 years # Source: https://eiopa.europa.eu/Publications/Standards/EIOPA_RFR_20190531.zip # EIOPA_RFR_20190531_Term_Structures.xlsx; Tab: RFR_spot_no_VA rates = [0.00803, 0.00814, 0.00778, 0.00725, 0.00652, 0.00565, 0.0048, 0.00391, 0.00313, 0.00214, 0.0014, 0.00067, 0.00008, 0.00051, 0.00108, 0.00157, 0.00197, 0.00228, 0.0025, 0.00264, 0.00271, 0.00274, 0.0028, 0.00291, 0.00309] terms = [float(y + 1) for y in range(len(rates))] # [1.0, 2.0, ..., 25.0] ufr = 0.029 alpha = 0.128562

Specify the targeted output maturities. This is the set of terms you want to get rates fitted by SmithWilson. Expand the set of rates beyond the Last Liquid Point (e.g. extrapolate to 150 years with annual frequency):
# Extrapolate to 150 years terms_target = [float(y + 1) for y in range(150)] # [1.0, 2.0, ..., 150.0]
Alternatively, you can retrieve a different frequency (e.g. interpolate quarterly instead of annual):
# Interpolate to quarterly granularity terms_target = [float(y + 1) / 4 for y in range(25*4)] # [0.25, 0.5, ..., 25.0]
A combination of interpolation & extrapolation is possible, too. Same for sets of arbitrary maturities:
# Get rates for a wellspecified set of maturities only terms_target = [0.25, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0]

Call the SmiwthWilson fitting algorithm. This returns the rates as numpy vector with each element corresponding to the maturity in
terms_target
# Calculate fitted rates based on actual observations and two parametes alpha & UFR fitted_rates = sw.fit_smithwilson_rates(rates_obs=rates, t_obs=terms, t_target=terms_target, ufr=ufr, alpha=alpha) # Optional
The convergence parameter alpha is optional and will be estimated if not provided. The parameter determines the convergence speed of the yield curve towards the Ultimate Forward Rate (UFR). The parameter is estimated by finding the smallest value such that the difference between forward rate at convergence maturity and UFR is smaller than 1bps.

To display the results and/or processing them it can be useful to turn them into a table, here using the pandas library:
# Ensure pandas package is imported import pandas as pd # ... # Turn inputs & outputs into dataframe observed_df = pd.DataFrame(data=rates, index=terms, columns=["observed"]) extrapolated_df = pd.DataFrame(data=fitted_rates, index=terms_target, columns=["extrapolated"]) # Combine and print dataframe print(observed_df.join(extrapolated_df, how="outer"))
A complete example can be found in main.py
Algorithm
The algorithm is fully vectorized and uses numpy, making it very performant. The code is in core.py.
The function fit_smithwilson_rates()
expects following parameters:
 Observed rates
 Observed maturities
 Target maturities
 Convergence parameter alpha
 Ultimate forward rate (UFR)
The observed rates and maturities are assumed to be before the Last Liquid Point (LLP). The targeted maturity vector can
contain any set of maturities (e.g. more granular maturity structure (interpolation) or terms after the LLP (extrapolation)).
The SmithWilson fitting algorithm calculates first the Wilsonmatrix (EIOPA, 2010, p. 16):
W = e^(UFR * (t1 + t2)) * (α * min(t1, t2)  0.5 * e^(α * max(t1, t2))
* (e^(α * min(t1, t2))  e^(α * min(t1, t2))))
Given the Wilsonmatrix W
, vector of UFR discount factors μ
and prices P
, the parameter vector ζ
can be calculated as follows (EIOPA, 2010, p.17):
ζ = W^1 * (μ  P)
With the SmithWilson parameter ζ
and Wilsonmatrix W
, the zerocoupon bond prices can be represented as (EIOPA, 2010, p. 18) in matrix notation:
P = e^(t * UFR)  W * ζ
In the last case, t
can be any maturity vector, i.e. with additional maturities to extrapolate rates.
Sources
EIOPA (2010). QIS 5 Technical Paper; Riskfree interest rates – Extrapolation method; p.11ff
Project details
Release history Release notifications  RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for smithwilson0.2.0py3noneany.whl
Algorithm  Hash digest  

SHA256  b554f1c44db559071654eca04cf15311acf2cab8334304d958fc24ce167cd559 

MD5  605dd3e281402700d11bcc739ae4411f 

BLAKE2b256  f3ec540f106648ec92e5169bc760e5a45ecb3ae577f918caa01afcb4da8d734b 