@@ -12,7 +12,6 @@ kernelspec:
12
12
---
13
13
14
14
15
-
16
15
# Monte Carlo and Option Pricing
17
16
18
17
## Overview
@@ -49,7 +48,6 @@ from numpy.random import randn
49
48
```
50
49
51
50
52
-
53
51
## An Introduction to Monte Carlo
54
52
55
53
In this section we describe how Monte Carlo can be used to compute
@@ -153,7 +151,6 @@ p = 0.5
153
151
```
154
152
155
153
156
-
157
154
#### A Routine using Loops in Python
158
155
159
156
@@ -177,7 +174,6 @@ S / n
177
174
```
178
175
179
176
180
-
181
177
We can also construct a function that contains these operations:
182
178
183
179
``` {code-cell} ipython3
@@ -192,15 +188,13 @@ def compute_mean(n=1_000_000):
192
188
```
193
189
194
190
195
-
196
191
Now let's call it.
197
192
198
193
``` {code-cell} ipython3
199
194
compute_mean()
200
195
```
201
196
202
197
203
-
204
198
### A Vectorized Routine
205
199
206
200
If we want a more accurate estimate we should increase $n$.
@@ -225,7 +219,6 @@ compute_mean_vectorized()
225
219
```
226
220
227
221
228
-
229
222
Notice that this routine is much faster.
230
223
231
224
We can increase $n$ to get more accuracy and still have reasonable speed:
@@ -237,7 +230,6 @@ compute_mean_vectorized(n=10_000_000)
237
230
```
238
231
239
232
240
-
241
233
## Pricing a European Call Option under Risk Neutrality
242
234
243
235
Next we are going to price a European call option under risk neutrality.
284
276
$$
285
277
286
278
287
-
288
279
### A Comment on Risk
289
280
290
281
As suggested by the name, the risk-neutral price ignores risk.
@@ -306,7 +297,6 @@ Nonetheless, the risk-neutral price is an important benchmark, which economists
306
297
and financial market participants try to calculate every day.
307
298
308
299
309
-
310
300
### Discounting
311
301
312
302
Another thing we ignored in the previous discussion was time.
336
326
$$
337
327
338
328
339
-
340
329
### European Call Options
341
330
342
331
Now let's price a European call option.
@@ -388,15 +377,13 @@ n = 10
388
377
```
389
378
390
379
391
-
392
380
We set the simulation size to
393
381
394
382
``` {code-cell} ipython3
395
383
M = 10_000_000
396
384
```
397
385
398
386
399
-
400
387
Here is our code
401
388
402
389
``` {code-cell} ipython3
@@ -407,7 +394,6 @@ print(f"The Monte Carlo option price is approximately {P:3f}")
407
394
```
408
395
409
396
410
-
411
397
## Pricing Via a Dynamic Model
412
398
413
399
In this exercise we investigate a more realistic model for the share price $S_n$.
479
465
Here $\{ \eta_t\} $ is also IID and standard normal.
480
466
481
467
482
-
483
468
### Default Parameters
484
469
485
470
For the dynamic model, we adopt the following parameter values.
@@ -493,7 +478,6 @@ h0 = 0
493
478
```
494
479
495
480
496
-
497
481
(Here ` S0 ` is $S_0$ and ` h0 ` is $h_0$.)
498
482
499
483
For the option we use the following defaults.
@@ -505,7 +489,6 @@ n = 10
505
489
```
506
490
507
491
508
-
509
492
### Visualizations
510
493
511
494
With $s_t := \ln S_t$, the price dynamics become
@@ -528,7 +511,6 @@ def simulate_asset_price_path(μ=μ, S0=S0, h0=h0, n=n, ρ=ρ, ν=ν):
528
511
```
529
512
530
513
531
-
532
514
Here we plot the paths and the log of the paths.
533
515
534
516
``` {code-cell} ipython3
@@ -547,7 +529,6 @@ plt.show()
547
529
```
548
530
549
531
550
-
551
532
### Computing the Price
552
533
553
534
Now that our model is more complicated, we cannot easily determine the
@@ -598,7 +579,6 @@ compute_call_price()
598
579
```
599
580
600
581
601
-
602
582
## Exercises
603
583
604
584
``` {exercise}
@@ -644,7 +624,6 @@ compute_call_price()
644
624
```
645
625
646
626
647
-
648
627
Notice that this version is faster than the one using a Python loop.
649
628
650
629
Now let's try with larger $M$ to get a more accurate calculation.
@@ -655,7 +634,6 @@ compute_call_price(M=10_000_000)
655
634
```
656
635
657
636
658
-
659
637
``` {solution-end}
660
638
```
661
639
@@ -703,17 +681,18 @@ def compute_call_price_with_barrier(β=β,
703
681
for m in range(M):
704
682
s = np.log(S0)
705
683
h = h0
706
- is_null = False
684
+ payoff = 0
707
685
# Simulate forward in time
708
686
for t in range(n):
709
687
s = s + μ + np.exp(h) * randn()
710
688
h = ρ * h + ν * randn()
711
689
if np.exp(s) > bp:
712
- is_null = True
713
-
714
- if not is_null:
715
- # And add the value max{S_n - K, 0} to current_sum
716
- current_sum += np.maximum(np.exp(s) - K, 0)
690
+ payoff = 0
691
+ break
692
+ else:
693
+ payoff = np.maximum(np.exp(s) - K, 0)
694
+ # And add the payoff to current_sum
695
+ current_sum += payoff
717
696
718
697
return β**n * current_sum / M
719
698
```
0 commit comments