LINEBURG

Y1 =

σ2

Formula 13.1: Analytical formula for a lookback call

#include <cmath>

using namespace std;

#include "normdist.h"

double option price european lookback call(const double& S,

const double& Smin,

const double& r,

const double& q,

const double& sigma,

const double& time){

if (r==q) return 0;

double sigma sqr=sigma*sigma;

double time sqrt = sqrt(time);

double a1 = (log(S/Smin) + (r’q+sigma sqr/2.0)*time)/(sigma*time sqrt);

double a2 = a1’sigma*time sqrt;

double a3 = (log(S/Smin) + (’r+q+sigma sqr/2.0)*time)/(sigma*time sqrt);

double Y1 = 2.0 * (r’q’sigma sqr/2.0)*log(S/Smin)/sigma sqr;

return S * exp(’q*time)*N(a1)’ S*exp(’q*time)*(sigma sqr/(2.0*(r’q)))*N(’a1)

’ Smin * exp(’r*time)*(N(a2)’(sigma sqr/(2*(r’q)))*exp(Y1)*N(’a3));

};

Code 13.3: Price of lookback call option

99

13.4 Monte Carlo Pricing of options whose payo¬ depend on the whole price

path

Monte Carlo simulation can be used to price a lot of di¬erent options. The limitation is that the options

should be European. American options can not be priced by simulation methods. In chapter 11 we looked

at a general simulation case where we wrote a generic routine which we passed a payo¬ function to, and the

payo¬ function was all that was necessary to de¬ne an option value. The payo¬ function in that case was

a function of the terminal price of the underlying security. The only di¬erence to the previous case is that

we now have to generate a price sequence and write the terminal payo¬ of the derivative in terms of that,

instead of just generating the terminal value of the underlying security from the lognormal assumption.

13.4.1 Generating a series of lognormally distributed variables

Recall that one will generate lognormally distributed variables as

√

12

ST = St e(r’ 2 σ )(T ’t)+σ T ’t˜

x

where the current time is t and terminal date is T . To simulate a price sequence one splits this period into

say N periods, each of length

T ’t

∆t =

N

E

t + 2∆t t + 3∆t · · ·

t t + ∆t T Time

Each step in the simulated price sequence is

√

12

= St e(r’ 2 σ )∆+σ ∆t˜

x

St+∆t

Code 13.4 shows how one would simulate a sequence of lognormally distributed variables.

#include <cmath>

#include <vector>

using namespace std;

#include "normdist.h"

vector<double>

simulate lognormally distributed sequence(const double& S, // current value of underlying

const double& r, // interest rate

const double& sigma, // volatitily

const double& time, // time to ¬nal date

const int& no steps){ // number of steps

vector<double> prices(no steps);

double delta t = time/no steps;

double R = (r’0.5*pow(sigma,2))*delta t;

double SD = sigma * sqrt(delta t);

double S t = S; // initialize at current price

for (int i=0; i<no steps; ++i) {

S t = S t * exp(R + SD * random normal());

prices[i]=S t;

};

return prices;

};

Code 13.4: Simulating a sequence of lognormally distributed variables

100

#include <cmath>

using namespace std;

#include "fin_recipes.h"

double

derivative price simulate european option generic(const double& S, // price of underlying

const double& X, // used by user provided payo¬ function

const double& r, // risk free interest rate

const double& sigma, // volatility

const double& time, // time to maturity

double payo¬(const vector<double>& prices,

const double& X),

// user provided function

const int& no steps, // number of steps in generated price sequence

const int& no sims) { // number of simulations to run

double sum payo¬s=0;

for (int n=0; n<no sims; n++) {

vector<double>prices = simulate lognormally distributed sequence(S,r,sigma,time,no steps);

sum payo¬s += payo¬(prices,X);

};

return exp(’r*time) * (sum payo¬s/no sims);

};

Code 13.5: Generic routine for pricing European options which

This code is then used in the generic routine to do calculations, as shown in code 13.5.

To price an option we are then only in need of a de¬nition of a payo¬ function. We consider a couple of

examples. One is the case of an Asian option, shown in code 13.6.

#include <cmath>

#include <numeric>

#include <vector>

using namespace std;

double payo¬ arithmetric average call(const vector<double>& prices, const double& X) {

double sum=accumulate(prices.begin(), prices.end(),0.0);

double avg = sum/prices.size();

return max(0.0,avg’X);

};

double payo¬ geometric average call(const vector<double>& prices, const double& X) {

double logsum=log(prices[0]);

for (unsigned i=1;i<prices.size();++i){ logsum+=log(prices[i]); };

double avg = exp(logsum/prices.size());

return max(0.0,avg’X);

};

Code 13.6: Payo¬ function for Asian call option

Another is the payo¬ for a lookback, shown in code 13.7

101

#include <vector>

#include <algorithm>

using namespace std;

double payo¬ lookback call(const vector<double>& prices, const double& unused variable) {

double m = *min element(prices.begin(),prices.end());

return prices.back()’m; // always positive or zero

};

double payo¬ lookback put(const vector<double>& prices, const double& unused variable) {

double m = *max element(prices.begin(),prices.end());

return m’prices.back(); // max is always larger or equal.

};

Code 13.7: Payo¬ function for lookback option

102

13.5 Control variate

As discussed in chapter 11, a control variate is a price which we both have an analytical solution of and ¬nd

the Monte Carlo price of. The di¬erences between these two prices is a measure of the bias in the Monte

Carlo estimate, and is used to adjust the Monte Carlo estimate of other derivatives priced using the same

random sequence.

Code 13.8 shows the Black Scholes price used as a control variate. An alternative could have been the

analytical lookback price, or the analytical solution for a geometric average price call shown earlier.

#include "fin_recipes.h"

#include <cmath>

using namespace std;

double

derivative price simulate european option generic with control variate(const double& S,

const double& X,

const double& r,

const double& sigma,

const double& time,

double payo¬(const vector<double>& prices,

const double& X),

const int& no steps,

const int& no sims) {

double c bs = option price call black scholes(S,S,r,sigma,time);// price an at the money Black Scholes call

double sum payo¬s=0;

double sum payo¬s bs=0;

for (int n=0; n<no sims; n++) {

vector<double> prices = simulate lognormally distributed sequence(S,r,sigma,time, no steps);

double S1= prices.back();

sum payo¬s += payo¬(prices,X);

sum payo¬s bs += payo¬ call(S1,S); // simulate at the money Black Scholes price

};

double c sim = exp(’r*time) * (sum payo¬s/no sims);

double c bs sim = exp(’r*time) * (sum payo¬s bs/no sims);

c sim += (c bs’c bs sim);

return c sim;

};

Code 13.8: Control Variate

References Exotic options are covered in Hull [2003]. Rubinstein [1993] has an extensive discussion of

analytical solutions to various exotic options.

103

Chapter 14

Alternatives to the Black Scholes type option formula

Contents

14.1 Merton™s Jump di¬usion model. . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

A large number of alternative formulations to the Black Scholes analysis has been proposed. Very few of

them have seen any widespread use, but we will look at some of these alternatives.

14.1 Merton™s Jump di¬usion model.

Merton has proposed a model where in addition to a Brownian Motion term, the price process of the

underlying is allowed to have jumps. The risk of these jumps is assumed to not be priced.

In the following we look at an implementation of a special case of Merton™s model, described in [Hull, 1993, pg

454], where the size of the jump has a normal distribution. » and κ are parameters of the jump distribution.

The price of an European call option is

∞

e» „ (» „ )n 2

CBS (S, X, rn , σn , T ’ t)

c=

n!

n=0

where

„ =T ’t

» = »(1 + κ)

CBS (·) is the Black Scholes formula, and

nδ 2

σn = σ 2 +

2

„

n ln(1 + κ)

rn = r ’ »κ +

„

In implementing this formula, we need to terminate the in¬nite sum at some point. But since the factorial

function is growing at a much higher rate than any other, that is no problem, terminating at about n = 50

should be on the conservative side. To avoid numerical di¬culties, use the following method for calculation

of

n

e» „ (» „ )n e» „ (» „ )n

= exp ’» „ + n ln(» „ ) ’

= exp ln ln i

n! n! i=1

104

#include <cmath>

#include "fin_recipes.h"

double option price call merton jump di¬usion( const double& S,

const double& X,

const double& r,

const double& sigma,

const double& time to maturity,

const double& lambda,

const double& kappa,

const double& delta) {

const int MAXN=50;

double tau=time to maturity;

double sigma sqr = sigma*sigma;

double delta sqr = delta*delta;

double lambdaprime = lambda * (1+kappa);

double gamma = log(1+kappa);

double c = exp(’lambdaprime*tau)*option price call black scholes(S,X,r’lambda*kappa,sigma,tau);

double log n = 0;

for (int n=1;n<=MAXN; ++n) {

log n += log(double(n));

double sigma n = sqrt( sigma sqr+n*delta sqr/tau );

double r n = r’lambda*kappa+n*gamma/tau;

c += exp(’lambdaprime*tau+n*log(lambdaprime*tau)’log n)*

option price call black scholes(S,X,r n,sigma n,tau);

};

return c;

};

Code 14.1: Mertons jump di¬usion formula

The program

#include <cmath>

#include "fin_recipes.h"

void test merton jump di¬ call(){

double S=100;

double K=100;

double r=0.05;

double sigma=0.3;

double time to maturity=1;

double lambda=0.5;

double kappa=0.5;

double delta=0.5;

cout << " Merton Jump diffusion call = "

<< option price call merton jump di¬usion(S,K,r,sigma,time to maturity,lambda,kappa,delta)

<< endl;

};

provides the output

Merton Jump diffusion call = 23.2074

Example 14.1: Mertons Jump di¬usion formula

105

Chapter 15

Using a library for matrix algebra

Contents

15.1 An example matrix class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

15.2 Finite Di¬erences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

15.3 European Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

15.4 American Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

What really distinguishes C++ from standard C is the ability to extend the language by creating classes

and collecting these classes into libraries. A library is a collection of classes and routines for one particular

purpose. We have already seen this idea when creating the date and term structure classes. However,

one should not necessarily always go ahead and create such classes from scratch. It is just as well to use

somebody else class, as long as it is correct and well documented and ful¬lls a particular purpose.

15.1 An example matrix class

Use Newmat as an example matrix class.

15.2 Finite Di¬erences

We use the case of implicit ¬nite di¬erence calculations to illustrate matrix calculations in action.

The method of choice for any engineer given a di¬erential equation to solve is to numerically approximate it

using a ¬nite di¬erence scheme, which is to approximate the continous di¬erential equation with a discrete

di¬erence equation, and solve this di¬erence equation.

In the following we implement the implicit ¬nite di¬erences.

Explicit ¬nite di¬erences was discussed earlier, we postponed the implicit case to now because it is much

simpli¬ed by a matrix library.

15.3 European Options

For European options we do not need to use the ¬nite di¬erence scheme, but we show how one would ¬nd

the european price for comparison purposes.

15.4 American Options

We now compare the American versions of the same algoritms, the only di¬erence being the check for exercise

at each point.

106

#include <cmath>

Copyright Design by: Sunlight webdesign