<<

. 9
( 9)



In Chapter 9, we developed an implied volatility function; this function necessarily
meant we needed formulas for the Black“Scholes price and vega of a call option.
We present code for the pricing of calls, puts, digital calls and digital puts, and
for the vega of a call option in BlackScholesFormulas.h and BlackScholes-
Formulas.cpp. We do not present the formulas here as they can be found in
just about any book on derivatives pricing, e.g. [13]. The code is a straightfor-
ward implementation of formulas. Note that we rely heavily on having an imple-
mentation of the cumulative normal function. We give such an implementation in
Appendix B.

Listing A.1 (BlackScholesFormulas.h)

#ifndef BLACK_SCHOLES_FORMULAS_H
#define BLACK_SCHOLES_FORMULAS_H

double BlackScholesCall( double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry);

double BlackScholesPut( double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry);

266
Black“Scholes formulas 267

double BlackScholesDigitalCall(double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry);

double BlackScholesCallVega( double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry);

#endif

Listing A.2 (BlackScholesFormulas.cpp)
#include <BlackScholesFormulas.h>
#include <Normals.h>
#include <cmath>

#if !defined(_MSC_VER)
using namespace std;
#endif

double BlackScholesCall( double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry)
{
double standardDeviation = Vol*sqrt(Expiry);
double moneyness = log(Spot/Strike);
double d1 =( moneyness + (r-d)*Expiry +
0.5* standardDeviation*standardDeviation)/standardDeviation;
double d2 = d1 - standardDeviation;
return Spot*exp(-d*Expiry) * CumulativeNormal(d1) -
Strike*exp(-r*Expiry)*CumulativeNormal(d2);
}
268 Appendix A

double BlackScholesPut( double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry)
{
double standardDeviation = Vol*sqrt(Expiry);
double moneyness = log(Spot/Strike);
double d1 =( moneyness + (r-d)*Expiry +
0.5* standardDeviation*standardDeviation)/standardDeviation;
double d2 = d1 - standardDeviation;
return Strike*exp(-r*Expiry)*(1.0-CumulativeNormal(d2)) -
Spot*exp(-d*Expiry) * (1-CumulativeNormal(d1));
}

double BlackScholesDigitalCall( double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry)
{
double standardDeviation = Vol*sqrt(Expiry);
double moneyness = log(Spot/Strike);
double d2 =( moneyness + (r-d)*Expiry -
0.5* standardDeviation*standardDeviation)/standardDeviation;
return exp(-r*Expiry)*CumulativeNormal(d2);
}

double BlackScholesDigitalPut( double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry)
{
double standardDeviation = Vol*sqrt(Expiry);
double moneyness = log(Spot/Strike);
double d2 =( moneyness + (r-d)*Expiry -
Black“Scholes formulas 269

0.5* standardDeviation*standardDeviation)/standardDeviation;
return exp(-r*Expiry)*(1.0-CumulativeNormal(d2));
}

double BlackScholesCallVega( double Spot,
double Strike,
double r,
double d,
double Vol,
double Expiry)
{
double standardDeviation = Vol*sqrt(Expiry);
double moneyness = log(Spot/Strike);
double d1 =( moneyness + (r-d)*Expiry +
0.5* standardDeviation*standardDeviation)/standardDeviation;
return Spot*exp(-d*Expiry) * sqrt(Expiry)*NormalDensity(d1);
}
Appendix B

Distribution functions




We have repeatedly used the cumulative normal distribution function for a standard
normal random variable and its inverse. We give an implementation of rational
approximations for these functions in Normals.h and Normals.cpp. For further
discussion of these approximations see [5], [21] and [10].

Listing B.1 (Normals.h)
#ifndef NORMALS_H
#define NORMALS_H

double NormalDensity(double x);

double CumulativeNormal(double x);

double InverseCumulativeNormal(double x);

#endif

Listing B.2 (Normals.cpp)
/*
code to implement the basic distribution functions necessary
inmathematical finance via rational approximations
*/

#include <cmath>
#include <Normals.h>

// the basic math functions should be in namespace std but
// aren™t in VCPP6

270
Distribution functions 271

#if !defined(_MSC_VER)
using namespace std;
#endif

const double OneOverRootTwoPi = 0.398942280401433;

// probability density for a standard Gaussian distribution
double NormalDensity(double x)
{
return OneOverRootTwoPi*exp(-x*x/2);
}

// the InverseCumulativeNormal function via the
// Beasley-Springer/Moro approximation
double InverseCumulativeNormal(double u)
{

static double a[4]={ 2.50662823884,
-18.61500062529,
41.39119773534,
-25.44106049637};

static double b[4]={-8.47351093090,
23.08336743743,
-21.06224101826,
3.13082909833};

static double c[9]={0.3374754822726147,
0.9761690190917186,
0.1607979714918209,
0.0276438810333863,
0.0038405729373609,
0.0003951896511919,
0.0000321767881768,
0.0000002888167364,
0.0000003960315187};

double x=u-0.5;
double r;
272 Appendix B

if (fabs(x)<0.42) // Beasley-Springer
{
double y=x*x;

r=x*(((a[3]*y+a[2])*y+a[1])*y+a[0])/
((((b[3]*y+b[2])*y+b[1])*y+b[0])*y+1.0);

}
else // Moro
{

r=u;

if (x>0.0)
r=1.0-u;

r=log(-log(r));

r=c[0]+r*(c[1]+r*(c[2]+r*(c[3]+r*(c[4]+r*(c[5]+
r*(c[6]+r*(c[7]+r*c[8])))))));

if (x<0.0)
r=-r;

}

return r;
}

// standard normal cumulative distribution function
double CumulativeNormal(double x)
{
static double a[5] = { 0.319381530,
-0.356563782,
1.781477937,
-1.821255978,
1.330274429};

double result;
Distribution functions 273

if (x<-7.0)
result = NormalDensity(x)/sqrt(1.+x*x);

else
{
if (x>7.0)
result = 1.0 - CumulativeNormal(-x);
else
{
double tmp = 1.0/(1.0+0.2316419*fabs(x));

result=1-NormalDensity(x)*
(tmp*(a[0]+tmp*(a[1]+tmp*(a[2]+
tmp*(a[3]+tmp*a[4])))));

if (x<=0.0)
result=1.0-result;
}
}
return result;
}
Appendix C

A simple array class




C.1 Choosing an array class
To do any serious numerical work, we need the concept of an array. In C++
this translates into the need for an array class. There are any number of array
classes available on the web, and the coder can easily write his own. Indeed most
learners of C++ develop their own array class as an exercise sometime early in
their study. In fact, the C++ standard library includes an array class which is de-
signed to be optimized for high-speed numerical computation. This template array
class is called valarray and has different emphases from the standard library™s
vector class. Where vector was designed to be ef¬cient for resizing and insert-
ing elements, the assumption in valarray is that the array™s size will not often
vary. Instead valarray is designed for speed, and it provides many numerical op-
erations. For a discussion of the valarray class see [12] or [31].
There is, however, a downside to using valarray: there is no range checking. So
if your index goes off the end of the array, you do not receive a nice error message,
but instead you just get garbage or a crash. The reason that range checking is not
provided is that it is time consuming, and logically correct code will, by de¬nition,
not need it. However, it is an extremely useful debugging tool, and so ideally it
should be easy to switch on and off.
Our solution is therefore to provide our own array class which is modelled on
valarray<double> and provides a subset of its operations. This means that we
can use a typedef to replace our class with valarray<double> when we are
con¬dent in our code. This allows us to take advantage of all the optimizations
in valarray, whilst retaining an easy-to-use class for debugging. Our class pro-
vides range-checking if and only if the macro RANGE CHECKING is de¬ned. Thus
by changing one project setting, we can quickly shift between safe and fast modes.
We also provide the facility to shift between valarray<double> and our class via
de¬ning the macro USE VAL ARRAY.


274
A simple array class 275

It is important to be careful when choosing an array class. Once a class interface
has been chosen, you are stuck with it. You can always gut the insides of your
class to make it more ef¬cient but once the class has been used throughout your
code, a lot of time has been invested in the interface, and to change it is a dif¬cult
proposition.


C.2 The header ¬le
We present the class, called MJArray to avoid the likelihood of name clashes, in
Arrays.h.

Listing C.1 (Arrays.h)

#ifndef MJARRAYS_H
#define MJARRAYS_H

#ifdef USE_VAL_ARRAY

#include <valarray>

typedef std::valarray<double> MJArray;

#else // ifdef USE_VAL_ARRAY

class MJArray
{

public:
explicit MJArray(unsigned long size=0);
MJArray(const MJArray& original);

˜MJArray();

MJArray& operator=(const MJArray& original);
MJArray& operator=(const double& val);

MJArray& operator+=(const MJArray& operand);
MJArray& operator-=(const MJArray& operand);
MJArray& operator/=(const MJArray& operand);
MJArray& operator*=(const MJArray& operand);
276 Appendix C

MJArray& operator+=(const double& operand);
MJArray& operator-=(const double& operand);
MJArray& operator/=(const double& operand);
MJArray& operator*=(const double& operand);

MJArray apply(double f(double)) const;

inline double operator[](unsigned long i) const;
inline double& operator[](unsigned long i);

inline unsigned long size() const;

void resize(unsigned long newSize);

double sum() const;
double min() const;
double max() const;

private:
double* ValuesPtr;
double* EndPtr;

unsigned long Size;
unsigned long Capacity;
};

inline double MJArray::operator[](unsigned long i) const
{
#ifdef RANGE_CHECKING
if (i >= Size)
{
throw("Index out of bounds");
}
#endif

return ValuesPtr[i];
}

inline double& MJArray::operator[](unsigned long i)
{
#ifdef RANGE_CHECKING
A simple array class 277

if (i >= Size)
{
throw("Index out of bounds");
}
#endif

return ValuesPtr[i];
}

inline unsigned long MJArray::size() const
{
return Size;
}
#endif // ifdef USE_VAL_ARRAY
#endif // ifndef MJARRAYS_H
We have provided the standard class operations: constructor, copy constructor,
assignment operator, and destructor. We can carry out simple numerical operations,
such as addition or multiplication, both by doubles, which are applied to each
element, and by arrays, which are applied pointwise.
We have overloaded operator[]. It is provided in const and non-const ver-
sions. The former can be used to read elements of const arrays, whereas the latter
can be used to modify elements of non-const arrays. Note that these operators
have been inlined. This means that when the compiler encounters the operator, it
reproduces the code inside the function instead of setting up a call to the function.
This ensures that no extra overhead is caused by going via the class interface. (An
alternative would have been to make the data pointer public and use C style array
access, but this would have badly violated one of our basic rules that the class data
members should be private.)
We also include the apply method. This takes in a function object, f, and applies
it to each element of the array and outputs a new array consisting of the results.
We can take the size of our array, and we can resize it. We follow the
valarray class in not requiring the resize operation to preserve the underlying
data.
Finally, we also include the self-explanatory operations sum, min, and max.
Valarray contains many more operations which could be added to our class as
and when necessary.
Our implementation has four data members. We have pointers to express the
beginning and end of the array. We also have two different size members. The
member Size expresses the number of elements currently in the array, whereas the
member Capacity expresses the amount of memory that has been allocated. So
278 Appendix C

we should always have that Size is less than or equal to Capacity, and that Size
is equal to EndPtr minus StartPtr.


C.3 The source code
We present the source code for our array class in Arrays.cpp.

Listing C.2 (Arrays.cpp)
#include <Arrays.h>
#include<algorithm>
#include<numeric>

MJArray::MJArray(unsigned long size)
: Size(size), Capacity(size)
{
if (Size >0)
{
ValuesPtr = new double[size];
EndPtr = ValuesPtr;
EndPtr += size;
}
else
{
ValuesPtr=0;
EndPtr=0;
}
}

MJArray::MJArray(const MJArray& original)
:
Size(original.Size), Capacity(original.Size)
{
if (Size > 0)
{
ValuesPtr = new double[Size];

EndPtr = ValuesPtr;

EndPtr += Size;

std::copy(original.ValuesPtr, original.EndPtr, ValuesPtr);
A simple array class 279

}
else
{
ValuesPtr = EndPtr =0;
}
}

MJArray::˜MJArray()
{
if (ValuesPtr >0)
delete [] ValuesPtr;
}

MJArray& MJArray::operator=(const MJArray& original)
{
if (&original == this)
return *this;

if (original.Size > Capacity)
{
if (Capacity > 0)
delete [] ValuesPtr;

ValuesPtr = new double[original.Size];

Capacity = original.Size;
}

Size=original.Size;

EndPtr = ValuesPtr;
EndPtr += Size;

std::copy(original.ValuesPtr, original.EndPtr, ValuesPtr);

return *this;
}

void MJArray::resize(unsigned long newSize)
{
if (newSize > Capacity)
280 Appendix C

{
if (Capacity > 0)
delete [] ValuesPtr;

ValuesPtr = new double[newSize];

Capacity = newSize;
}
Size = newSize;

EndPtr = ValuesPtr + Size;
}

MJArray& MJArray::operator+=(const MJArray& operand)
{
#ifdef RANGE_CHECKING
if ( Size != operand.size())
{
throw("to apply += two arrays must be of same size");
}
#endif

for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]+=operand[i];

return *this;
}
MJArray& MJArray::operator-=(const MJArray& operand)
{
#ifdef RANGE_CHECKING
if ( Size != operand.size())
{
throw("to apply -= two arrays must be of same size");
}
#endif

for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]-=operand[i];

return *this;
}
A simple array class 281

MJArray& MJArray::operator/=(const MJArray& operand)
{
#ifdef RANGE_CHECKING
if ( Size != operand.size())
{
throw("to apply /= two arrays must be of same size");
}
#endif

for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]/=operand[i];

return *this;
}

MJArray& MJArray::operator*=(const MJArray& operand)
{
#ifdef RANGE_CHECKING
if ( Size != operand.size())
{
throw("to apply *= two arrays must be of same size");
}
#endif

for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]*=operand[i];

return *this;
}

/////////////////////////////

MJArray& MJArray::operator+=(const double& operand)
{
for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]+=operand;

return *this;
}

MJArray& MJArray::operator-=(const double& operand)
282 Appendix C

{
for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]-=operand;

return *this;
}

MJArray& MJArray::operator/=(const double& operand)
{
for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]/=operand;

return *this;
}

MJArray& MJArray::operator*=(const double& operand)
{
for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]*=operand;

return *this;
}

MJArray& MJArray::operator=(const double& val)
{
for (unsigned long i =0; i < Size; i++)
ValuesPtr[i]=val;

return *this;
}

double MJArray::sum() const
{
return std::accumulate(ValuesPtr,EndPtr,0.0);
}

double MJArray::min() const
{
#ifdef RANGE_CHECKING
if ( Size==0)
{
A simple array class 283

throw("cannot take min of empty array");
}
#endif RANGE_CHECKING
double* tmp = ValuesPtr;
double* endTmp = EndPtr;

return *std::min_element(tmp,endTmp);
}

double MJArray::max() const
{
#ifdef RANGE_CHECKING
if ( Size==0)
{
throw("cannot take max of empty array");
}
#endif RANGE_CHECKING
double* tmp = ValuesPtr;
double* endTmp = EndPtr;

return *std::max_element(tmp,endTmp);
}

MJArray MJArray::apply(double f(double)) const
{
MJArray result(size());

std::transform(ValuesPtr,EndPtr,result.ValuesPtr,f);

return result;
}

The code here is quite straightforward. Some points to note: we only reallocate
memory when the size becomes greater than the capacity so operator= and
resize check size against capacity. This reduces the number of memory alloca-
tions necessary. The data member EndPtr is optional in that its value is determined
by ValuesPtr and size. However, having a pointer for the start of the array and
the end of the array leaves us very well placed to use the STL algorithms. These
generally take in two (or more) iterators which point to the start of the sequence,
and to the element after the end of a sequence, which is precisely what ValuesPtr
and EndPtr respectively do.
284 Appendix C

We therefore use the STL algorithms to perform mundane tasks such as copying,
taking the min and taking the max, and soon, rather than writing loops to do them
ourselves. As well as saving us coding time, the general principle that we should
use pre-de¬ned routines rather than user-de¬ned ones is a good one; pre-de¬ned
routines are generally close to optimal and we have the advantage that, as part of
the standard library, another C++ programmer should recognize and understand
them instantly.
Appendix D

The code




D.1 Using the code
The source code is downloadable from www.markjoshi.com/design. The code has
been been placed in three directories: C/include, C/source, and C/main. Each
main program indicates the source ¬les that must be included in the same project
for the code to link. The include ¬les are included using < > so the directory
C/include must be included in the list of places your compiler looks for include
¬les. In Visual C++, the directories for include ¬les can be changed via the menus
tools, options, directories.
Make¬les, project ¬les, etc. are not included as they are highly compiler depen-
dent.


D.2 Compilers
The code has been tested under three compilers: MingW 2.95, Borland 5.5, and
Visual C++ 6.0. The ¬rst two of these are available for free so you should have
no trouble ¬nding a compiler that the code works for. In addition, MingW is the
Windows port of the GNU compiler, gcc, so the code should work with that com-
piler too. Visual C++ is not free but is popular in the City and the introductory
version is not very expensive. In addition, I have strived to use only ANSI/ISO
code so the code should work under any compiler. In any case, it does not use any
cutting-edge language features so if it is not compatible with your compiler, ¬xing
the problems should not be hard.


D.3 License
The code is released under an artistic license. This means that you can do what you
like with it, provided that if you redistribute the source code you allow the receiver
to do what they like with it too.

285
Appendix E

Glossary




anti-thetic sampling “ a method of improving convergence in Monte Carlo sim-
ulations by following each sample by its negative.
class “ a user-de¬ned type.
constructor “ a member function that has the same name as its class. It provides
a way to create objects from the class.
container “ a class with the main purpose of holding other objects.
decoration “ the act of wrapping a class around another class in such a way that
the interface does not change.
encapsulation “ the process of representing a concept atomically in terms of a
single class.
function “ a routine inside a program to which information may be passed and/or
returned.
inheritance “ de¬ning classes in such a way that they take on the attributes of an
existing class plus additional characteristics.
iterator “ a class that is similar to a pointer and, in particular, it can be incremented
and dereferenced.
member function “ a function associated with objects of a particular class.
method “ another name for a member function.
object “ a variable that comes from a class.
pattern “ a code design.
pointer “ a variable that points to a location in memory.
standard template library “ a collection of header ¬les with properties de¬ned
by the standard which provide a collection of container classes and algo-
rithms.
STL “ shorthand for standard template library.
template “ a piece of code which is written to work with any class that de¬nes
certain chosen methods.
variable “ a quantity that is stored within a program and can change in value.
wrapper “ a smart pointer class that handles memory allocation and deallocation.

286
Bibliography




[1] A. Alexandrescu, Modern C++ Design, Addison-Wesley, 2001.
[2] M. Baxter & A. Rennie, Financial Calculus, Cambridge University Press, 1999.
[3] T. Bj¨ rk, Arbitrage Theory in Continuous Time, Oxford University Press, 1998.
o
[4] S. Dalton, Financial Applications using Excel Add-in Development in C/C++ ,
Second Edition, Wiley, 2007.
[5] B. Dupire, Monte Carlo: Methodologies and Applications for Pricing and Risk
Management, Risk Books, 1998.
[6] G. Entsminger, The Tao of Objects, Hungry Minds Inc., 1995.
[7] E. Gamma, R. Helm, R. Johnson & J. Vlissides, Design Patterns: Elements of
Reusable Object-Oriented Software, Addison-Wesley, 1995.
[8] G. Grimmett & D. Stirzaker, Probability and Random Processes, second edition,
Oxford University Press, 1992.
[9] E. Haug, The Complete Guide to Option Pricing Formulas, Irwin Professional,
1997.
[10] J. Hull, Options, Futures, and Other Derivatives, ¬fth edition, Prentice Hall, 2002.
[11] P. J¨ ckel, Monte Carlo Methods in Finance, Wiley, 2002.
a
[12] N. Josuttis, The C++ Standard Library, Addison-Wesley, 1999.
[13] M. S. Joshi, The Concepts and Practice of Mathematical Finance, Cambridge
University Press, 2003.
[14] I. Karatzas & S. Shreve, Brownian Motion and Stochastic Calculus, second edition,
Berlin: Springer-Verlag, 1997
[15] I. Karatzas & S. Shreve, Methods of Mathematical Finance, Springer-Verlag, 1998.
[16] J. Lakos, Large Scale C++ Software Design, Addison“Wesley, 1996.
[17] A. L. Lewis, Option Valuation under Stochastic Volatility, Finance Press, 2001.
[18] S. Meyers, Effective C++, second edition, Addison-Wesley, 1997.
[19] S. Meyers, More Effective C++, Addison-Wesley, 1995.
[20] S. Meyers, Effective STL, Addison-Wesley, 2001.
[21] B. Moro, The full monte, Risk 8(2), 1995, 53“57.
[22] R. Merton, Continuous-Time Finance, Blackwell, 1998.
[23] R. Merton, Option pricing when underlying stock returns are discontinuous, Journal
of Financial Economics 3, 1976, 125“144.
[24] T. Muldner, C++ Programming: with Design Patterns Revealed, Addison-Wesley,
2001.
[25] M. Musiela, M. Rutowski, Martingale Methods in Financial Modelling, Berlin:
Springer-Verlag, 1997.


287
288 Bibliography

[26] B. Oksendal, Stochastic Differential Equations, Springer-Verlag, 1998.
[27] S. K. Park & K. W. Miller, Random number generators: good ones are hard to ¬nd,
Comm. ACM 31, 1988, 1192“1201.
[28] W. H. Press, S. A. Teutolsky, W. T. Vetterling & B. P. Flannery, Numerical Recipes in
C, second edition, Cambridge University Press, 1992.
[29] L. C. G. Rogers, Monte Carlo Valuation of American Options. Preprint, University
of Bath, 2001.
[30] A. Shalloway & J. R. Trott, Design Patterns Explained: A New Perspective on
Object-Oriented Design, Addison-Wesley, 2001.
[31] B. Stroustrup, The C++ Programming Language, third edition, Addison“Wesley,
2000.
[32] H. Sutter, Exceptional C++, Addison“Wesley, 2000.
[33] H. Sutter, More Exceptional C++, Addison“Wesley 2001.
[34] H. Sutter, Exceptional C++ style, Addison“Wesley 2004.
[35] D. Vandevoorde and N. M. Josuttis, C++ Templates: The Complete Guide,
Addison“Wesley, 2002.
Index




boost, 181
abstract base class, 259
Boost, 184, 197
abstract factory, 169
Borland, 174
adapter pattern, 90, 170
Box“Muller, 6, 9
American option
bridge pattern, 53“57, 59, 170
on a tree, 122, 126
Brownian motion, 2
Ametrano
BSCall class, 144, 149
Ferdinando, 178
BSCallTwo class, 151
ANSI/ISO standard, 174
BSCallTwo.cpp, 152
anti-thetic sampling, 84, 93“97, 204
BSCallTwo.h, 151
AntiThetic class, 93
AntiThetic.cpp, 94
AntiThetic.h, 93 C API, 253, 264
ArgList.cpp, 208 CashFlow class, 106
ArgList.h, 200 catch, 179, 189, 192
ArgListFactory.h, 233 CellMatrix, 206, 220“232, 248, 252, 257, 259, 262
argument list, 200“220, 224“242 CellMatrix.h, 220
ArgumentList, 247, 249 class, 9
array, 87, 274 clone, 44, 168, 175, 180, 182
Arrays.cpp, 278 Comeau, 174
Arrays.h, 275 compilers, 174“176
Asian option completeness, 123
arithmetic, 115 concrete, 260
geometric, 114 const, 14, 53, 77, 97, 147, 180
assignment operator, 52, 183 constructor, 197
auto pointer, 182 contract, 16
automatic registration, 162 control variate
automatic variable, 32, 181 on a tree, 138
ConvergenceTable class, 77
ConvergenceTable.cpp, 78
base class, 23
ConvergenceTable.h, 78
basic guarantee, 180
copy constructor, 29, 51, 182, 183, 197
behavioural patterns, 170“171
creational patterns, 168“169
binomial tree, 129
cumulative normal function, 266, 270
BinomialTree.cpp, 131
curiously recurring template pattern, 199“200, 250
BinomialTree.h, 130
bisection, 141, 142
Bisection template function, 146, 154 data type, 247“250
Bisection.h, 146 basic, 247“248
Black“Scholes formula, 141 extended, 248“250
implementation of, 266 polymorphic, 253
Black“Scholes model, 1, 111 debuggers
BlackScholesFormulas.cpp, 267 and template code, 155
BlackScholesFormulas.h, 266 debugging, 176
an xll, 254
Boost, 176“177


289
290 Index

decorator pattern, 80, 170 functional interface, 264
and anti-thetic sampling, 93 functor, see function object
decoupling, 256“265
deep copy, 51 g++, 174
delete, 180, 181, 184 Gaussian random variable
delete command, 33, 43 generation of, 85
delete[], 184 gcc, 174
dereference, 74 geometric Brownian motion
destructor, 33, 52, 183 discretization of, 121
DevCpp, 244, 245, 254 global variables, 157
dimension
of a Monte Carlo simulation, 84 header ¬les
displaced diffusion, 115 and decoupling, 256“260
dll, 244, 246 heap, 57
missing, 254
DoubleDigital.cpp, 34 IDE, 174
DoubleDigital.h, 34 implied volatility, 141, 151
DoubleOrNothing, 247, 249, 257 include, 257
DoubleOrNothing.cpp, 258 inheritance, 23“34
dumpbin, 254 private, 197“199
dynamic link library, see dll public, 24, 198
inherited class, 23
elegance, 7 inline, 262“263
encapsulation, 10, 13“20 insulation, 256“265
enum statement, 8 interface, 10
EquityFXMain.cpp, 117 interface generator, see InterfaceGenerator
European option InterfaceGenerator, 244, 245, 248
on a tree, 126 inverse cumulative normal function, 85, 87, 93,
ExampleFile1.h, 257 270
ExampleFile2.h, 257 iterator, 87, 162, 171
Excel, 204
EXCEL, 244“255, 262, 264 law of large numbers, 2
exception Lecomte
¬‚oating point, 187“192 Jerome, 178
exceptions, 179“192 levelization, 260“262
safety guarantees, 180 linear congruential generator, 88
exotic option log-normal, 114
logical design, 256
path-dependent, 103, 104, 111
low-discrepancy numbers, 77, 84
ExoticBSEngine class, 111
LPXLOPER, 252, 253
ExoticBSEngine.cpp, 112
ExoticBSEngine.h, 112
ExoticEngine class, 108 malloc, 184
ExoticEngine.cpp, 109 map, 207
ExoticEngine.h, 108 map class, 159, 161
max, 219
export, 174, 263
MCStatistics.cpp, 68
extern C, 253
MCStatistics.h, 67
memory allocation, 179
factory, 204, 260
memory leak, 183
factory method, 169
Microsoft Platform SDK, 188, 247
factory pattern, 37, 157, 169, 199
minimal standard generator, 89
and templatization, 197“242
MJMatrix, 247
¬‚oat under¬‚ow, 188
moment matching, 85
¬‚oating point exceptions, see exception, ¬‚oating point
monostate pattern, 169
for loop, 175
Monte Carlo, 1, 6, 58
forward declaration, 257
Moro approximation to inverse cumulative normal
FPMain.cpp, 190
function, 87
FPSetup.cpp, 189
MyMatrix, 247, 252, 261
FPSetup.h, 188
free, 184
namespace, 164
function objects, 14, 142“144
NEMatrix, 247, 252
function pointer, 8, 21
new, 184
function wizard, 250
Index 291

new command, 33, 43, 44, 57“58 public inheritance, see inheritance, public
Newton“Raphson, 141, 142, 149“154 pure virtual function, 27, 29
NewtonRaphson template function, 150, 152,
154 QuantLib, 177
NewtonRaphson.h, 150 quasi-random numbers, 84
new[], 184
noncopyable, 197 rand command, 83
normal process, 115 random number generator, 9, 83, 89, 177
Normals.cpp, 270 Random1.cpp, 5
Normals.h, 270 Random1.h, 4
Random2.cpp, 88
open-closed principle, 20“21, 157, 166 Random2.h, 86
operator overloading, 14 RandomBase class, 86
operator(), 14 RandomMain3.cpp, 99
RandomParkMiller class, 90
pair class, 131, 162 range-checking, 176, 185, 274
Parameters class, 58“62, 131 raw pointer, 183
Parameters.cpp, 61 reference, 40, 43
Parameters.h, 59 reference-counted pointer, 182
ParkMiller class, 90 reusability, 7
ParkMiller.cpp, 90 root mean square, 62
ParkMiller.h, 89 rule of almost zero, 183“184
path-dependent exotic option, see exotic option, rule of three, 51, 183
path-dependent
PathDependent class, 106 scoped pointer, 182, 183
PathDependent.cpp, 108 shallow copy, 51, 183
PathDependent.h, 107 shared pointer, 182, 183
PathDependentAsian class, 115 SimpleBinomialTree class, 130
PathDependentAsian.cpp, 116 SimpleMC.cpp, 16
PathDependentAsian.h, 115 SimpleMC.h, 16
PayFactoryMain.cpp, 165 SimpleMC3.cpp, 40
PayOff, 179, 247, 260 SimpleMC3.h, 40
PayOff class, 9, 13“20, 23, 24, 34, 44, SimpleMC4.cpp, 48
159 SimpleMC4.h, 48
PayOff.h, 237, 260 SimpleMC6.cpp, 63
PayOff1.cpp, 15 SimpleMC6.h, 63
PayOff1.h, 13 SimpleMC7.cpp, 70
PayOff2.cpp, 25 SimpleMC7.h, 69
PayOff2.h, 24 SimpleMC8.cpp, 98
PayOff3.cpp, 45 SimpleMC8.h, 97
PayOff3.h, 44 SimpleMCMain1.cpp, 2
PayOffBridge.cpp, 54 SimpleMCMain2.cpp, 18
PayOffBridge.h, 54 SimpleMCMain3.cpp, 27
PayOffBridged class, 129 SimpleMCMain4.cpp, 30
PayOffConcrete.cpp, 239 SimpleMCMain5.cpp, 35
PayOffConcrete.h, 237 singleton, 197, 198, 199“200, 250, 251
PayOffConstructible.h, 163 singleton pattern, 158“159, 169
PayOffFactory class, 160 sizeof, 198
PayOffFactory.cpp, 161 smart pointer, 177, 180“184
PayOffFactory.h, 160 SolveMain1.cpp, 147
PayOffForward class, 138 SolveMain2.cpp, 152
PayOffForward.cpp, 139 sstream, 219
PayOffForward.h, 138 stack, 57
PayOffHelper template class, 163 standard library, 181, 184
PayOffRegistration.cpp, 164, 242 standard template library, 219
physical design, 256“265 static, 158, 159, 164
PIMPL idiom, 264“265 statistics gatherer class, 66
POD, 253 StatisticsMC class, 68
pointer to a member function, 149 StatsMain1.cpp, 71
pragma, 131 stlport, 176, 185
private, 15“16, 24, 182, 207, 263 stock price evolution
protected keyword, 24 model for, 1
292 Index

strategy pattern, 66, 170 valarray class, 274
strong guarantee, 180, 186 Vanilla1.cpp, 39
structural patterns, 169“170 Vanilla1.h, 39
structured exception, 188 Vanilla2.cpp, 47
switch, 19 Vanilla2.h, 46
switch statement, 8, 157 Vanilla3.cpp, 56
Vanilla3.h, 55
template pattern, 104, 120, 171 VanillaMain1.cpp, 41
templates, 73“77, 154“155, 158, 175, 263 VanillaMain2.cpp, 49
throw, 179, 180 VanillaOption class, 39
in a constructor, 186“187 vector, 184, 224
in a destructor, 186“187 vector class, 134, 274
time in standard template library, 106
to execute, 250 virtual copy constructor, 44, 168
transform, 219 virtual destructor, 33
TreeAmerican class, 126 virtual function, 24“29, 155
TreeAmerican.cpp, 128 virtual function table, 26, 30
TreeAmerican.h, 126 virtual method, see virtual function
TreeEuropean class, 127 Visual Studio, 174, 185, 244, 245, 254
TreeEuropean.cpp, 128 volatile, 250
TreeEuropean.h, 127
TreeMain.cpp, 135 weak guarantee, 180, 186
TreeProduct class, 125, 130 wrapper class, 249
TreeProducts.cpp, 126 wrapper template class, 53, 73“77, 181, 185“186
TreeProducts.h, 125 Wrapper.h, 74
trees wrapper2.h, 193
mathematics of, 121“123 WrapperMain.cpp, 195
trinomial tree, 123
Turing machine, 175 XlfOper, 253, 261
typedef, 160, 259, 274 xll, 244“255, 264
XLOPER, 247
unde¬ned class, 259 xlw, 177“178, 200, 232, 244“255, 257,
unrecognizable format, 254 261

<<

. 9
( 9)