Out[59]: 7.9500085250284336
In [ 60 ]: gbm_mcs_dyna(K=110., option=‘put’)
Out[60]: 12.629934942682004
The question is how well these simulation-based valuation approaches perform relative to
the benchmark value from the Black-Scholes-Merton valuation formula. To find out, let us
generate respective option values/estimates for a range of strike prices, using the analytical
option pricing formula for European calls in Black-Scholes-Merton found in the module
BSM_Functions.py:
In [ 61 ]: from bsm_functions import bsm_call_value
stat_res = []
dyna_res = []
anal_res = []
k_list = np.arange(80., 120.1, 5.)
np.random.seed( 200000 )
for K in k_list:
stat_res.append(gbm_mcs_stat(K))
dyna_res.append(gbm_mcs_dyna(K))
anal_res.append(bsm_call_value(S0, K, T, r, sigma))
stat_res = np.array(stat_res)
dyna_res = np.array(dyna_res)
anal_res = np.array(anal_res)
First, we compare the results from the static simulation approach with precise analytical
values:
In [ 62 ]: fig, (ax1, ax2) = plt.subplots( 2 , 1 , sharex=True, figsize=( 8 , 6 ))
ax1.plot(k_list, anal_res, ‘b’, label=‘analytical’)
ax1.plot(k_list, stat_res, ‘ro’, label=‘static’)
ax1.set_ylabel(‘European call option value’)
ax1.grid(True)
ax1.legend(loc= 0 )
ax1.set_ylim(ymin= 0 )
wi = 1.0
ax2.bar(k_list - wi / 2 , (anal_res - stat_res) / anal_res * 100 , wi)
ax2.set_xlabel(‘strike’)
ax2.set_ylabel(‘difference in %’)
ax2.set_xlim(left= 75 , right= 125 )
ax2.grid(True)
Figure 10-15 shows the results. All valuation differences are smaller than 1% absolutely.
There are both negative and positive value differences.