@@ -85,7 +85,7 @@ Suppose that, after analyzing the data, we guess that $S$ is well
85
85
represented by a lognormal distribution with parameters $\mu, \sigma$ .
86
86
87
87
* $S$ has the same distribution as $\exp(\mu + \sigma Z)$ where $Z$ is standard normal.
88
- * we write this statement as $S \sim LN(\mu, \sigma)$.
88
+ * We write this statement as $S \sim LN(\mu, \sigma)$.
89
89
90
90
Any good reference on statistics (such as
91
91
[ Wikipedia] ( https://en.wikipedia.org/wiki/Log-normal_distribution ) ) will tell
@@ -136,12 +136,12 @@ But fortunately there's an easy way to do this, at least approximately.
136
136
This is the Monte Carlo method, which runs as follows:
137
137
138
138
1 . Generate $n$ independent draws of $X_1$, $X_2$ and $X_3$ on a computer,
139
- 1 . Use these draws to generate $n$ independent draws of $S$, and
140
- 1 . Take the average value of these draws of $S$.
139
+ 1 . use these draws to generate $n$ independent draws of $S$, and
140
+ 1 . take the average value of these draws of $S$.
141
141
142
142
This average will be close to the true mean when $n$ is large.
143
143
144
- This is due to the law of large numbers, which we discussed in {doc}` another lecture < lln_clt> ` .
144
+ This is due to the law of large numbers, which we discussed in {doc}` lln_clt ` .
145
145
146
146
We use the following values for $p$ and each $\mu_i$ and $\sigma_i$.
147
147
@@ -238,15 +238,15 @@ compute_mean_vectorized(n=10_000_000)
238
238
239
239
240
240
241
- ## Pricing a european call option under risk neutrality
241
+ ## Pricing a European call option under risk neutrality
242
242
243
243
Next we are going to price a European call option under risk neutrality.
244
244
245
245
Let's first discuss risk neutrality and then consider European options.
246
246
247
247
248
248
249
- ### Risk-Neutral Pricing
249
+ ### Risk-neutral pricing
250
250
251
251
When we use risk-neutral pricing, we determine the price of a given asset
252
252
according to its expected payoff:
@@ -426,7 +426,7 @@ $$ \ln \frac{S_{t+1}}{S_t} = \mu + \sigma \xi_{t+1} $$
426
426
427
427
where
428
428
429
- * $S_0$ is normally distributed and
429
+ * $S_0$ is lognormally distributed and
430
430
* $\{ \xi_t \} $ is IID and standard normal.
431
431
432
432
@@ -485,23 +485,23 @@ Here $\{\eta_t\}$ is also IID and standard normal.
485
485
For the dynamic model, we adopt the following parameter values.
486
486
487
487
``` {code-cell} ipython3
488
- μ = 0.0001
489
- ρ = 0.1
490
- ν = 0.001
491
- S0 = 10
492
- h0 = 0
488
+ default_μ = 0.0001
489
+ default_ρ = 0.1
490
+ default_ν = 0.001
491
+ default_S0 = 10
492
+ default_h0 = 0
493
493
```
494
494
495
495
496
496
497
- (Here ` S0 ` is $S_0$ and ` h0 ` is $h_0$.)
497
+ (Here ` default_S0 ` is $S_0$ and ` default_h0 ` is $h_0$.)
498
498
499
499
For the option we use the following defaults.
500
500
501
501
``` {code-cell} ipython3
502
- K = 100
503
- n = 10
504
- β = 0.95
502
+ default_K = 100
503
+ default_n = 10
504
+ default_β = 0.95
505
505
```
506
506
507
507
@@ -515,7 +515,7 @@ $$ s_{t+1} = s_t + \mu + \exp(h_t) \xi_{t+1} $$
515
515
Here is a function to simulate a path using this equation:
516
516
517
517
``` {code-cell} ipython3
518
- def simulate_asset_price_path(μ=μ , S0=S0 , h0=h0 , n=n , ρ=ρ , ν=ν ):
518
+ def simulate_asset_price_path(μ=default_μ , S0=default_S0 , h0=default_h0 , n=default_n , ρ=default_ρ , ν=default_ν ):
519
519
s = np.empty(n+1)
520
520
s[0] = np.log(S0)
521
521
568
568
Here's a version using Python loops.
569
569
570
570
``` {code-cell} ipython3
571
- def compute_call_price(β=β ,
572
- μ=μ ,
573
- S0=S0 ,
574
- h0=h0 ,
575
- K=K ,
576
- n=n ,
577
- ρ=ρ ,
578
- ν=ν ,
571
+ def compute_call_price(β=default_β ,
572
+ μ=default_μ ,
573
+ S0=default_S0 ,
574
+ h0=default_h0 ,
575
+ K=default_K ,
576
+ n=default_n ,
577
+ ρ=default_ρ ,
578
+ ν=default_ν ,
579
579
M=10_000):
580
580
current_sum = 0.0
581
581
# For each sample path
@@ -617,14 +617,14 @@ Your task is to write a faster version of this code using NumPy.
617
617
```
618
618
619
619
``` {code-cell} ipython3
620
- def compute_call_price (β=β ,
621
- μ=μ ,
622
- S0=S0 ,
623
- h0=h0 ,
624
- K=K ,
625
- n=n ,
626
- ρ=ρ ,
627
- ν=ν ,
620
+ def compute_call_price_vector (β=default_β ,
621
+ μ=default_μ ,
622
+ S0=default_S0 ,
623
+ h0=default_h0 ,
624
+ K=default_K ,
625
+ n=default_n ,
626
+ ρ=default_ρ ,
627
+ ν=default_ν ,
628
628
M=10_000):
629
629
630
630
s = np.full(M, np.log(S0))
@@ -640,7 +640,7 @@ def compute_call_price(β=β,
640
640
641
641
``` {code-cell} ipython3
642
642
%%time
643
- compute_call_price ()
643
+ compute_call_price_vector ()
644
644
```
645
645
646
646
@@ -676,27 +676,27 @@ Use the dynamics defined in {eq}`s_mc_dyms` to price the European call option.
676
676
```
677
677
678
678
``` {code-cell} ipython3
679
- μ = 0.0001
680
- ρ = 0.1
681
- ν = 0.001
682
- S0 = 10
683
- h0 = 0
684
- K = 100
685
- n = 10
686
- β = 0.95
687
- bp = 120
679
+ default_μ = 0.0001
680
+ default_ρ = 0.1
681
+ default_ν = 0.001
682
+ default_S0 = 10
683
+ default_h0 = 0
684
+ default_K = 100
685
+ default_n = 10
686
+ default_β = 0.95
687
+ default_bp = 120
688
688
```
689
689
690
690
``` {code-cell} ipython3
691
- def compute_call_price_with_barrier(β=β ,
692
- μ=μ ,
693
- S0=S0 ,
694
- h0=h0 ,
695
- K=K ,
696
- n=n ,
697
- ρ=ρ ,
698
- ν=ν ,
699
- bp=bp ,
691
+ def compute_call_price_with_barrier(β=default_β ,
692
+ μ=default_μ ,
693
+ S0=default_S0 ,
694
+ h0=default_h0 ,
695
+ K=default_K ,
696
+ n=default_n ,
697
+ ρ=default_ρ ,
698
+ ν=default_ν ,
699
+ bp=default_bp ,
700
700
M=50_000):
701
701
current_sum = 0.0
702
702
# For each sample path
@@ -731,15 +731,15 @@ def compute_call_price_with_barrier(β=β,
731
731
Let's look at the vectorized version which is faster than using Python loops.
732
732
733
733
``` {code-cell} ipython3
734
- def compute_call_price_with_barrier_vector(β=β ,
735
- μ=μ ,
736
- S0=S0 ,
737
- h0=h0 ,
738
- K=K ,
739
- n=n ,
740
- ρ=ρ ,
741
- ν=ν ,
742
- bp=bp ,
734
+ def compute_call_price_with_barrier_vector(β=default_β ,
735
+ μ=default_μ ,
736
+ S0=default_S0 ,
737
+ h0=default_h0 ,
738
+ K=default_K ,
739
+ n=default_n ,
740
+ ρ=default_ρ ,
741
+ ν=default_ν ,
742
+ bp=default_bp ,
743
743
M=50_000):
744
744
s = np.full(M, np.log(S0))
745
745
h = np.full(M, h0)
0 commit comments