-
Notifications
You must be signed in to change notification settings - Fork 0
/
Lattice Pricing
192 lines (187 loc) · 10.5 KB
/
Lattice Pricing
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//Knock-In barrier options have correct prices, but the table representing the tree does not fully display option values where nodes rise above barrier due to path dependency.
binTree:{[d;u;t;deltaT;r;y;s;k]
//returns European put/call binomial tree in table form
//d--downstep multiplier
//u--upstep multiplier
//t--timesteps(including first)
//deltaT--number of timesteps per year
//r--risk free rate(for cont. dividends, 0 if none)
//y--yield
//s--Stock Price
//k--strike
nodeList:asc raze (til t+1) #'(til t+1); //gives the sorted attribute
$[d=1%u;q:((exp(deltaT*r-y))-d)%(u-d);q:.5]; //risk neutral "probability"
upsteps:raze reverse each til each distinct nodeList;
downsteps:raze til each distinct nodeList;
stockPrice:s*xexp[u;upsteps]*xexp[d;downsteps];
//initialization for calls
callPrice:0|(neg k)+(max nodeList)#reverse stockPrice;
list:(-2_til count nodeList) except (-1+max nodeList),(-1+(max nodeList) +\(reverse til (max nodeList)));
counter:-1_reverse til (max nodeList);
//iterate for each timestep
do[-1 + max nodeList;callPrice,:(exp(neg r*deltaT))*{[n;q;callPrice]((1-q)*callPrice[n])+(q*callPrice[n+1])}[(first counter)#list;q;callPrice];list:(first counter)_list;counter:1_counter];
callPrice:reverse callPrice;
//initialization for puts
putPrice:0|k-(max nodeList)#reverse stockPrice;
list:(-2_til count nodeList) except (-1+max nodeList),(-1+(max nodeList) +\(reverse til (max nodeList)));
counter:-1_reverse til (max nodeList);
//iterate for each timestep
do[-1 + max nodeList;putPrice,:(exp(neg r*deltaT))*{[n;q;putPrice]((1-q)*putPrice[n])+(q*putPrice[n+1])}[(first counter)#list;q;putPrice];list:(first counter)_list;counter:1_counter];
putPrice:reverse putPrice;
tree:flip `time`upsteps`downsteps`stockPrice`call`put!(nodeList;upsteps;downsteps;stockPrice;callPrice;putPrice);
tree};
binTreeAmerican:{[d;u;t;deltaT;r;y;s;k]
//returns American put/call binomial tree in table form. Exercise when call=exCall, put=exPut
//d--downstep multiplier
//u--upstep multiplier
//t--timesteps(including first)
//deltaT--number of timesteps per year
//r--risk free rate(for cont. dividends, 0 if none)
//y--yield
//s--Stock Price
//k--strike
tree:binTree[d;u;t;deltaT;r;y;s;k];
$[d=1%u;q:((exp(deltaT*r-y))-d)%(u-d);q:.5]; //risk neutral "probability"
call:exec call from tree;
put:exec put from tree;
time:exec time from tree;
stockPrice:exec stockPrice from tree;
//initialization for calls
exCall:(exp(r*deltaT*(neg time)+ max time))*0|stockPrice-k;
tree:update exCall:exCall from tree;
exCall:reverse exCall;
callPrice:0|(neg k)+(max time)#reverse stockPrice;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (call)
do[-1 + max time;callPrice,:(exp(neg r*deltaT))*{[n;q;callPrice]((1-q)*callPrice[n])+(q*callPrice[n+1])}[(first counter)#list;q;callPrice];callPrice:callPrice[til count callPrice]|exCall[til count callPrice];list:(first counter)_list;counter:1_counter];
callPrice:reverse callPrice;
//initialization for puts
putPrice:0|k-(max time)#reverse stockPrice;
exPut:(exp(r*deltaT*(neg time)+ max time))*0|k-stockPrice;
tree:update exPut:exPut from tree;
exPut:reverse exPut;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (put)
do[-1 + max time;putPrice,:(exp(neg r*deltaT))*{[n;q;putPrice]((1-q)*putPrice[n])+(q*putPrice[n+1])}[(first counter)#list;q;putPrice];putPrice:putPrice[til count putPrice]|exPut[til count putPrice];list:(first counter)_list;counter:1_counter];
putPrice:reverse putPrice;
tree:update call:callPrice from tree;
tree:update put:putPrice from tree;
tree};
barrierUpOutEur:{[dict]
//dict has keys d,u,t,deltaT,r,y,s,k,b
//downstep, upstep, timesteps(including first), timesteps per year, risk free rate, yield, stock, strike, barrier
t:"i"$dict[`t];
tree:binTree[dict[`d];dict[`u];t;dict[`deltaT];dict[`r];dict[`y];dict[`s];dict[`k]];
tree:update call:0f from tree where stockPrice>dict[`b];
tree:update put:0f from tree where stockPrice>dict[`b];
$[dict[`d]=1%dict[`u];q:((exp(dict[`deltaT]*dict[`r]-dict[`y]))-dict[`d])%(dict[`u]-dict[`d]);q:.5]; //risk neutral "probability"
call:exec call from tree;
put:exec put from tree;
time:exec time from tree;
stockPrice:reverse exec stockPrice from tree;
//initialization for calls
callPrice:(max time)#reverse exec call from tree;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (call)
do[-1 + max time;callPrice,:(exp(neg dict[`r]*dict[`deltaT]))*{[n;q;callPrice]((1-q)*callPrice[n])+(q*callPrice[n+1])}[(first counter)#list;q;callPrice];callPrice[where stockPrice[til count callPrice]>dict[`b]]:0f;list:(first counter)_list;counter:1_counter];
callPrice:reverse callPrice;
tree:update call:callPrice from tree;
//initialization for puts
putPrice:(max time)#reverse exec put from tree;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (put)
do[-1 + max time;putPrice,:(exp(neg dict[`r]*dict[`deltaT]))*{[n;q;putPrice]((1-q)*putPrice[n])+(q*putPrice[n+1])}[(first counter)#list;q;putPrice];putPrice[where stockPrice[til count putPrice]>dict[`b]]:0f;list:(first counter)_list;counter:1_counter];
putPrice:reverse putPrice;
tree:update put:putPrice from tree;
tree};
barrierUpInEur:{[dict]
//dict has keys d,u,t,deltaT,r,y,s,k,b
//downstep, upstep, timesteps(including first), timesteps per year, risk free rate, yield, stock, strike, barrier
t:"i"$dict[`t];
tree:binTree[dict[`d];dict[`u];t;dict[`deltaT];dict[`r];dict[`y];dict[`s];dict[`k]];
tree:update call:0f from tree where stockPrice<dict[`b];
tree:update put:0f from tree where stockPrice<dict[`b];
$[dict[`d]=1%dict[`u];q:((exp(dict[`deltaT]*dict[`r]-dict[`y]))-dict[`d])%(dict[`u]-dict[`d]);q:.5]; //risk neutral "probability"
call:exec call from tree;
put:exec put from tree;
time:exec time from tree;
stockPrice:reverse exec stockPrice from tree;
//initialization for calls
callPrice:(max time)#reverse exec call from tree;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (call)
do[-1 + max time;callPrice,:(exp(neg dict[`r]*dict[`deltaT]))*{[n;q;callPrice]((1-q)*callPrice[n])+(q*callPrice[n+1])}[(first counter)#list;q;callPrice];list:(first counter)_list;counter:1_counter];
callPrice:reverse callPrice;
tree:update call:callPrice from tree;
//initialization for puts
putPrice:(max time)#reverse exec put from tree;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (put)
do[-1 + max time;putPrice,:(exp(neg dict[`r]*dict[`deltaT]))*{[n;q;putPrice]((1-q)*putPrice[n])+(q*putPrice[n+1])}[(first counter)#list;q;putPrice];list:(first counter)_list;counter:1_counter];
putPrice:reverse putPrice;
tree:update put:putPrice from tree;
tree};
barrierDownOutEur:{[dict]
//dict has keys d,u,t,deltaT,r,y,s,k,b
//downstep, upstep, timesteps(including first), timesteps per year, risk free rate, yield, stock, strike, barrier
t:"i"$dict[`t];
tree:binTree[dict[`d];dict[`u];t;dict[`deltaT];dict[`r];dict[`y];dict[`s];dict[`k]];
tree:update call:0f from tree where stockPrice<dict[`b];
tree:update put:0f from tree where stockPrice<dict[`b];
$[dict[`d]=1%dict[`u];q:((exp(dict[`deltaT]*dict[`r]-dict[`y]))-dict[`d])%(dict[`u]-dict[`d]);q:.5]; //risk neutral "probability"
call:exec call from tree;
put:exec put from tree;
time:exec time from tree;
stockPrice:reverse exec stockPrice from tree;
//initialization for calls
callPrice:(max time)#reverse exec call from tree;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (call)
do[-1 + max time;callPrice,:(exp(neg dict[`r]*dict[`deltaT]))*{[n;q;callPrice]((1-q)*callPrice[n])+(q*callPrice[n+1])}[(first counter)#list;q;callPrice];callPrice[where stockPrice[til count callPrice]<dict[`b]]:0f;list:(first counter)_list;counter:1_counter];
callPrice:reverse callPrice;
tree:update call:callPrice from tree;
//initialization for puts
putPrice:(max time)#reverse exec put from tree;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (put)
do[-1 + max time;putPrice,:(exp(neg dict[`r]*dict[`deltaT]))*{[n;q;putPrice]((1-q)*putPrice[n])+(q*putPrice[n+1])}[(first counter)#list;q;putPrice];putPrice[where stockPrice[til count putPrice]<dict[`b]]:0f;list:(first counter)_list;counter:1_counter];
putPrice:reverse putPrice;
tree:update put:putPrice from tree;
tree};
barrierDownInEur:{[dict]
//dict has keys d,u,t,deltaT,r,y,s,k,b
//downstep, upstep, timesteps(including first), timesteps per year, risk free rate, yield, stock, strike, barrier
t:"i"$dict[`t];
tree:binTree[dict[`d];dict[`u];t;dict[`deltaT];dict[`r];dict[`y];dict[`s];dict[`k]];
tree:update call:0f from tree where stockPrice>dict[`b];
tree:update put:0f from tree where stockPrice>dict[`b];
$[dict[`d]=1%dict[`u];q:((exp(dict[`deltaT]*dict[`r]-dict[`y]))-dict[`d])%(dict[`u]-dict[`d]);q:.5]; //risk neutral "probability"
call:exec call from tree;
put:exec put from tree;
time:exec time from tree;
stockPrice:reverse exec stockPrice from tree;
//initialization for calls
callPrice:(max time)#reverse exec call from tree;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (call)
do[-1 + max time;callPrice,:(exp(neg dict[`r]*dict[`deltaT]))*{[n;q;callPrice]((1-q)*callPrice[n])+(q*callPrice[n+1])}[(first counter)#list;q;callPrice];list:(first counter)_list;counter:1_counter];
callPrice:reverse callPrice;
tree:update call:callPrice from tree;
//initialization for puts
putPrice:(max time)#reverse exec put from tree;
list:(-2_til count time) except (-1+max time),(-1+(max time) +\(reverse til (max time)));
counter:-1_reverse til (max time);
//iterate for each timestep (put)
do[-1 + max time;putPrice,:(exp(neg dict[`r]*dict[`deltaT]))*{[n;q;putPrice]((1-q)*putPrice[n])+(q*putPrice[n+1])}[(first counter)#list;q;putPrice];list:(first counter)_list;counter:1_counter];
putPrice:reverse putPrice;
tree:update put:putPrice from tree;
tree};