Skip to main content

smithwilson

Overview

This Python package implements the Smith-Wilson yield curve fitting algorithm. It allows for interpolations and extrapolations of zero-coupon bond rates. This algorithm is used for the extrapolation of EIOPA risk-free term structures in the Solvency II framework. Details are available in the Technical Paper QIS 5 Risk-free interest rates. Examples of extrapolated yield curves including the parameters applied can be found here.

How to use the package

  1. Install the package with pip install smithwilson

  2. To use the Smith-Wilson fitting algorithm, first import the Python package and specify the inputs. In the example below the inputs are zero-coupon 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
    
  3. Specify the targeted output maturities. This is the set of terms you want to get rates fitted by Smith-Wilson. 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 well-specified set of maturities only
    terms_target = [0.25, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0]
    
  4. Call the Smiwth-Wilson 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.

  5. 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 Smith-Wilson fitting algorithm calculates first the Wilson-matrix (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 Wilson-matrix 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 Smith-Wilson parameter ζ and Wilson-matrix W, the zero-coupon 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; Risk-free interest rates – Extrapolation method; p.11ff

EIOPA (2018). Technical documentation of the methodology to derive EIOPA’srisk-free interest rate term structures; p.37-46

Metadata

Release files for smithwilson 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for smithwilson 0.2.0
File Size Uploaded
smithwilson-0.2.0.tar.gz 11.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for smithwilson 0.2.0
File Interpreter ABI Platform
smithwilson-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.4 kB

Release files / smithwilson-0.2.0.tar.gz

Download URL smithwilson-0.2.0.tar.gz
Size 11.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9acacf6cac7080c221518e20511bf415ebd213cfe63f42943b4fa0654f042971
BLAKE2b-256 checksum
How to use checksums
08c0198a1bff975b03eccea4d2fab4ca4d34570f2dcd170e0a48fdd3fb87ab1e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.2

Release files / smithwilson-0.2.0-py3-none-any.whl

Download URL smithwilson-0.2.0-py3-none-any.whl
Size 10.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b554f1c44db559071654eca04cf15311acf2cab8334304d958fc24ce167cd559
BLAKE2b-256 checksum
How to use checksums
f3ec540f106648ec92e5169bc760e5a45ecb3ae577f918caa01afcb4da8d734b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.2

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page