number of option valuations/strikes
”’
strikes = np.linspace( 80 , 120 , n)
option_values = []
for strike in strikes:
value = view.apply_async(bsm_mcs_valuation, strike)
option_values.append(value)
c.wait(option_values)
return strikes, option_values
There are two major differences to note. The first is that the valuation function is applied
asynchronously via view.apply_sync to our cluster view, which in effect initiates the
parallel valuation of all options at once. Of course, not all options can be valued in parallel
because there are (generally) not enough cores/threads available. Therefore, we have to
wait until the queue is completely finished; this is accomplished by the wait method of the
Client object c. When all results are available, the function returns, as before, list
objects containing the strike prices and the valuation results, respectively.
Execution of the parallel valuation function yields a productivity that ideally scales
linearly with the number of cores (threads) available. For example, having eight cores
(threads) available reduces the execution time to maximally one-eighth of the time needed
for the sequential calculation:
In [ 41 ]: %time strikes, option_values_obj = par_value(n)
Out[41]: CPU times: user 415 ms, sys: 30 ms, total: 445 ms
Wall time: 1.88 s
The parallel execution does not return option values directly; it rather returns more
complex result objects:
In [ 42 ]: option_values_obj[ 0 ].metadata
Out[42]: {‘after’: [],
‘completed’: datetime.datetime(2014, 9, 28, 16, 6, 54, 93979),
‘data’: {},
‘engine_id’: 5,
‘engine_uuid’: u‘6b64aebb-39d5-49aa-9466-e6ab37d3b2c9’,
‘follow’: [],
‘msg_id’: u’c7a44c22-b4bd-46d7-ba5e-34690f178fa9’,
‘outputs’: [],
‘outputs_ready’: True,
‘pyerr’: None,
‘pyin’: None,
‘pyout’: None,
‘received’: datetime.datetime(2014, 9, 28, 16, 6, 54, 97195),
‘started’: datetime.datetime(2014, 9, 28, 16, 6, 53, 921633),
‘status’: u’ok’,
‘stderr’: ”,
‘stdout’: ”,
‘submitted’: datetime.datetime(2014, 9, 28, 16, 6, 53, 917290)}
The valuation result itself is stored in the result attribute of the object:
In [ 43 ]: option_values_obj[ 0 ].result
Out[43]: 24.436651486350289
To arrive at a results list as with the sequential calculation, we need to read the single
results out from the returned objects:
In [ 44 ]: option_values_par = []
for res in option_values_obj:
option_values_par.append(res.result)
This could have been done, of course, in the parallel valuation loop directly. Figure 8-3
compares the valuation results of the sequential calculation with those of the parallel
calculation. Differences are due to numerical issues concerning the Monte Carlo valuation: