Skip to main content

Implementation of the Smith-Wilson yield curve fitting algorithm in Python for interpolations and extrapolations of zero-coupon bond rates

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smithwilson-0.2.0.tar.gz (11.1 kB view details)

Uploaded Source

Built Distribution

smithwilson-0.2.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file smithwilson-0.2.0.tar.gz.

File metadata

  • Download URL: smithwilson-0.2.0.tar.gz
  • Upload date:
  • Size: 11.1 kB
  • Tags: Source
  • Uploaded using 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

File hashes

Hashes for smithwilson-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9acacf6cac7080c221518e20511bf415ebd213cfe63f42943b4fa0654f042971
MD5 d418984f1ce75662dea2201ee92c9b9d
BLAKE2b-256 08c0198a1bff975b03eccea4d2fab4ca4d34570f2dcd170e0a48fdd3fb87ab1e

See more details on using hashes here.

File details

Details for the file smithwilson-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: smithwilson-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using 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

File hashes

Hashes for smithwilson-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b554f1c44db559071654eca04cf15311acf2cab8334304d958fc24ce167cd559
MD5 605dd3e281402700d11bcc739ae4411f
BLAKE2b-256 f3ec540f106648ec92e5169bc760e5a45ecb3ae577f918caa01afcb4da8d734b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page