<< . .

( 20)

. . >>

2 Smin
Y1 =

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

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

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

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

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 =

t + 2∆t t + 3∆t · · ·
t t + ∆t T Time

Each step in the simulated price sequence is

= St e(r’ 2 σ )∆+σ ∆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"

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

#include <cmath>
using namespace std;
#include "fin_recipes.h"

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

#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

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;

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.

Chapter 14

Alternatives to the Black Scholes type option formula
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)


„ =T ’t

» = »(1 + κ)

CBS (·) is the Black Scholes formula, and

nδ 2
σn = σ 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
e» „ (» „ )n e» „ (» „ )n
= exp ’» „ + n ln(» „ ) ’
= exp ln ln i
n! n! i=1

#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

Chapter 15

Using a library for matrix algebra
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.

#include <cmath>

<< . .

( 20)

. . >>

Copyright Design by: Sunlight webdesign