Factoryised C++

In two of my most recent posts I’ve talked about Forward Contracts and an implementation of the Normal Quantile function. One strategic reason for this will become apparent from today’s post!

I’m going to be talking here about one of the design patterns used in the Monte Carlo code presented on my blog and discussed recently. It isn’t really my goal for this blog to dwell heavily on programming topics as there are many, many more competent people than me sharing their knowledge on the subject across the web. However, there are some topics that are quite interesting to discuss and make ideal blog topics, and a grounding in Object-Oriented programming (particularly in C++) is vital for the modern Quant.

As I stated before, the goal of the code presented to date in ‘Simple Option Pricer 1.0’ is to choose a fairly simple option payoff, choose a method for generating uniform random numbers, and then choose a method for generating gaussian variates from these (and of course to enter the relevant market parameters like discount factor and volatility). The first thing to do is to download all of the code presented on that page, compile it, and run it a few times to make sure you can get all of it to work. Check the answers correspond to the results you get from the analytical pricers for the same parameters, although don’t forget that there will be some Monte Carlo error on the answers coming for C++, and observe that answers get better (though time taken increases!) as the number of paths is increased.

A very straight-forward way of achieving selectivity would be to use a switch statement:

int option;
SimpleOption* theOptionPointer;

cout << "Select a Contract Type: Call [1], Put [2]";
cin >> option;

switch ( option ) {
 case 1 :
  theOptionPointer = new CallOption( ... );
  break;
 case 2 :
  theOptionPointer = new PutOption( ... );
  break;
 default :
  throw("You must enter [1] or [2]!");
}

where I’ve assumed that we’ve defined some suitable option classes elsewhere that all inherit from an abstract base class SimpleOption (if there is demand for it I might go over inheritance another time, but there are many sources on the web. This IS important for quants, but it’s rather dry to go over!).

The switch statement looks at the user-entered value and assigns the pointer to an option of the relevant type. This is a basic example of polymorphism – we’ve declared theOptionPointer to be a pointer to the abstract base class SimpleOption, but then given it the address of a specific implementation of the base class via a derived class, either CallOption or PutOption. If we were to call any functions of this pointer, they would have to be those functions defined in the base class itself (although they could be abstract and potentially over-loaded in the derived classes) – if, for example, CallOption had a method called getStrike(), there would need to be a [potentially abstract] prototype for this in the base class SimpleOption if we want to have access to it via the SimpleOption pointer..

However, the code isn’t that great as it stands. We’re going to need a switch statement for each of the choices we’re giving the user (currently Option type, RNG type and Gaussian converter type), which will lead to a bloated main(){} function. More annoyingly, every time we want to include a new option in any of these selections, as well as coding up the relevant classes for the new choice we’re going to need to go into the main function and alter the choices and control structures given by the switch statements. As well as being a bother, this will mean the whole project will need to be re-compiled, and for large projects this can be a significant time constraint. You can see roughly how much time this takes by comparing the speed of Build/Compiling your project (which checks to see if changes have been made, and then only rebuilds the files that are affected) with the time taken to Re-Build/Re-Compile your project (which throws away previously compiled files and starts again from the beginning). Give this a try!

I’ve got around this in ‘Simple Option Pricer 1.0’ by coding up a basic Factory for each of the three selections, based on the Factory presented in Chapter 10 of Joshi’s text, C++ Design Patterns and Derivatives Pricing (this is one of my favourite textbooks on the subject – I’ll do some book reviews of other gems in the future). You can see how this works by downloading the following four files:

Drop these into the same folder as the rest of the files in ‘Simple Option Pricer 1.0’, and then right-click on the Project in your development environment and add them to the project one-by-one [Nb. if you’re using Visual Studio, you may need to add

#include "stdafx.h"

to the two .cpp files before this will work – and make sure they’re in the same folder as the rest, this can cause problems!!].

Now, Build/Compile your project. If you’ve done everything correctly, it should happen very swiftly – only the forward.cpp and the gaussianCdfInverter.cpp will need to compile, and the linker will need to run, but the other files won’t need to be recompiled (this is the real strength of the method, by the way!). Now, re-run the programme and you should discover two new options available to you for the option pricer! How have we achieved this sorcery?!

In the files optionFactory.cpp and optionFactory.h (and the corresponding files for the RNG and gaussian converters), we’ve defined the factories for the different types of classes we want to use. I’ve used the Singleton Pattern (for brevity I’m not going to discuss it here, but do have a look at wikipedia) to create and access a single instance of each factory. The important point is that there will be a single instance of each factory, and we can get their addresses in memory using the following method at any point in the code

optionFactory::factoryAddress()

The factories themselves store a two column table (implemented with a map) which links a string (the option name) in the first column with a function that constructs an option of that type and returns a pointer to it in the second column (this will be a base class pointer, using polymorphism as discussed above).

The functions that will create these pointers are implemented using another type of polymorphism – templatisation. In the optionFactoryHelper.h header, I’ve defined a new class which is constructed by calling it with a string. It also has a method which builds a new instance of the <class T>, and returns a pointer to it – which is exactly what we said the factory table needs.

template <class T>
simpleOption* simpleOptionHelper<T>::buildOption(double strike) {
 return new T(strike);
}

The constructer for the helper function registers this method in the factory’s table, along with the string.

template <class T>
simpleOptionHelper<T>::simpleOptionHelper(std::string optionType){
 optionFactory& theFactoryAddress = optionFactory::factoryAddress();
 theFactoryAddress.registerOption(optionType, simpleOptionHelper<T>::buildOption);
}

Options are registered in their .cpp files, the simple code to register the forward is at the top of forward.cpp, creating a new instance of the helper class templatised on the specific instance of the option that we are registering through it. This will call the helper class constructor, which as we just saw contains code to register the corresponding option type with the factory

namespace {
 simpleOptionHelper<forward> registerForward("forward");
}

Since these are done in namespaces, they happen before main(){} starts running – and once registered, we can call the factory at any time in our code using a string and giving it the required parameters and it will create a new instance of the derived class with that name

simpleOption* thisOptionPointer = optionFactory::factoryAddress().createOption( optionType, strike );

I’ll use this pattern again and again in future as more and more options are added to the code. At some point in the future, I’ll look at a way of combining ALL of the factories into a single, templatised factory process using more polymorphism, but the complication will be that since different processes need different arguments for their constructors, I’ll need to build a generic container class first that could contain many different sorts of arguments inside it. The next thing I want to do, however, is look at easier ways of data input and output, as the current console application is very clunky and wouldn’t be suitable for a large amount of data input. I’ll discuss ways of dealing with this in future posts.

Inverse Normal CDF

Now that I’ve got some Monte Carlo code up, it’s inevitable that I will eventually need an implementation of the Inverse of the Normal Cumulative Density Function (CDF). The inverse of a CDF is called a Quantile function by the way, so I’ll often refer to this as the Normal Quantile function. The reason this is so important is because, as I discussed in my post on Random Number Generators, it can be used to convert uniformly distributed random numbers into normally distributed random numbers, which we will need for Monte Carlo simulations if we believe that underlyings are distributed according to a lognormal distribution.

As a reminder, I’ve repeated the graph from the previous post here to show the behaviour of the Normal Quantile:

The inverse CDF - called the quantile function
The standard Normal Quantile function. Simple transformations of the normal distribution will allow any non-standard normal quantile to be expressed using the standard version.

 

As with the implementation of an algorithm for the Normal CDF (discussed here), there were several possibilities for implementation. In the end I’ve decided to go with the analytic approximation due to Beasley, Springer and Moro as presented in Joshi’s text on computational derivative pricing:

a1 = 2.50662823884
a2 = -18.61500062529
a3 = 41.39119773534
a4 = -25.44106049637

b1 = -8.47351093090
b2 = 23.08336743743
b3 = -21.06224101826
b4 = 3.13082909833

c1 = 0.3374754822726147
c2 = 0.9761690190917186
c3 = 0.1607979714918209
c4 = 0.0276438810333863
c5 = 0.0038405729373609
c6= 0.0003951896511919
c7 = 0.0000321767881768
c8 = 0.0000002888167364
c9 = 0.0000003960315187

 

A polynomial form is used for the central region of the quantile, where \inline 0.08 < x < 0.92:

y = x - 0.5 \ ; \quad z = y^2

\Phi^{-1}(x) \simeq y \cdot { (a_1 + a_2 z + a_3 z^2 + a_4 z^3 ) \over (1 + b_1 z + b_2 z^2 + b_3 z^3 + b_4 z^4 ) }

 

And if \inline x \leq 0.08 or \inline x \geq 0.92 then:

y = x - 0.5 \ ; \quad z = \Bigl\{ \begin{matrix} x & y\leq 0\\ 1 - x & y > 0 \end{matrix} \ ; \quad \kappa = \ln (-\ln z)

\Phi^{-1}(x) = \pm (c_1 + c_2\kappa + c_3\kappa^2 + c_4\kappa^3 + c_5\kappa^4 + c_6\kappa^5 + c_7\kappa^6 + c_8\kappa^7 + c_9\kappa^8)

With a plus at the front if \inline y \geq 0 and a minus in front if \inline y < 0.

This is fairly swift as an algorithm, and the quantile method of generating normal variates will turn out to have some key advantages over the various other methods discussed before which will become apparent in future. In a future post I’ll show how to integrate this method of converting uniform variates to gaussian variates into the Monte Carlo code that I’ve made available here, thanks to the factory pattern that I’ve used it will turn out to be incredibly straight-forward!

Finally, if you are wondering why the numbers in these numerical algorithms seem so arbitrary, it’s because they [sort-of] are! Once I’ve implemented some optimisation routines (this might not be for a while…) I’ll have a look at how we can find our own expressions for these functions, and hopefully be able to back out some of the numbers above!!