-
Notifications
You must be signed in to change notification settings - Fork 0
/
BinomialTree.cpp
170 lines (137 loc) · 5.86 KB
/
BinomialTree.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* Cox-Ross-Rubenstein Option Price Model 12/10/2014
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$ BinomialTree.cpp - code $
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
by W.B. Yates
Copyright (c) W.B. Yates. All rights reserved.
History:
Cox-Ross-Rubenstein binomial tree option price model (see Hull (6th edition), page 393)
Suitable for pricing, for example, American options
*/
#ifndef __BINOMIALTREE_H__
#include "BinomialTree.h"
#endif
#ifndef __NEARZERO_H__
#include "NearZero.h"
#endif
#include <math.h>
double
BinomialTree::value( double strike, // option strike
double assetPrice, // asset's current value
double vol, // volatility
double rate, // risk free rate of interest; modify for inclusion of Div Yield
double maturity, // year fraction; options time to maturity
double yield,
bool call )
{
// How many time steps to maturity
double dt = maturity / double(m_stepNumber-1);
// see Hull (6th edition), Chapter 17, page 393
// Cox, Ross, Rubinstein
double sqrtDt = sqrt(dt);
double u = exp( vol * sqrtDt );
double d = exp( -vol * sqrtDt );
double a = exp( (rate - yield) * dt );
double p = (a - d) / (u - d);
m_s[0][0] = assetPrice;
for (int m = 1; m < m_stepNumber; m++)
{
for (int n = m + 1; n > 0 ;n--)
{
m_s[m][n] = u * m_s[m - 1][n - 1];
}
m_s[m][0] = d * m_s[m - 1][0];
}
for (int n = 0; n < m_stepNumber; n++)
{
m_v[m_stepNumber-1][n] = payOff( strike, m_s[m_stepNumber-1][n], call );
}
double discount = exp(-rate * dt);
for (int m = m_stepNumber - 2; m >= 0; m--)
{
for (int n = 0; n <= m; n++)
{
double hold = ((1 - p) * m_v[m+1][n]) + (p * m_v[m+1][n+1]);
hold *= discount;
m_v[m][n] = dmax( hold, payOff( strike, m_s[m][n], call ) );
}
}
return m_v[0][0];
}
double
BinomialTree::delta( double strike, // option strike
double assetPrice, // underlying asset's current value
double vol, // volatility
double rate, // risk free rate of interest
double maturity, // time to maturity (year fraction)
double yield, // annualised yield of underlying asset over life of option (continuous compounded)
bool call )
{
value( strike, assetPrice, vol, rate, maturity, yield, call );
double dt = maturity / double(m_stepNumber-1);
double sqrtDt = sqrt(dt);
double u = exp( vol * sqrtDt );
double d = exp( -vol * sqrtDt );
double delta = (m_v[1][1] - m_v[1][0]) / ((assetPrice * u) - (assetPrice * d));
return delta;
}
double
BinomialTree::gamma( double strike, // option strike
double assetPrice, // underlying asset's current value
double vol, // volatility
double rate, // risk free rate of interest
double maturity, // time to maturity (year fraction)
double yield ) // annualised yield of underlying asset over life of option (continuous compounded)
{
value( strike, assetPrice, vol, rate, maturity, yield, true );
double dt = maturity / double(m_stepNumber-1);
double sqrtDt = sqrt(dt);
double u = exp( vol * sqrtDt );
double d = exp( -vol * sqrtDt );
double h = 0.5 * ((assetPrice * u * u) - (assetPrice * d * d));
double delta1 = (m_v[2][2] - m_v[2][1]) / ((assetPrice * u * u) - assetPrice);
double delta2 = (m_v[2][1] - m_v[2][0]) / (assetPrice - (assetPrice * d * d));
return (delta1 - delta2) / h;
}
double
BinomialTree::theta( double strike, // option strike
double assetPrice, // underlying asset's current value
double vol, // volatility
double rate, // risk free rate of interest
double maturity, // time to maturity (year fraction)
double yield, // annualised yield of underlying asset over life of option (continuous compounded)
bool call )
{
value( strike, assetPrice, vol, rate, maturity, yield, call );
double dt = maturity / double(m_stepNumber-1);
double theta = (m_v[2][1] - m_v[0][0]) / (2.0 * dt);
return theta;
}
double
BinomialTree::rho( double strike, // option strike
double assetPrice, // underlying asset's current value
double vol, // volatility
double rate, // risk free rate of interest
double maturity, // time to maturity (year fraction)
double yield, // annualised yield of underlying asset over life of option (continuous compounded)
bool call )
{
double deltaR = 0.00001;
double f0 = value( strike, assetPrice, vol, rate, maturity, yield, call );
double f1 = value( strike, assetPrice, vol, rate + deltaR, maturity, yield, call );
return ((f0 - f1) / deltaR) / 100.0; // express as decimal not percentage
}
double
BinomialTree::vega( double strike, // option strike
double assetPrice, // underlying asset's current value
double vol, // volatility
double rate, // risk free rate of interest
double maturity, // time to maturity (year fraction)
double yield ) // annualised yield of underlying asset over life of option (continuous compounded)
{
double deltaV = 0.00001;
double f0 = value( strike, assetPrice, vol, rate, maturity, yield, true );
double f1 = value( strike, assetPrice, vol + deltaV, rate, maturity, yield, true );
return ((f0 - f1) / deltaV) / 100.0; // express as decimal not percentage
}
///