LINEBURG

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

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

return (c q’c)/q;

};

Code 11.3: Estimate Delta of European Call option priced by Monte Carlo

11.4 More general payo¬s. Function prototypes

The above shows the case for a call option. If we want to price other types of options, with di¬erent payo¬s

we could write similar routines for every possible case. But this would be wasteful, instead a bit of thought

allows us to write option valuations for any kind of option whose payo¬ depend on the value of the underlying

at maturity, only. Let us now move toward a generic routine for pricing derivatives with Monte Carlo. This

83

relies on the ability of C++ to write subroutines which one call with function prototypes, i.e. that in the call

to to the subroutine/function one provides a function instead of a variable. Consider pricing of standard

European put and call options. At maturity each option only depend on the value of the underlying ST and

the exercise price X through the relations

CT = max(ST ’ X, 0)

PT = max(X ’ ST , 0)

Code 11.4 shows two C++ functions which calculates this.

#include <algorithm>

using namespace std;

double payo¬ call(const double& price, const double& X){

return max(0.0,price’X);

};

double payo¬ put (const double& price, const double& X) {

return max(0.0,X’price);

};

Code 11.4: Payo¬ call and put options

The interesting part comes when one realises one can write a generic simulation routine to which one provide

one of these functions, or some other function describing a payo¬ which only depends on the price of the

underlying and some constant. Code 11.5 shows how this is done.

#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 double& price, const double& X),

// user provided function

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

double sum payo¬s=0;

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

double S T = simulate lognormal random variable(S,r,sigma,time);

sum payo¬s += payo¬(S T,X);

};

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

};

Code 11.5: Generic simulation pricing

Note the presence of the line

double payoff(const double& price, const double& X),

in the subroutine call. When this function is called, the calling program will need to provide a function to

put there, such as the Black Scholes example above. Code 11.6 shows a complete example of how this is

done. Running the program in code 11.6 results in the output:

84

#include "fin_recipes.h"

#include <algorithm>

#include <iostream>

using namespace std;

double payo¬ european call(const double& price, const double& X){ return max(0.0,price’X); };

double payo¬ european put (const double& price, const double& X) { return max(0.0,X’price); };

int main(){

double S = 100.0;

double X = 100.0;

double r = 0.1;

double sigma = 0.25;

double time = 1.0;

int no sims = 50000;

cout << "Black Scholes call option price = "

<< option price call black scholes(S,X,r,sigma,time)

<< endl;

cout << "Simulated call option price = "

<< derivative price simulate european option generic(S,X,r,sigma,time,payo¬ european call,no sims)

<< endl;

cout << "Black Scholes put option price = "

<< option price put black scholes(S,X,r,sigma,time)

<< endl;

cout << "Simulated put option price = "

<< derivative price simulate european option generic(S,X,r,sigma,time,payo¬ european put,no sims)

<< endl;

};

Code 11.6: Simulating Black Scholes values using the generic routine

Simulated call option price = 14.995

Black Scholes call option price = 14.9758

Simulated put option price = 5.5599

Black Scholes put option price = 5.45954

As we see, even with as many as 50,000 simuations, the option prices estimated using Monte Carlo still

di¬ers substantially from the “true” values.

11.5 Improving the e¬ciency in simulation

There are a number of ways of “improving” the implementation of Monte Carlo estimation such that the

estimate is closer to the true value.

11.5.1 Control variates.

One is the method of control variates. The idea is simple. When one generates the set of terminal values

of the underlying security, one can value several derivatives using the same set of terminal values. What

if one of the derivatives we value using the terminal values is one which we have an analytical solution

to? For example, suppose we calculate the value of an at the money European call option using both the

(analytical) Black Scholes formula and Monte Carlo simulation. If it turns out that the Monte Carlo estimate

overvalues the option price, we think that this will also be the case for other derivatives valued using the

same set of simulated terminal values. We therefore move the estimate of the price of the derivative of

interest downwards.

Thus, suppose we want to value an European put and we use the price of an at the money European call as

the control variate. Using the same set of simulated terminal values ST,i , we estimate the two options using

85

Monte Carlo as:

n

’r(T ’t)

max (0, X ’ ST,i )

pt = e

ˆ

i=1

n

’r(T ’t)

max (0, ST,i ’ X)

ct = e

ˆ

i=1

We calculate the Black Scholes value of the call cbs , and calculate pcv , the estimate of the put price with a

ˆt t

control variate adjustment, as follows

pcv = pt + (cbs ’ ct )

ˆt ˆ ˆ

t

One can use other derivatives than the at-the-money call as the control variate, the only limitation being

that it has a tractable analytical solution.

Code 11.7 shows the implementation of a Monte Carlo estimation using an at-the-money European call as

the control variate.

#include <cmath>

using namespace std;

#include "fin_recipes.h"

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 double& S,

const double& X),

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++) {

double S T= simulate lognormal random variable(S,r,sigma,time);

sum payo¬s += payo¬(S T,X);

sum payo¬s bs += payo¬ call(S T,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 11.7: Generic with control variate

11.5.2 Antithetic variates.

An alternative to using control variates is to consider the method of antithetic variates. The idea behind this

is that Monte Carlo works best if the simulated variables are “spread” out as closely as possible to the true

distribution. Here we are simulating unit normal random variables. One property of the normal is that it is

symmetric around zero, and the median value is zero. Why don™t we enforce this in the simulated terminal

values? An easy way to do this is to ¬rst simulate a unit random normal variable Z, and then use both

Z and ’Z to generate the lognormal random variables. Code 11.8 shows the implementation of this idea.

Boyle [1977] shows that the e¬ciency gain with antithetic variates is not particularly large. There are other

ways of ensuring that the simulated values really span the whole sample space, sometimes called “pseudo

Monte Carlo.”

86

#include "fin_recipes.h"

#include "normdist.h"

#include <cmath>

using namespace std;

double

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

const double& X,

const double& r,

const double& sigma,

const double& time,

double payo¬(const double& S,

const double& X),

const int& no sims) {

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

double SD = sigma * sqrt(time);

double sum payo¬s=0;

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

double x=random normal();

double S1 = S * exp(R + SD * x);

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

double S2 = S * exp(R + SD * (’x));

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

};

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

};

Code 11.8: Generic with antithetic variates

87

11.5.3 Example

Let us see how these improvements change actual values. We use the same numbers as in code 11.6, but add

estimation using control and antithetic variates. Code 11.9 shows a complete example of how this is done.

#include "fin_recipes.h"

#include <algorithm>

#include <iostream>

using namespace std;

double payo¬ european call(const double& price, const double& X){ return max(0.0,price’X); };

double payo¬ european put (const double& price, const double& X) { return max(0.0,X’price); };

int main(){

double S = 100.0;

double X = 100.0;

double r = 0.1;

double sigma = 0.25;

double time = 1.0;

int no sims = 50000;

cout << "Black Scholes call option price = "

<< option price call black scholes(S,X,r,sigma,time)

<< endl;

cout << "Simulated call option price = "

<< derivative price simulate european option generic(S,X,r,sigma,time,

payo¬ european call,no sims)

<< endl;

cout << "Simulated call option price, CV = "

<< derivative price simulate european option generic with control variate(S,X,r,sigma,time,

payo¬ european call,no sims)

<< endl;

cout << "Simulated call option price, AV = "

<< derivative price simulate european option generic with antithetic variate(S,X,r,sigma,time,

payo¬ european call,no sims)

<< endl;

cout << "Black Scholes put option price = "

<< option price put black scholes(S,X,r,sigma,time)

<< endl;

cout << "Simulated put option price = "

<< derivative price simulate european option generic(S,X,r,sigma,time,payo¬ european put,no sims)

<< endl;

cout << "Simulated put option price, CV = "

<< derivative price simulate european option generic with control variate(S,X,r,sigma,time,

payo¬ european put,no sims)

<< endl;

cout << "Simulated put option price, AV = "

<< derivative price simulate european option generic with antithetic variate(S,X,r,sigma,time,

payo¬ european put,no sims)

<< endl;

};

Code 11.9: Simulating Black Scholes values using the generic Monte Carlo routines, with e¬ciency im-

provents

Running this program results in the output:

Black Scholes call option price = 14.9758

Simulated call option price = 14.995

Simulated call option price, CV = 14.9758

Simulated call option price, AV = 14.9919

Black Scholes put option price = 5.45954

Simulated put option price = 5.41861

Simulated put option price, CV = 5.42541

88

Simulated put option price, AV = 5.46043

89

11.6 More exotic options

These generic routines can also be used to price other options. Any European option that only depends

on the terminal value of the price of the underlying security can be valued. Consider the binary options

discussed by e.g. Hull [2003]. An cash or nothing call pays a ¬xed amount Q if the price of the asset is

above the exercise price at maturity, otherwise nothing. An asset or nothing call pays the price of the asset

if the price is above the exercise price at maturity, otherwise nothing. Both of these options are easy to

implement using the generic routines above, all that is necesary is to provide the payo¬ functions as shown

in code 11.10.

double payo¬ cash or nothing call(const double& price, const double& X){

double Q=1;

if (price>=X) return Q;

return 0;

};

double payo¬ asset or nothing call(const double& price, const double& X){

if (price>=X) return price;

return 0;

};

Code 11.10: Payo¬ binary options

Now, many exotic options are not simply functions of the terminal price of the underlying security, but

depend on the evolution of the price from “now” till the terminal date of the option. For example options

that depend on the average of the price of the underlying (Asian options). For such cases one will have to

simulate the whole path. We will return to these cases in the chapter on pricing of exotic options.

Further Reading Boyle [1977] is a good early source on the use of the Monte Carlo technique for pricing

derivatives. Simulation is also covered in Hull [2003].

11.7 Exercises

Exercise 11.

Consider the pricing of an European Call option as implemented in code 11.2, and the generic formula for pricing

with Monte Carlo for European options that only depend on the terminal value of the underlying security, as

implemented in code 11.5.

Note the di¬erence in the implementation of the lognormal simulation of terminal values. Why can one argue

that the ¬rst implementation is more e¬cient than the other?

90

Chapter 12

Approximations

Contents

12.1 A quadratic approximation to American prices due to Barone“Adesi and

Whaley. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

There has been developed some useful approximations to various speci¬c options. It is of course American

options that are approximated. The particular example we will look at, is a general quadratic approximation

to American call and put prices.

12.1 A quadratic approximation to American prices due to Barone“Adesi and

Whaley.

We now discuss an approximation to the option price of an American option on a commodity, described in

Barone-Adesi and Whaley [1987] (BAW).1 The commodity is assumed to have a continuous payout b. The

starting point for the approximation is the (Black-Scholes) stochastic di¬erential equation valid for the value

of any derivative with price V .

122

σ S VS S + bSVS ’ rV + Vt = 0 (12.1)

2

Here V is the (unknown) formula that determines the price of the contingent claim. For an European option

the value of V has a known solution, the adjusted Black Scholes formula. For American options, which may

be exercised early, there is no known analytical solution.

To do their approximation, BAW decomposes the American price into the European price and the early

exercise premium

C(S, T ) = c(S, T ) + µC (S, T )

Copyright Design by: Sunlight webdesign