The roots of the MPI specification are going back to the early 90’s and you will feel the age if you use the C-API, which is designed to achieve maximum performance. The Boost.MPI library – quoting from the web page – “is a C++ friendly interface to the standard Message Passing Interface… Boost.MPI can build MPI data types for user-defined types using the Boost.Serialization library”.
Model calibration can be a very time-consuming task, e.g. the calibration of a Heston or a Heston-Hull-White model using American puts with discrete dividends. The class MPICalibrationHelper acts as a MPI wrapper for a given CalibrationHelper and allows to parallelize an existing model calibration routine (hopefully with minimal impact/effort). The source code is available here. It contains the MPICalibrationHelper class and as an example the parallel version of the DAXCalibration test case (part of test-suite/hestonmodel.cpp). The code depends on QuantLib 1.0 or higher, Boost.Thread and Boost.MPI.
The diagram above shows the speed-up of a Heston-Hull-White calibration with discrete dividends on an eight core machine using a finite difference pricing engine. The main reason for the sub-linear scaling is the limited memory bandwidth between the CPUs and the main memory and not the MPI communication overhead.
The CUDA based GPU implementation is available here. It depends on the latest QuantLib version from the SVN trunk or the upcoming QuantLib 1.2 release and CUDA 4.0. The corresponding C++ implementation is a speed-optimized version of the test-case VPPTest::testVPPPricing. This version also supports multi-threading. The following hardware was used to compare both implementations:
As can be seen in the diagram below the GPU outperforms the CPU roughly by a factor 100 for single precision and a factor of 50 if the GPU is using double precision.
The CUDA implementation consists of the following files:
gpuvpppricingengine.hpp / gpuvpppricingengine.cpp
A QuantLib pricing engine for a simple VPP based on a Monte-Carlo simulation and perfect foresight optimization via dynamic programming. The physical size of the Monte-Carlo simulation is controlled by the following parameters of the constructor
gpuvpppricingengine_kernel.hpp
gpuvpppricingengine_kernel.cu/ gpuvpppricingengine_kernel.def
The CUDA implementation consists of two kernels. The first kernel is the Monte-Carlo path generator, which calculates the paths on hourly granularity and stores them in the global memory of the graphic card.. The technics used are outlined e.g. in [2], [3] and [4]. The second kernel performs the optimization of the load schedule based on dynamic programming. The memory layout of this step depends on the number of possible states of the VPP because every possible state is stored in the shared memory of the GPU. The number of states is given by . CUDA does not support efficient dynamic shared memory allocation. Therefore the sizes of all shared memory arrays must be given at compile time. To allow an optimal use of the limited shared memory capacity different kernels with different
values are generated using X-macros and the appropriate kernel is chosen at runtime.
cudatype.hpp
defines basic CUDA types, especially the typedef for the type “real” can be used to compile the code either for single or double precision.
gpurand.hpp
C++ interface for a GPU random number generator
gpucurand.hpp / gpucurand.cpp / gpucurand_kernel.hpp / gpucurand_kernel.cu
implementation of the GPURand interface based on the CURAND library, which is part of CUDA 4.0.
[1] this blog, VPP Pricing III: Exact Pricing based on Finite Difference Methods.
[2] L. Howes, D. Thomas, Efficient Random Number Generation and Application Using CUDA.
[3] A. Bernemann, R. Schreyer, K. Spanderen, Accelerating Exotic Option Pricing and Model Calibration Using GPUs
[4] M. Joshi, Graphical Asian Options
]]>The focus is on the finite difference method, which involves solving the three-dimensional partial integro differential equation
An additional fourth dimension is needed to keep track of the different states of the VPP. Based on the characteristics of the VPP type outlined in the article VPP Pricing II: Mixed Integer Linear Programming a VPP with three possible load levels has
different states.
Pricing via Monte-Carlo and perfect foresight involves simulating the stochastic process
and optimize the power plant load schedule for each path separately in the same way the intrinsic value is calculated. This procedure will result in an upper bound for the exact price of the VPP. The prices for a 4 weeks VPP contract based on this two methods and with the parameters outlined in VPP Pricing II show almost no differences between the “exact” finite difference method and the perfect foresight upper bound value beside the Monte-Carlo error (s. diagram below, compare with [1]).
The size of the lattice for the finite difference method was
.
The code is available here. It depends on the latest QuantLib version from the SVN trunk or the upcoming QuantLib 1.2 release. If you want to generate the plot you’ll also need R
[1] H. van Dijken, D. van Abbena, H.S. Los, C. de Jong, The value of starting up the power plant.
]]>The set-up of the simplified gas-run power plant is similar to the one explained in chapter 4.2.3 of the text-book [1]. In general the power plant has three power output level:
The power plant has a fixed efficiency rate
.
Ramp rates will be neglected, but the power plant has a minimum uptime and a minimum downtime
. The start-up costs are given by a fixed start-up cost
(in €) and the price of the gas needed to produce the start-up heat
(in MWh).
The mixed integer linear optimization is running in one hour blocks and is using three decision variables per hour . The binary decision variable
is true if the power plant is running at minimum load
or at maximum load
and
is false if the plant is off. The real decision variable
is equal to one if the plant is started in hour
, which is implied by the following constraint
.
The minimum up-time and the minimum down-time
is a consequence of the constraints
The real decision variable is equal to one if the power plant is running at maximum load
and zero if the power plant is either running at minimum load
or if the plant is off, that means
Let be the power price,
be the gas price and
be the carbon dioxide price at hour
. The objective function is then given by
For a one year span the problem consists of decision variables
and
constraints. This comparable small problem can be solved using e.g. the Gnu Linear Programming Kit (GLPK). For an overview on open source linear/mixed integer programming solver see [2].
The model parameters and the example forward curves are outlined in the previous entry VPP Pricing I. The diagram below shows the intrinsic value and the upper bound for the total value (intrinsic plus extrinsic value) based on Monte-Carlo, perfect foresight and MIP for different power plant efficiencies . The parameters of the VPP contract are given by
,
the (fixed) carbon dioxide price is 3.0€ per MWh heat.

The source code is available here. It depends on GLPK and the latest QuantLib version from the SVN trunk or the next QuantLib 1.2 release.
It is now quite easy to add and price time-integral constraints, e.g. the following constraint restricts the number of starts within a year to be less than or equal to a given number
.
The following diagram shows the results for and a minimum load
.
The source code is available here. It depends on QuantLib 1.1 and if you want to generate the plot directly from the C++ program you’ll also need R, RCPP and RInside.
[1] M. Burger, B. Graeber, G. Schindlmayr, Managing Energy Risk, ISDN 978-0-470-ß2962-6
[2] S. R. Thorncraft, Evaluation of Open-Source LP Optimization Codes in Solving Electricity Spot Market Optimization Problems.
]]>With maturity of twelve weeks the example swing option provides exercise opportunities. The number of overall exercised swing opportunities is constraint by
.
The size of two dimensions of the finite difference method (dynamic programming) is therefore already been given. 2016 steps are needed in time direction and 500 steps are needed in the “consumed exercises” direction. Together with the two other directions – one for the power price and one dimension for the jump process – and without further simplidsfications this forms a pretty large finite difference problem. The Monte-Carlo based linear programming approach reduces the computational burden but will lead to an upper bound of the swing option price. The diagram below shows the corresponding results.
The code is available here. It depends on the GNU Linear Programming Kit, the Boost Thread library for parallelization and at the time of writing on the latest QuantLib version from the SVN trunk. If you want to generate the plot directly out of the C++ program you also need R, RCPP and RInside. To utilize all CPU cores please use the -DNTHREADS=(number of CPU cores) compiler switch. In addition to run the program you have to download the forward curve German power from the Kyos web page and convert it into a text file EEX_2010-2013.txt of the folliwing format
4-Oct-2010 36.73 32.09 27.32 23.22 25.71 35.60 47.32 …
5-Oct-2010 38.12 31.12 22.76 25.65 27.87 34.60 50.01 …
[1] T. Kluge, Pricing Swing Options and other Electricity Derivatives
]]>A basic payoff structure is e.g.: On the exercise dates the decision variables
indicate whether to exercise
or not to exercise
the option at a given point
in time. Payoff is either
for a call or
for a put option. Here
is the strike price and
is the spot price . The number of exercise opportunities is constraint by
.
The price of a swing call option is then given by
Let the dynamics of the spot price in the risk neutral measure be given by the Kluge model [2]:
This model is composed of an Ornstein-Uhlenbeck (OU) process , a deterministic period function
characterizing the seasonality and a mean reverting process
with jumps to incorporate spikes.
is a Poisson process with jump intensity
and the jump size itself is exponentially distributed. The random variables
and
are independent. The Monte-Carlo path simulation will be built on top of standard components for an OU process and a Poisson jump-diffusion process [3]. The dynamic programming approach can either be carried out using least squares Monte-Carlo ansatz (Longstaff Schwartz algorithm) or using finite difference methods. We prefer finite difference methods to avoid e.g. the problem of choosing an appropriate basis function set. The Feynman-Kac theorem leads to the corresponding partial integro differential equation (PIDE):
A Gauss-Laguerre quadrature is appropriate to calculate the integral part of the PIDE. Beside this two-dimensional PIDE an additional dimension is needed to keep track of the already consumed exercise rights. The three-dimensional formulation together with Bellman’s principle of optimality transforms the global optimization problem into a local optimization problem.
Target of the linear programming approach is the upper bound
The linear programming algorithm will calculate the optimal exercise strategy on each Monte-Carlo path separately (perfect foresight) with respect to the given constraints. For this basic type of swing option linear programming is sort of over-engineering because a simple sort algorithm will also reproduce the optimal exercise strategy. But introducing linear programming and mixed integer programming now will enable us later on to deal with more complicated time-integral constraints. Libraries for this task are freely available, e.g. the GNU Linear Programming Kit.
The test parameterization of the model is
,
the example swing call option has maturity of one year, strike price is equal 40, one exercise opportunity per month and the minimum number of exercise rights is equal to the maximum number of exercise rights, . Interest rates are at
.
As the diagram above shows for this set-up the upper bound for the swing option price calculated using linear programming differs significantly from the correct price calculated based on dynamic programming on a lattice. For twelve exercise rights both algorithms have to provide the same results because the constraint forces to always exercise on each exercise date. Next to come is to rerun the simulation with a more realistic forward curve and process parameters.
The code is available here. It depends on the GNU Linear Programming Kit, the Boost Thread library for parallelization and at the time of writing on the latest QuantLib version from the SVN trunk. If you want to generate the plot directly out of the C++ program you also need R, RCPP and RInside.
[1] M. Burger, B. Graeber, G. Schindlmayr, Managing Energy Risk, ISDN 978-0-470-ß2962-6
[2] T. Kluge, Pricing Swing Options and other Electricity Derivatives
[3] P. Glasserman, Monte Carlo Methods in Financial Engineering. ISBN-0387004513
]]>The parameter set is supposed to be piecewise constant in time. This model has a semi-closed solution for plain vanilla European put/call options based on the characteristic function method [1].
The DAX implied volatility surface based on July 5, 2002 data taken from [2] defines the “benchmark” calibration problem. The benchmark model parameters for the optimization problem are given by
.
The non-linear least square optimization problem is defined by the goodness of fit measure
where is the market implied volatility for strike K and maturity T and
is the corresponding Black-Scholes volatility implied from the model price. The optimal solution for this problem is
leading to a goodness of fit measure of (Please keep in mind that this result is the outcome of a naive calibration procedure. Due to the large
and
values I’d not use these parameters to price a derivative.).

The diagram above shows the “goodness of fit”-surface for the parameter sets in
To be able to compare a larger number of deterministic optimizers the model calibration will be carried out using R and with help of the additional packages minpack.lm and minqa.
Non-linear Least Square Optimization:
Non-linear (trusted region) Minimization:
The particular result dependents on the starting vector but the following diagram shows a common outcome.

The best methods are the non-linear least square algorithms nls.lm and nls followed by nl2sol. Algorithms not included in the diagram have performed even worse than “nm” for this problem.
The goodness of fit measure is calculated in C++ based on the QuantLib and exposed to R using RCPP. The C++ code and the R scripts to perform the optimizations and to create the plots can be found here.
1] A. Elices, Models with time-dependent parameters using transform methods: application to Heston’s model,
]]>