Friday, 14 March 2014

Smith Wilson and Deedle

A Diversion

In this post, I am taking a brief detour into the asset side of actuarial modelling. This is definitely not my area of expertise, but fortunately I know some experts who are happy to give me a hand.

For this post I am going to look at the Smith-Wilson method of curve fitting. This was the method preferred under QIS5 for interpolating and extrapolating interest rate curves - see http://eiopa.europa.eu/fileadmin/tx_dam/files/consultations/QIS/QIS5/ceiops-paper-extrapolation-risk-free-rates_en-20100802.pdf.
(This method was proposed in one of the earlier publications jointly authored by the amazing Andrew Smith - http://www.theactuary.com/features/2012/12/dare-to-be-different/).

I have had a lot of help from an ex-colleague and expert in this field, Phil Joubert. Phil writes a very interesting blog at http://www.not-normal-consulting.co.uk/. He has written a CRAN R package to carry out this curve fitting, which is documented in two of his blogs:
In this post, I will initially run this R package using RStudio and then use F# to host the package using Deedle and the R Type Provider.

The R Package

The R Package is called "SmithWilsonYieldCurve". Once installed, you have access to a number of functions. The most straightforward to use is fFitSmithWilsonYieldCurveToInstruments. This is described as "A convenience function that takes a dataframe containing market instrument data as type, tenor, frequency and rate. It extracts the required vectors and matrices and then calls fFitSmithWilsonYieldCurve."

To illustrate usage, I will use code that replicates results from a QIS5 Example - see page 24 of the paper mentioned above.

It is very straightforward to do this in R Studio, using the R Code shown below:

  library( "SmithWilsonYieldCurve" )
  InstrumentSet1 <- read.csv("InstrumentSet1.csv")
  ufr <- log( 1 + 0.042 )
  alpha <- 0.1
  Curve <- fFitSmithWilsonYieldCurveToInstruments(InstrumentSet1, ufr, alpha )
  plot(Curve)


This displays this curve:
You can also verify that this generates the expected example result by inspecting the value of Curve$P(4) which returns 0.8850041. (0.885 is the value in the QIS5 example).

F# using Deedle

In this post, I will limit myself to retaining the use of R for the calculations and plotting (I will revisit this in a later post). I will however use F# Interactive to host the code and use F# to call into R using the R Type Provider. I will also use Deedle, which provides a dataframe capability that is directly usable with R.

To access the supporting libraries it is easiest to use NuGet. You should select the Deedle package with the R Plugin. (Note that there seems an issue with the NuGet package - so you might need to make some manual changes - see this StackOverflow question).

Once you have this installed, you can reference the relevant libraries and very simply replicate the R calling code:
 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
#I "../packages/Deedle.0.9.12/"
#I "../packages/RProvider.1.0.5/"
#load "RProvider.fsx"
#load "Deedle.fsx"

open RProvider
open RDotNet
open Deedle
open RProvider.graphics
open RProvider.SmithWilsonYieldCurve
open RProvider.``base``

let InstrumentSet1 = Frame.ReadCsv("c:/temp/InstrumentSet1.csv")
let ufr = log( 1.0 + 0.042 )
let alpha = 0.1
let Curve = R.fFitSmithWilsonYieldCurveToInstruments(InstrumentSet1, ufr, alpha )
R.plot(Curve)
let Pfn = Curve.AsList().[0].AsFunction()
let ans  = R.sapply(R.c(4),Pfn)

(A copy of the InstrumentSet1.csv file can be downloaded from bitbucket.)

Lines 13 to 17 are virtually identical to the R code and generate exactly the same effect - R is called and displays the identical curve.

When you run this in F# interactive it also display the following output:

val InstrumentSet1 : Deedle.Frame<int,string> =
 
     Type Tenor Rate  Frequency
0 -> SWAP 1     0.01  1        
1 -> SWAP 2     0.02  1        
2 -> SWAP 3     0.026 1        
3 -> SWAP 5     0.034 1        

val ufr : float = 0.04114194333
val alpha : float = 0.1
val Curve : RDotNet.SymbolicExpression =
  $P
function (t)
{
    fBase(t) + t(KernelWeights) %*% fCompoundKernel(t)
}
<environment: 0x08cde364>

$xi
           [,1]
[1,]  57.790688
[2,] -33.507208
[3,]  11.396473
[4,]  -5.466968

$K
function (t)
{
    CashflowMatrix %*% fKernel(t, TimesVector)
}
<environment: 0x08cde364>

attr(,"class")
[1] "SmithWilsonYieldCurve" "YieldCurve"          


Notice that the dataframe InstrumentSet1 is displayed in a friendly format followed by the other function parameters: ufr and alpha

This is followed by a full display of the Curve object. This is a rather complex object, which is documented as "Objects of class SmithWilsonYieldCurve are a list, the first element of which is a function P(t), which returns the zero coupon bond price of the fitted curve at time t."

To obtain the test value for P in F#, we therefore, in line 18, convert the R SymbolicExpression to a List, take the first element and then convert this to a Function. We can then call this function, in line 19, using the R high level function sapply . In F# Interactive we then get:

val ans : SymbolicExpression = [1] 0.8850041

In the next post, I will explore converting the underlying R code to F#.

2 comments:

  1. Thanks a lot for this post. Could you please attach "InstrumentSet1.csv" to the blog so that we can try your example?

    ReplyDelete
    Replies
    1. Thanks very much for the interest in this post and sorry for not providing this file.

      There is a copy held on bitbucket at:
      https://bitbucket.org/pb_bwfc/blog/src/2a59bbc76c32f5270b43cf72f694121bce43b1b1/SmithWilsonR/InstrumentSet1.csv?at=default

      Delete