forked from TRBD/option_pricing_cython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpy_opt_pricing.py
80 lines (76 loc) · 2.67 KB
/
py_opt_pricing.py
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
import numpy as np
def option_price_american_binomial(flag,
s,
k,
r,
sigma,
t,
steps):
R = np.exp(r * (t / steps))
rInv = 1. / R
u = np.exp(sigma * np.sqrt(t / steps))
uu = u * u
d = 1. / u
p_up = (R - d) / (u - d)
p_down = 1.0 - p_up
prices = np.empty(steps + 1)
option_values = np.empty(steps + 1)
prices[0] = s * (d**steps)
for i in range(1, steps + 1):
prices[i] = uu * prices[i-1]
for i in range(steps+1):
option_values[i] = np.max([0.0, flag*(prices[i] - k)])
for step in range(steps-1, -1, -1):
for i in range(step+1):
option_values[i] = (p_up * option_values[i+1] + p_down * option_values[i]) * rInv
prices[i] = d * prices[i+1]
option_values[i] = np.max([option_values[i], flag*(prices[i] - k)])
return option_values[i]
def option_price_american_discrete_divs(flag,
s,
k,
r,
sigma,
t,
steps,
div_times,
div_amounts):
no_dividends = len(div_times)
if no_dividends == 0:
return option_price_american_binomial(flag, s, k, r, sigma, t, steps)
steps_before_dividend = int((div_times[0] / t) * steps)
R = np.exp(r * (t / steps))
Rinv = 1. / R
u = np.exp(sigma * np.sqrt(t/ steps))
d = 1. / u
pUp = (R-d)/(u-d)
pDown = 1.0 - pUp
dividend_amount = div_amounts[0]
tmp_dividend_times = np.empty(no_dividends - 1)
tmp_dividend_amounts = np.empty(no_dividends - 1)
for i in range(no_dividends - 1):
tmp_dividend_times[i] = div_times[i+1]
tmp_dividend_amounts[i] = div_amounts[i+1]
prices = np.empty(steps_before_dividend + 1)
option_values = np.empty(steps_before_dividend + 1)
prices[0] = s * d ** (steps_before_dividend)
for i in range(1, steps_before_dividend + 1):
prices[i] = u * u * prices[i-1]
for i in range(steps_before_dividend+1):
value_alive = option_price_american_discrete_divs(
flag,
prices[i] - dividend_amount,
k,
r,
sigma,
t - div_times[0],
steps - steps_before_dividend,
tmp_dividend_times,
tmp_dividend_amounts)
option_values[i] = np.max([value_alive, flag*(prices[i] - k)])
for step in range(steps_before_dividend - 1, -1, -1):
for i in range(step+1):
prices[i] = d * prices[i+1]
option_values[i] = (pDown * option_values[i] + pUp * option_values[i+1]) * Rinv
option_values[i] = np.max([option_values[i], flag*(prices[i] - k)])
return option_values[0]