import numpy as np import matplotlib.pyplot as plt %matplotlib inline import datetime
The randomly selected asset price:
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:
def call_payout(S_T, K): """ S_T : asset price (prediction) at time T K : strike price """ return max(0, S_T - K)
Now set the price at 120, the volatility at 25%, the rate at 0.21%, and the strike price at 120 on Oct 16, 2015.
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.
nsim = 10000 payout = np.zeros((nsim,)) discount = np.exp(-r * T)
for i in range(nsim): S_T = generate_brownian_asset_price(S, sigma, r, T) payout[i] = call_payout(S_T, K)
price = discount * payout.sum() / nsim print("price: %g" % price)
Notice this price seem "reasonable". If we had no interest and no volatility, then the price should be $2. But with interest and with volatility, one would expect this to be more expensive because the payout may be better. So 3.3 or so seems reasonable.
Let's look at how many payouts were at each "value"
_ = plt.hist(payout, bins=100, log=True) plt.xlabel('payout') plt.ylabel('frequency')
<matplotlib.text.Text at 0x10fa56d68>
It might be easier to look at it here:
[<matplotlib.lines.Line2D at 0x10f8fadd8>]