A DiversionIn 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:
The R PackageThe 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 )
This displays this curve:
F# using DeedleIn 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()..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 =
fBase(t) + t(KernelWeights) %*% fCompoundKernel(t)
CashflowMatrix %*% fKernel(t, TimesVector)
 "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 =  0.8850041
In the next post, I will explore converting the underlying R code to F#.