Skip to content

Commit

Permalink
Merge pull request #417 from QuantEcon/update_monte_carlo
Browse files Browse the repository at this point in the history
[monte_carlo] updates and editorial suggestions
  • Loading branch information
jstac authored Apr 12, 2024
2 parents 8c53ec8 + 0b46db1 commit 240e65f
Showing 1 changed file with 61 additions and 61 deletions.
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,
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
```



(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

1 comment on commit 240e65f

@github-actions
Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.