LINEBURG

 << Пред. стр. страница 10(всего 20)ОГЛАВЛЕНИЕ След. стр. >>
prices[i] = d*prices[i+1];
call values[i] = (pDown*call values[i]+pUp*call values[i+1])*Rinv;
call values[i] = max(call values[i], prices[i]в€’X); // check for exercise
};
double f11 = call values;
double f10 = call values;
prices = d*prices;
call values = (pDown*call values+pUp*call values)*Rinv;
call values = max(call values, Sв€’X); // check for exercise on п¬Ѓrst date
double f00 = call values;
delta = (f11в€’f10)/(S*uв€’S*d);
double h = 0.5 * S * ( uu в€’ d*d);
gamma = ( (f22в€’f21)/(S*(uuв€’1)) в€’ (f21в€’f20)/(S*(1в€’d*d)) ) / h;
theta = (f21в€’f00) / (2*delta t);
double diп¬Ђ = 0.02;
double tmp sigma = sigma+diп¬Ђ;
double tmp prices = option price call american binomial(S,X,r,tmp sigma,time,no steps);
vega = (tmp pricesв€’f00)/diп¬Ђ;
diп¬Ђ = 0.05;
double tmp r = r+diп¬Ђ;
tmp prices = option price call american binomial(S,X,tmp r,sigma,time,no steps);
rho = (tmp pricesв€’f00)/diп¬Ђ;
};

Code 9.4: Hedge parameters

67
The program

void test binomial approximations option price partials(){
double S = 100.0; double K = 100.0;
double r = 0.1; double sigma = 0.25;
double time=1.0; int no steps = 100;

double delta, gamma, theta, vega, rho;
option price partials american call binomial(S,K,r, sigma, time, no steps,
delta, gamma, theta, vega, rho);
cout << " Call price partials " << endl;
cout << " delta = " << delta << endl;
cout << " gamma = " << gamma << endl;
cout << " theta = " << theta << endl;
cout << " vega = " << vega << endl;
cout << " rho = " << rho << endl;
};

provides the output
Call price partials
delta = 0.699792
gamma = 0.0140407
theta = -9.89067
vega = 34.8536
rho = 56.9652

Example 9.2: Option price partials using binomial approximations

68
9.3 Adjusting for payouts for the underlying

The simplest case of a payout is the similar one to the one we saw in the Black Scholes case, a continous
payout of y.

#include <cmath> // standard mathematical library
#include <algorithm> // deп¬Ѓnes the max() operator
#include <vector> // STL vector templates
using namespace std;

double option price call american binomial( const double& S, // spot price
const double& X, // exercice price
const double& r, // interest rate
const double& y, // continous payout
const double& sigma, // volatility
const double& t, // time to maturity
const int& steps) { // no steps in binomial tree
double R = exp(r*(t/steps)); // interest rate for each step
double Rinv = 1.0/R; // inverse of interest rate
double u = exp(sigma*sqrt(t/steps)); // up movement
double uu = u*u;
double d = 1.0/u;
double p up = (exp((rв€’y)*(t/steps))в€’d)/(uв€’d);
double p down = 1.0в€’p up;
vector<double> prices(steps+1); // price of underlying
vector<double> call values(steps+1); // value of corresponding call

prices = S*pow(d, steps); // п¬Ѓll in the endnodes.
for (int i=1; i<=steps; ++i) prices[i] = uu*prices[iв€’1];
for (int i=0; i<=steps; ++i) call values[i] = max(0.0, (prices[i]в€’X)); // call payoп¬Ђs at maturity
for (int step=stepsв€’1; step>=0; в€’в€’step) {
for (int i=0; i<=step; ++i) {
call values[i] = (p up*call values[i+1]+p down*call values[i])*Rinv;
prices[i] = d*prices[i+1];
call values[i] = max(call values[i],prices[i]в€’X); // check for exercise
};
};
return call values;
};

Code 9.5: Binomial option price with continous payout

69
9.4 Pricing options on stocks paying dividends using a binomial approximation

9.4.1 Checking for early exercise in the binomial model.

If the underlying asset is a stock paying dividends during the maturity of the option, the terms of the option
is not adjusted to reп¬‚ect this cash payment, which means that the option value will reп¬‚ect the dividend
payments.
In the binomial model, the adjustment for dividends depend on whether the dividends are discrete or pro-
portional.

9.4.2 Proportional dividends.

For proportional dividends, we simply multiply with an adjustment factor the stock prices at the exвЂ“dividend
date, the nodes in the binomial tree will вЂњlink upвЂќ again, and we can use the same вЂњrolling backвЂќ procedure.

9.4.3 Discrete dividends

The problem is when the dividends are constant dollar amounts.
In that case the nodes of the binomial tree do not вЂњlink up,вЂќ and the number of branches increases dramat-
ically, which means that the time to do the calculation is increased.
The algorithm presented here implements this case, with no linkup, by constructing a binomial tree up to
the ex-dividend date, and then, at the terminal nodes of that tree, call itself with one less dividend payment,
and time to maturity the time remaining at the ex-dividend date. Doing that calculates the value of the
option at the ex-dividend date, which is then compared to the value of exercising just before the ex-dividend
date. It is a cute example of using recursion in simplifying calculations, but as with most recursive solutions,
it has a cost in computing time. For large binomial trees and several dividends this procedure will take a
long time.

70
<cmath>
#include
<algorithm>
#include
<vector>
#include
#include "fin_recipes.h"
<iostream>
#include

double option price call american proportional dividends binomial(const double& S,
const double& X,
const double& r,
const double& sigma,
const double& time,
const int& no steps,
const vector<double>& dividend times,
const vector<double>& dividend yields) {
int no dividends=dividend times.size();
if (no dividends == 0) {
return option price call american binomial(S,X,r,sigma,time,no steps); // price w/o dividends
};
double delta t = time/no steps;
double R = exp(r*delta t);
double Rinv = 1.0/R;
double u = exp(sigma*sqrt(delta t));
double uu= u*u;
double d = 1.0/u;
double pUp = (Rв€’d)/(uв€’d);
double pDown = 1.0 в€’ pUp;
vector<int> dividend steps(no dividends); // when dividends are paid
for (int i=0; i<no dividends; ++i) {
dividend steps[i] = (int)(dividend times[i]/time*no steps);
};
vector<double> prices(no steps+1);
vector<double> call prices(no steps+1);
prices = S*pow(d, no steps);
for (int i=0; i<no dividends; ++i) { prices*=(1.0в€’dividend yields[i]); };
for (int i=1; i<=no steps; ++i) { prices[i] = uu*prices[iв€’1]; }; // terminal tree nodes
for (int i=0; i<=no steps; ++i) call prices[i] = max(0.0, (prices[i]в€’X));
for (int step=no stepsв€’1; step>=0; в€’в€’step) {
for (int i=0;i<no dividends;++i) { // check whether dividend paid
if (step==dividend steps[i]) {
for (int j=0;j<=step;++j) {
prices[j]*=(1.0/(1.0в€’dividend yields[i]));
};
};
};
for (int i=0; i<=step; ++i) {
prices[i] = d*prices[i+1];
call prices[i] = (pDown*call prices[i]+pUp*call prices[i+1])*Rinv;
call prices[i] = max(call prices[i], prices[i]в€’X); // check for exercise
};
};
return call prices;
};

Code 9.6: Binomial option price of stock option where stock pays proportional dividends

71
#include <cmath>
#include <vector>
#include "fin_recipes.h"
#include <iostream>
double option price call american discrete dividends binomial(const double& S,
const double& K,
const double& r,
const double& sigma,
const double& t,
const int& steps,
const vector<double>& dividend times,
const vector<double>& dividend amounts) {
int no dividends = dividend times.size();
if (no dividends==0) return option price call american binomial(S,K,r,sigma,t,steps);// just do regular
int steps before dividend = (int)(dividend times/t*steps);
const double R = exp(r*(t/steps));
const double Rinv = 1.0/R;
const double u = exp(sigma*sqrt(t/steps));
const double d = 1.0/u;
const double pUp = (Rв€’d)/(uв€’d);
const double pDown = 1.0 в€’ pUp;
double dividend amount = dividend amounts;
vector<double> tmp dividend times(no dividendsв€’1); // temporaries with
vector<double> tmp dividend amounts(no dividendsв€’1); // one less dividend
for (int i=0;i<(no dividendsв€’1);++i){
tmp dividend amounts[i] = dividend amounts[i+1];
tmp dividend times[i] = dividend times[i+1] в€’ dividend times;
};
vector<double> prices(steps before dividend+1);
vector<double> call values(steps before dividend+1);
prices = S*pow(d, steps before dividend);
for (int i=1; i<=steps before dividend; ++i) prices[i] = u*u*prices[iв€’1];
for (int i=0; i<=steps before dividend; ++i){
double value alive
= option price call american discrete dividends binomial(prices[i]в€’dividend amount,K, r, sigma,
tв€’dividend times,// time after п¬Ѓrst dividend
stepsв€’steps before dividend,
tmp dividend times,
tmp dividend amounts);
call values[i] = max(value alive,(prices[i]в€’K)); // compare to exercising now
};
for (int step=steps before dividendв€’1; step>=0; в€’в€’step) {
for (int i=0; i<=step; ++i) {
prices[i] = d*prices[i+1];
call values[i] = (pDown*call values[i]+pUp*call values[i+1])*Rinv;
call values[i] = max(call values[i], prices[i]в€’K);
};
};
return call values;
};

Code 9.7: Binomial option price of stock option where stock pays discrete dividends

72
The program

void test binomial approximations option price dividends(){
double S = 100.0; double K = 100.0;
double r = 0.10; double sigma = 0.25;
double time=1.0;
int no steps = 100;
double d=0.02;
cout << " call price with continuous dividend payout = "
<< option price call american binomial(S,K,r,d,sigma,time,no steps) << endl;
vector<double> dividend times; vector<double> dividend yields;
dividend times.push back(0.25); dividend yields.push back(0.025);
dividend times.push back(0.75); dividend yields.push back(0.025);
cout << " call price with proportial dividend yields at discrete dates = "
<< option price call american proportional dividends binomial(S,K,r,sigma,time,no steps,
dividend times, dividend yields)
<< endl;

vector<double> dividend amounts;
dividend amounts.push back(2.5);
dividend amounts.push back(2.5);
cout << " call price with proportial dividend amounts at discrete dates = "
<< option price call american discrete dividends binomial(S,K,r,sigma,time,no steps,
dividend times, dividend amounts)
<< endl;
};

provides the output

call price with continuous dividend payout = 13.5926
call price with proportial dividend yields at discrete dates = 11.8604
call price with proportial dividend amounts at discrete dates = 12.0233

Example 9.3: Binomial pricing with dividends

73
9.5 Option on futures

For American options, because of the feasibility of early exercise, the binomial model is used to approximate
the option value.

#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;

double futures option price call american binomial(const double& F, // price futures contract
const double& X, // exercise price
const double& r, // interest rate
const double& sigma, // volatility
const double& time, // time to maturity
const int& no steps) { // number of steps
vector<double> futures prices(no steps+1);
vector<double> call values (no steps+1);
double t delta= time/no steps;
double Rinv = exp(в€’r*(t delta));
double u = exp(sigma*sqrt(t delta));
double d = 1.0/u;
double uu= u*u;
double pUp = (1в€’d)/(uв€’d); // note how probability is calculated
double pDown = 1.0 в€’ pUp;
futures prices = F*pow(d, no steps);
int i;
for (i=1; i<=no steps; ++i) futures prices[i] = uu*futures prices[iв€’1]; // terminal tree nodes
for (i=0; i<=no steps; ++i) call values[i] = max(0.0, (futures prices[i]в€’X));
for (int step=no stepsв€’1; step>=0; в€’в€’step) {
for (i=0; i<=step; ++i) {
futures prices[i] = d*futures prices[i+1];
call values[i] = (pDown*call values[i]+pUp*call values[i+1])*Rinv;
call values[i] = max(call values[i], futures prices[i]в€’X); // check for exercise
};
};
return call values;
};

Code 9.8: Option on futures

The program

void test binomial approximations futures options(){
double F = 50.0; double K = 45.0;
double r = 0.08; double sigma = 0.2;
double time=0.5;
int no steps=100;
cout << " european futures call option = "
<< futures option price call american binomial(F,K,r,sigma,time,no steps) << endl;
};

provides the output
european futures call option = 5.74254

Example 9.4: Futures option price

74
9.6 Foreign Currency options

For American options, the usual method is approximation using binomial trees, checking for early exercise
due to the interest rate diп¬Ђerential.

#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;

double currency option price call american binomial(const double& S,
const double& K,
const double& r,
const double& r f,
const double& sigma,
const double& time,
const int& no steps) {
vector<double> exchange rates(no steps+1);
vector<double> call values(no steps+1);
double t delta= time/no steps;
double Rinv = exp(в€’r*(t delta));
double u = exp(sigma*sqrt(t delta));
double d = 1.0/u;
double uu= u*u;
double pUp = (exp((rв€’r f)*t delta)в€’d)/(uв€’d); // adjust for foreign int.rate
double pDown = 1.0 в€’ pUp;
exchange rates = S*pow(d, no steps);
int i;
for (i=1; i<=no steps; ++i) {
 << Пред. стр. страница 10(всего 20)ОГЛАВЛЕНИЕ След. стр. >>