Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[monte_carlo] updates and editorial suggestions #417

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 61 additions & 61 deletions lectures/monte_carlo.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Suppose that, after analyzing the data, we guess that $S$ is well
represented by a lognormal distribution with parameters $\mu, \sigma$ .

* $S$ has the same distribution as $\exp(\mu + \sigma Z)$ where $Z$ is standard normal.
* we write this statement as $S \sim LN(\mu, \sigma)$.
* We write this statement as $S \sim LN(\mu, \sigma)$.

Any good reference on statistics (such as
[Wikipedia](https://en.wikipedia.org/wiki/Log-normal_distribution)) will tell
Expand Down Expand Up @@ -136,12 +136,12 @@ But fortunately there's an easy way to do this, at least approximately.
This is the Monte Carlo method, which runs as follows:

1. Generate $n$ independent draws of $X_1$, $X_2$ and $X_3$ on a computer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Generate $n$ independent draws of $X_1$, $X_2$ and $X_3$ on a computer,
1. generate $n$ independent draws of $X_1$, $X_2$ and $X_3$ on a computer,

1. Use these draws to generate $n$ independent draws of $S$, and
1. Take the average value of these draws of $S$.
1. use these draws to generate $n$ independent draws of $S$, and
1. take the average value of these draws of $S$.

This average will be close to the true mean when $n$ is large.

This is due to the law of large numbers, which we discussed in {doc}`another lecture <lln_clt>`.
This is due to the law of large numbers, which we discussed in {doc}`lln_clt`.

We use the following values for $p$ and each $\mu_i$ and $\sigma_i$.

Expand Down Expand Up @@ -238,15 +238,15 @@ compute_mean_vectorized(n=10_000_000)



## Pricing a european call option under risk neutrality
## Pricing a European call option under risk neutrality

Next we are going to price a European call option under risk neutrality.

Let's first discuss risk neutrality and then consider European options.



### Risk-Neutral Pricing
### Risk-neutral pricing

When we use risk-neutral pricing, we determine the price of a given asset
according to its expected payoff:
Expand Down Expand Up @@ -426,7 +426,7 @@ $$ \ln \frac{S_{t+1}}{S_t} = \mu + \sigma \xi_{t+1} $$

where

* $S_0$ is normally distributed and
* $S_0$ is lognormally distributed and
* $\{ \xi_t \}$ is IID and standard normal.


Expand Down Expand Up @@ -485,23 +485,23 @@ Here $\{\eta_t\}$ is also IID and standard normal.
For the dynamic model, we adopt the following parameter values.

```{code-cell} ipython3
μ = 0.0001
ρ = 0.1
ν = 0.001
S0 = 10
h0 = 0
default_μ = 0.0001
default_ρ = 0.1
default_ν = 0.001
default_S0 = 10
default_h0 = 0
```
Comment on lines +488 to 493
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@longye-tian I wonder if this would be better setup as a named tuple called defaults so that would then be referenced as defaults.μ as a tidier solution.




(Here `S0` is $S_0$ and `h0` is $h_0$.)
(Here `default_S0` is $S_0$ and `default_h0` is $h_0$.)

For the option we use the following defaults.

```{code-cell} ipython3
K = 100
n = 10
β = 0.95
default_K = 100
default_n = 10
default_β = 0.95
```


Expand All @@ -515,7 +515,7 @@ $$ s_{t+1} = s_t + \mu + \exp(h_t) \xi_{t+1} $$
Here is a function to simulate a path using this equation:

```{code-cell} ipython3
def simulate_asset_price_path(μ=μ, S0=S0, h0=h0, n=n, ρ=ρ, ν=ν):
def simulate_asset_price_path(μ=default_μ, S0=default_S0, h0=default_h0, n=default_n, ρ=default_ρ, ν=default_ν):
s = np.empty(n+1)
s[0] = np.log(S0)

Expand Down Expand Up @@ -568,14 +568,14 @@ $$
Here's a version using Python loops.

```{code-cell} ipython3
def compute_call_price(β=β,
μ=μ,
S0=S0,
h0=h0,
K=K,
n=n,
ρ=ρ,
ν=ν,
def compute_call_price(β=default_β,
μ=default_μ,
S0=default_S0,
h0=default_h0,
K=default_K,
n=default_n,
ρ=default_ρ,
ν=default_ν,
M=10_000):
current_sum = 0.0
# For each sample path
Expand Down Expand Up @@ -617,14 +617,14 @@ Your task is to write a faster version of this code using NumPy.
```

```{code-cell} ipython3
def compute_call_price(β=β,
μ=μ,
S0=S0,
h0=h0,
K=K,
n=n,
ρ=ρ,
ν=ν,
def compute_call_price_vector(β=default_β,
μ=default_μ,
S0=default_S0,
h0=default_h0,
K=default_K,
n=default_n,
ρ=default_ρ,
ν=default_ν,
M=10_000):

s = np.full(M, np.log(S0))
Expand All @@ -640,7 +640,7 @@ def compute_call_price(β=β,

```{code-cell} ipython3
%%time
compute_call_price()
compute_call_price_vector()
```


Expand Down Expand Up @@ -676,27 +676,27 @@ Use the dynamics defined in {eq}`s_mc_dyms` to price the European call option.
```

```{code-cell} ipython3
μ = 0.0001
ρ = 0.1
ν = 0.001
S0 = 10
h0 = 0
K = 100
n = 10
β = 0.95
bp = 120
default_μ = 0.0001
default_ρ = 0.1
default_ν = 0.001
default_S0 = 10
default_h0 = 0
default_K = 100
default_n = 10
default_β = 0.95
default_bp = 120
```

```{code-cell} ipython3
def compute_call_price_with_barrier(β=β,
μ=μ,
S0=S0,
h0=h0,
K=K,
n=n,
ρ=ρ,
ν=ν,
bp=bp,
def compute_call_price_with_barrier(β=default_β,
μ=default_μ,
S0=default_S0,
h0=default_h0,
K=default_K,
n=default_n,
ρ=default_ρ,
ν=default_ν,
bp=default_bp,
M=50_000):
current_sum = 0.0
# For each sample path
Expand Down Expand Up @@ -731,15 +731,15 @@ def compute_call_price_with_barrier(β=β,
Let's look at the vectorized version which is faster than using Python loops.

```{code-cell} ipython3
def compute_call_price_with_barrier_vector(β=β,
μ=μ,
S0=S0,
h0=h0,
K=K,
n=n,
ρ=ρ,
ν=ν,
bp=bp,
def compute_call_price_with_barrier_vector(β=default_β,
μ=default_μ,
S0=default_S0,
h0=default_h0,
K=default_K,
n=default_n,
ρ=default_ρ,
ν=default_ν,
bp=default_bp,
M=50_000):
s = np.full(M, np.log(S0))
h = np.full(M, h0)
Expand Down
Loading