Chapter 5, part 5 of 5: Model example
Hello everybody.
This is the final post in a series of five covering the newly written chapter 5 of my book. The previous posts are here, here, here and here. I’ll be grateful for any feedback.
As I publish this, I’m in London for my Introduction to QuantLib Development course. Drop me a line if you want to be notified when a new one is scheduled; my contact info is in the About page.
Follow me on Twitter if you want to be notified of new posts, or add me to your circles, or subscribe via RSS: the buttons for that are in the footer. Also, make sure to check my Training page.
Parameterized models and calibration
Example: the Heston model, continued
Time for the second part of the example I started in this post. The code for
the HestonModel
class is shown in listing 5.7.
Listing 5.7: Implementation of the HestonModel
class.
As you might know, the model has five parameters theta, kappa, sigma,
rho and v0. The process it describes for its underlying also depends
on the risk-free rate, its current value, and possibly a dividend
yield. For reasons that will become more clear in chapter 6, the
library groups all of those in a separate HestonProcess
class (for
brevity, I’m not showing its interface here; we’re just using it as
the container for the model parameters).
The HestonModel
constructor takes an instance of the process class,
stores it, and defines the parameters to calibrate. First it passes
their number (5) to its base class constructor, then it builds each of
them. They are all constant parameters; rho is constrained to be
between -1 and 1, while the others must all be positive. Their initial
values are taken from the process. The class defines the inspectors
theta
, kappa
, sigma
, rho
and v0
to retrieve their current
values; each of them returns the value of the corresponding
Parameter
instance at time t=0 (which is as good as any other time,
since the parameters are constant).
After the parameters are built, the generateArguments
method is
called. This will also be called each time the parameters change
during calibration, and replaces the stored process instance with
another one containing the same term structures and quote as the old
one but with the new parameters. The reason for this is that the new
process would be ready if any engine were to require it from the
model; but I wonder if the process
inspector should not build the
process on demand instead. If the actual process is not required
except as a holder of parameters and curves, we could define
inspectors for all of them instead, have the engine use them directly,
and save ourselves the creation of a new complex object at each step
of the calibration. You’re welcome to do the experiment and time the
new implementation against the current one.
Finally, the constructor registers with the relevant observables. The
process instance will be replaced by generateArguments
, so there’s
no point in registering with it. Instead, we register directly with
the contained handles, that will be moved inside each new process
instance.
Together with the inspectors I already mentioned, this completes the
implementation of the model. The calibration machinery is inherited
from the CalibratedModel
class, and the only thing that’s needed to
make it work is an engine that takes a HestonModel
instance and uses
it to price the VanillaOption
instances contained in the calibration
helpers.
You’ll forgive me for not showing here the AnalyticHestonEngine
class provided by QuantLib: it implements a closed formula for
European options under the Heston model, cites as many as five papers
and books in its comments, and goes on for about 650 lines of
code. For the non mathematically-minded, it is Cthulhu fhtagn
stuff. If you’re interested, the full code is available in the
library.