F# and QuantLib: An Introduction

F# and QuantLib: An Introduction

Rate This
  • Comments 4

Further information on the F# Community can be found at fsharp.org 

A Guest Blog in conjunction with Alexandre Radicchi (alex.radi@gmail.com)

F# is an attractive language to use in Financial Engineering because of its functional-first methodology, succinctness, strong typing, data-integration, stability, maturity, tooling and performance, as well as its supported editions in Visual Studio, its open-source edition, its cross-platform execution and its widespread availability. You can learn more about using F# for Financial Engineering through the excellent tutorials on Try F#.

QuantLib represents a unique project in the Financial Engineering panorama because of its maturity and of the vast quantity of tools implemented, all for free. In many situations it represents a sensible choice especially when starting a new project from scratch.  QuantLib is written in C++ but wrappers to many other languages exist. You can take a look at the project home page for further information. The majority of these wrappers are implemented using SWIG.

This blog post explores how to use F# in conjunction with QuantLib.

Preparing to access QuantLib

To access QuantLib on Windows we need two DLLs: NQuantLib.dll (a .NET component) and NQuantLibc.dll (a native component). If working in a financial institution these may already be available to you. If not, the native component is built from .lib files, in turn built from C++ source and C++ header files:

  • Install Boost to get the .lib and header files Boost (or build the source in the official repositories for Boost or BoostPro).
  • Get and build QuantLib  to build the .lib and header files for QuantLib (With VS2012, see these instructions, and reportedly you may need this fix to auto_link.hpp, see also the comment from pmcs below).
  • Download the QuantLib-SWIG zip file from the official repository (browse to the *other languages* directory on the QuantLib sourceforge repository).
  • Download SWIG and setup your environment so that the swig executable is visible.
  • Run the swig.cmd file located on the QuantLib-SWIG\CSharp directory. This will generate the C++ wrapper file.
  • Build NQuantLibc.dll and NQuantLib.dll using the given Visual Studio project.

Once done, place the NQuantLib.dll and NQuantLibc.dll in a directory under your F# scripting directory called references. If using a project then add NQuantLibc.dll as a file to the project and set to "Copy to Output" to "Copy if Newer"

The steps are slightly different if you need to compile for Mono. The following these steps targets Ubuntu/Linux:

  • Download Boost, compile and install it (./configure && make && sudo make install) or install it from package (e.g. sudo apt-get install libboost).
  • Install Swig using the package manager (sudo apt-get install swig) or download, compile and install it from sources.
  • Download QuantLib has seen before, uncompress it and launch ./configure && make && sudo make install.
  • Download QuantLib-SWIG, uncompress it and launch ./configure && make -C CSharp && sudo make install.
  • At this point you will end up with two libraries, the unmanaged one libNQuantLibc.so and the Mono wrapper NQuantLib.dll. As with the Windows libraries the managed extension must be able to invoke the unmanaged library.

Now let's F# QuantLib

Let's now compute something with our freshly compiled NQuantLib.dll.

We start by doing some F# scriptin from Visual Studio (or MonoDevelop, or Xamarin Studio, or whatever text editor you want).

When using F# Interactive you may need to set Tools --> Options --> F# Tools --> F# Interactive --> 64-bit --> False, or else build a 64-bit version of QuantLib.

In this first example we will create a simple QuantLib Date object containing the today's date and send its ISO string representation to the standard output.

#I "references"

#r "NQuantLib.dll"

let date = QuantLib.Date.todaysDate()

printfn "today is: %s" (date.ISO())

The output of this function on the fsharp interactive console is:

today is: 2013-03-24

Example 2: Pricing a Strip of European Call Options

In the next example we write a more financially meaningful example by computing the prices of a strip of European Call options. First of all, we define a series of hypothetical market observables (the underlying asset spot price, its implied volatility,  a reference risk-free rate and a flat dividend yield) and then instantiate, for each strike, a *PlainVanillaPayoff* and a *BlackCalculator*. Then we call the *value* method which returns the price of each option.

open QuantLib

let T = 3.0

let r, divYield, vol = 0.01, 0.03, 0.5

let stdev = vol* sqrt T

let discount = exp (-r*T)

let spot = 100.0

let forward = spot * exp ((r-divYield)*T)

let strikes = [|10.0..10.0..200.0|]

for strike in strikes do

    use payoff = new PlainVanillaPayoff(Option.Type.Call,strike)

    use bcalculator = new BlackCalculator(payoff,forward,stdev,discount)

    printfn "strike: %.5f, price: %.5f" strike (bcalculator.value())

The output of this script is:

    strike: 10.0, price: 81.72475

    strike: 20.0, price: 72.48247

    strike: 30.0, price: 64.10232

    strike: 40.0, price: 56.71391

    strike: 50.0, price: 50.27881

    strike: 60.0, price: 44.69816

    strike: 70.0, price: 39.86036

    strike: 80.0, price: 35.65964

    strike: 90.0, price: 32.00237

    strike: 100.0, price: 28.80815

    strike: 110.0, price: 26.00889

    strike: 120.0, price: 23.54731

    strike: 130.0, price: 21.37533

    strike: 140.0, price: 19.45254

    strike: 150.0, price: 17.74493

    strike: 160.0, price: 16.22378

    strike: 170.0, price: 14.86477

    strike: 180.0, price: 13.64725

    strike: 190.0, price: 12.55360

    strike: 200.0, price: 11.56872

This example is a simplification of reality in which we would use more complex structures such as:

  • yield curves instead of flat yield/dividend rates;
  • volatility surfaces instead of flat volatility value;
  • multi-payment or Bermudian payoffs;
  • multi-factorial models, and so on.

A lot of these features are already implemented into QuantLib and many of them are accessible through the .NET wrapper. See the reference manual for a full list of functionalities. You can also take a look at the Book which is a work in progress.

Example 3: Dates and Schedules

As a third example we use the Schedule class which, given a set of rules and a calendar, generates a list of dates. In this particular example, we tell Schedule to generate the set of dates starting from 2012-1-1 ending 3 years later with a 3 month interval. The dates are rolled forward if they corresponds to non-business days on the Target calendar.

First we add an extension member to act as a helper when converting dates:

open System

[<AutoOpen>]

module Conversion =

    type DateTime with

       member dt.AsQL = new Date(dt.ToOADate() |> int)

Now we set up our Schedule:

let today = new DateTime(2012,1,1)

let startdate = today.AsQL

let enddate = today.AddYears(3).AsQL

let tenor = new QuantLib.Period("3M")

let convention = QuantLib.BusinessDayConvention.ModifiedFollowing

let termination = convention

let eomonth = false

let scheduler = new QuantLib.Schedule(startdate,

                            enddate,tenor,new QuantLib.TARGET(),

                            convention,termination,

                            QuantLib.DateGeneration.Rule.Forward,

                            eomonth)

for i in [0u..scheduler.size()-1u] do

    printfn "date.[%d] = %s" i <| scheduler.date(i).ISO()

The output of this script is

    date.[0] = 2012-01-02

    date.[1] = 2012-04-02

    date.[2] = 2012-07-02

    date.[3] = 2012-10-01

    date.[4] = 2013-01-02

    date.[5] = 2013-04-02

    date.[6] = 2013-07-01

    date.[7] = 2013-10-01

    date.[8] = 2014-01-02

    date.[9] = 2014-04-01

    date.[10] = 2014-07-01

    date.[11] = 2014-10-01

    date.[12] = 2015-01-02

Using 'use'

Because QuantLib objects are generally native objects, you may need to use 'use' to ensure correct deterministic disposal of these objects. This doesn't apply so much to data scripting but more in project files. For example inside a function do this:

use date = QuantLib.Date.todaysDate()

Exploring Further

QuantLib contains a very large amount of functionality. An idea of the range of functionality can be seen from the following prefix of the tests run when building QuantLib. To explore further, see the reference manual for a full list of functionalities or the Book.

14>  Testing Barone-Adesi and Whaley approximation for American options...

14>  Testing Bjerksund and Stensland approximation for American options...

14>  Testing Ju approximation for American options...

14>  Testing finite-difference engine for American options...

14>  Testing finite-differences American option greeks...

14>  Testing finite-differences shout option greeks...

14>  Testing array construction...

14>  Testing analytic continuous geometric average-price Asians...

14>  Testing analytic continuous geometric average-price Asian greeks...

14>  Testing analytic discrete geometric average-price Asians...

14>  Testing analytic discrete geometric average-strike Asians...

14>  Testing Monte Carlo discrete geometric average-price Asians...

14>  Testing Monte Carlo discrete arithmetic average-price Asians...

14>  Testing Monte Carlo discrete arithmetic average-strike Asians...

14>  Testing discrete-averaging geometric Asian greeks...

...

Summary

 

In summary, using F# with QuantLib is straight-forward once QuantLib is installed.

  • QuantLib is the most advanced open source library for Financial Engineering;
  • Interfacing it with F# is quite easy;
  • We can potentially extend the set of exposed classes through SWIG;
  • F# is well fitted for Financial applications.

Along the way, some routine code has to be written to instantiate QuantLib classes.

We hope you enjoy using F# with QuantLib. If you are interested in connecting with other users of this combination, please email Alexandre, join the QuantLib group and/or the F# Software Foundation and associated community groups.

Don Syme and Alexandre Radicchi

 

Leave a Comment
  • Please add 2 and 7 and type the answer here:
  • Post
  • .NET as an excellent mean of allowing "foreign" library to be wrapped and used in CLR (usually I think C# is excellent for this task).

    The fact that F# is a first citizen of .NET platform open an entirely new world of possibilities.

    You can consume this libraries through the wrapper and experiment the object model with easy using F# Interactive.

    There's no doubt that F# will have shiny future!

    Excellent post.

  • Some points to bear in mind if you find yourself trying this out with Visual Studio 2012:

    1) The latest release version of QuantLib (1.2.1) doesn't include project files for Visual Studio 2012. Although VS2012 will automatically upgrade the supplied project files without trouble, QuantLib itself contains some macros that hard-code Visual Studio version numbers. These will give you some trouble if you attempt to build against the library, so it's best to fix them.

    2) Assuming that %QL_DIR% points to the base QuantLib directory, the macros you'll need to change are located in %QL_DIR%\ql\auto_link.hpp.

    3) Open auto_link.hpp and find the following lines:

    #else

    #  error "unknown Microsoft compiler"

    Insert the following just before those lines:

    #elif (_MSC_VER == 1700)

    #  define QL_LIB_TOOLSET "vc110"

    4) In Visual Studio, right-click on the QuantLib project and select Properties. In Configuration Properties -> General, change the Target Name to QuantLib-vc110-mt or QuantLib-vc110-mt-gd, depending on whether you're building release or debug versions of QuantLib.

    You should now be good to build the SWIG wrappers and dig into QuantLib from F#.

  • One thing I've been thinking about of late is how to mix the imperative design of QuantLib (some global state, events) with the functional nature of F# (in which, however, I only started dabbling).  Do you have any experience to share?

  • There is a yield method in FixedRateBond class. How do I call it in F#? I kept getting the following error:

    stdin(32,14): error FS0599: Missing qualification after '.'

Page 1 of 1 (4 items)