C = np.polyval(rg, instrument_values[t])
optimal decision step:
if condition is satisfied (inner value > regressed cont. value)
then take inner value; take actual cont. value otherwise
V = np.where(inner_values[t] > C, inner_values[t], V df)
df = discount_factors[ 0 , 1 ] / discount_factors[ 1 , 1 ]
result = df np.sum(V) / len(V)
if full:
return round(result, accuracy), df * V
else:
return round(result, accuracy)
A Use Case
As has become by now the means of choice, a use case shall illustrate how to work with
the valuation_mcs_american class. The use case replicates all American option values as
presented in Table 1 of the seminal paper by Longstaff and Schwartz (2001). The
underlying is the same as before, a geometric_brownian_motion object. The starting
parameterization for the underlying is as follows:
In [ 22 ]: from dx_simulation import *
In [ 23 ]: me_gbm = market_environment(‘me_gbm’, dt.datetime( 2015 , 1 , 1 ))
In [ 24 ]: me_gbm.add_constant(‘initial_value’, 36.)
me_gbm.add_constant(‘volatility’, 0.2)
me_gbm.add_constant(‘final_date’, dt.datetime( 2016 , 12 , 31 ))
me_gbm.add_constant(‘currency’, ‘EUR’)
me_gbm.add_constant(‘frequency’, ‘W’)
# weekly frequency
me_gbm.add_constant(‘paths’, 50000 )
In [ 25 ]: csr = constant_short_rate(‘csr’, 0.06)
In [ 26 ]: me_gbm.add_curve(‘discount_curve’, csr)
In [ 27 ]: gbm = geometric_brownian_motion(‘gbm’, me_gbm)
The option type is an American put option with payoff:
In [ 28 ]: payoff_func = ‘np.maximum(strike - instrument_values, 0)’
The first option in Table 1 of the paper has a maturity of one year, and the strike price is
40 throughout:
In [ 29 ]: me_am_put = market_environment(‘me_am_put’, dt.datetime( 2015 , 1 , 1 ))
In [ 30 ]: me_am_put.add_constant(‘maturity’, dt.datetime( 2015 , 12 , 31 ))
me_am_put.add_constant(‘strike’, 40.)
me_am_put.add_constant(‘currency’, ‘EUR’)
The next step is to instantiate the valuation object based on the numerical assumptions:
In [ 31 ]: from valuation_mcs_american import valuation_mcs_american
In [ 32 ]: am_put = valuation_mcs_american(‘am_put’, underlying=gbm,
mar_env=me_am_put, payoff_func=payoff_func)
The valuation of the American put option takes much longer than the same task for the
European options. Not only have we increased the number of paths and the frequency for
the valuation, but the algorithm is much more computationally demanding due to the
backward induction and the regression per induction step. Our numerical value is pretty
close to the correct one reported in the original paper of 4.478:
In [ 33 ]: %time am_put.present_value(fixed_seed=True, bf= 5 )
Out[33]: CPU times: user 1.36 s, sys: 239 ms, total: 1.6 s
Wall time: 1.6 s
4.470627