F# and QuantLib: An Introduction
Further information on the F# Community can be found at fsharp.org
A Guest Blog in conjunction with Alexandre Radicchi (firstname.lastname@example.org)
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-SWIGCSharp 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.
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.
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:
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,
for i in [0u..scheduler.size()-1u] do
printfn “date.[%d] = %s” i <| scheduler.date(i).ISO()
The output of this script is
date. = 2012-01-02
date. = 2012-04-02
date. = 2012-07-02
date. = 2012-10-01
date. = 2013-01-02
date. = 2013-04-02
date. = 2013-07-01
date. = 2013-10-01
date. = 2014-01-02
date. = 2014-04-01
date. = 2014-07-01
date. = 2014-10-01
date. = 2015-01-02
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()
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…
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