LINEBURG


<< . .

 12
( 20)



. . >>

};
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 )

<< . .

 12
( 20)



. . >>

Copyright Design by: Sunlight webdesign