In [3]:

```
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import datetime
```

The randomly selected asset price:

In [4]:

```
def generate_brownian_asset_price(S, sigma, r, T):
"""
S : current stock
sigma : volatility
r : rate
T : time
"""
ret = S * np.exp((r - 0.5 * sigma**2) * T + sigma * np.sqrt(T) * np.random.randn())
return ret
```

The basic call payout:

In [5]:

```
def call_payout(S_T, K):
"""
S_T : asset price (prediction) at time T
K : strike price
"""
return max(0, S_T - K)
```

In [6]:

```
S = 120
sigma = 0.25
r = 0.0021
T = (datetime.date(2015,10,16) - datetime.date(2015,9,17)).days / 365.0
K = 120
```

Now we can run this once. But that doesn't give any confidence. So we'll run it *many* times.

In [10]:

```
nsim = 10000
payout = np.zeros((nsim,))
discount = np.exp(-r * T)
```

In [11]:

```
for i in range(nsim):
S_T = generate_brownian_asset_price(S, sigma, r, T)
payout[i] = call_payout(S_T, K)
```

In [12]:

```
price = discount * payout.sum() / nsim
print("price: %g" % price)
```

*may* be better. So 3.3 or so seems reasonable.

Let's look at how many payouts were at each "value"

In [15]:

```
_ = plt.hist(payout, bins=100, log=True)
plt.xlabel('payout')
plt.ylabel('frequency')
```

Out[15]:

Notice that

- There are many zeros. This means that the simulation landed with a price below the strike.
- There's the potential for a much larger payout than 3.3

It might be easier to look at it here:

In [16]:

```
plt.plot(np.sort(payout))
```

Out[16]:

In [ ]:

```
```