Exercises in Computational Finance
Yves Hilpisch
The Python Quants GmbH
10th Fixed Income Conference, Barcelona, 26. September 2014
See www.hilpisch.com.
This talk/tutorial is about new approaches for the marketing and modelling of listed volatility and variance products. The focus lies on the VSTOXX volatility index and related derivatives as well as on the just launched Variance Futures by Eurex. Topics include:
Important Milestones (I), from a rather personal perspective.
Important Milestones (II), from a rather personal perspective.
Potential problems with analytical formulae for pricing/valuation:
Sometimes significant advantages of analytical formulae for pricing/valuation:
Alleged drawbacks of alternative numerical methods (such as simulation):
On the other hand, many benefits from numerical methods (such as simulation):
Not too long ago ...
Today, we are a bit more lucky ...
A Pythonic Library for Simulation-Based Derivatives Analytics developed and maintained by The Python Quants.
General ideas and approaches:
Global Valuation at its core:
Python specifics:
We model and value a simple American put option. First the underlying.
import dx
import numpy as np
import datetime as dt
r = dx.constant_short_rate('short_rate', 0.06)
me = dx.market_environment('gbm', dt.datetime(2015, 1, 1))
me.add_constant('initial_value', 36.)
me.add_constant('volatility', 0.2)
me.add_constant('currency', 'USD') # currency
me.add_constant('frequency', 'W') # pandas date_range frequency string
me.add_constant('paths', 50000) # number of paths
me.add_constant('final_date', dt.datetime(2015, 12, 31))
me.add_curve('discount_curve', r)
gbm = dx.geometric_brownian_motion('gbm', me) # simulation object
gbm.generate_paths()
A visualization of the first ten simulated paths.
import matplotlib.pyplot as plt
%matplotlib inline
fig = plt.figure(figsize=(9, 5))
plt.plot(gbm.time_grid, gbm.get_instrument_values()[:, :10]);
plt.grid(True); fig.autofmt_xdate()
Second, the American put option.
me_put = dx.market_environment('put', gbm.pricing_date)
me_put.add_constant('maturity', gbm.final_date)
me_put.add_constant('strike', 40.)
me_put.add_constant('currency', 'USD')
put = dx.valuation_mcs_american_single(
'put', gbm, me_put,
payoff_func='np.maximum(strike - instrument_values, 0)')
Valuation and Greeks for the American put.
put.present_value()
4.432783
put.delta()
-0.6757
put.vega()
11.5551
Some sensitivities of the American put (I).
%%time
s_list = np.arange(32., 50.1, 2.)
pv = []; de = []; ve = []
for s in s_list:
put.update(initial_value=s)
pv.append(put.present_value())
de.append(put.delta())
ve.append(put.vega())
put.update(initial_value=36.)
CPU times: user 31 s, sys: 3.98 s, total: 34.9 s Wall time: 34.7 s
Some sensitivities of the American put (II).
dx.plot_option_stats(s_list, pv, de, ve)
Now a more complex, two risk factor European option.
%run dx_example.py
# sets up market environments
# and defines derivative instrument
max_call.payoff_func
# payoff of a maximum call option
# on two underlyings (European exercise)
"np.maximum(np.maximum(maturity_value['gbm'], maturity_value['jd']) - 34., 0)"
We are going to generate a Vega surface for one risk factor with respect to the initial values of both risk factors.
asset_1 = np.arange(28., 46.1, 2.)
asset_2 = asset_1
a_1, a_2 = np.meshgrid(asset_1, asset_2)
value = np.zeros_like(a_1)
%%time
vega_gbm = np.zeros_like(a_1)
for i in range(np.shape(vega_gbm)[0]):
for j in range(np.shape(vega_gbm)[1]):
max_call.update('gbm', initial_value=a_1[i, j])
max_call.update('jd', initial_value=a_2[i, j])
vega_gbm[i, j] = max_call.vega('gbm')
CPU times: user 4.47 s, sys: 250 ms, total: 4.72 s Wall time: 4.72 s
The results visualized.
dx.plot_greeks_3d([a_1, a_2, vega_gbm], ['gbm', 'jd', 'vega gbm'])
# Vega surface plot
In June 2013, Eurex launched the VSTOXX Advanced Services, a series of Python-based tutorials about the VSTOXX and related derivatives. Contents covered:
See http://www.eurexchange.com/vstoxx/ and http://www.eurexchange.com/vstoxx/app2/.
The Python Quant Platform is developed and maintained by The Python Quants. It offers Web-/browser-based data and financial analytics for individuals, teams and organizations. Free registrations are possible under http://trial.quant-platform.com.
You can freely choose your user name and password. You can then login under http://analytics.quant-platform.com, using trial as company in combination with your user name and password.
At the moment, the Python Quant Platform comprises the following components and features:
IPython Notebook provides a unified analytics environment for a couple of (domain specific) languages, like R.
%load_ext rpy2.ipython
X = np.arange(100)
Y = 2 * X + 5 + 2 * np.random.standard_normal(len(X))
%Rpush X Y
Plotting with R from within IPython.
%R plot(X, Y, pch=19, col='blue'); grid(); title("R Plot with IPython")
Doing statistics with R.
%R print(summary(lm(Y~X)))
Call: lm(formula = Y ~ X) Residuals: Min 1Q Median 3Q Max -5.6227 -1.1901 0.0544 1.4933 4.5572 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 5.429466 0.399013 13.61 <2e-16 *** X 1.992930 0.006963 286.20 <2e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 2.01 on 98 degrees of freedom Multiple R-squared: 0.9988, Adjusted R-squared: 0.9988 F-statistic: 8.191e+04 on 1 and 98 DF, p-value: < 2.2e-16
Pulling data from R to Python.
%R c = coef(lm(Y~X))
%Rpull c
c
<FloatVector - Python:0x10efdb170 / R:0x1016ee6a8> [5.429466, 1.992930]
VSTOXX implied vol-vol on 28. Dezember 2012.
VSTOXX implied vol-vol on 31. March 2014.
One of the early models for volatility option pricing has been the square-root diffusion process (SRD) as proposed by Gruenbichler Longstaff (1996):
$$ dv_{t}=\kappa (\theta -v_{t})dt+\sigma \sqrt{v_{t}}dZ_{t} $$
The meaning of the variables and parameters is
Using DX Analytics, we calibrate the SRD model to European call options on the VSTOXX. The time series data is from QI of 2014. We calibrate to 2 maturities:
To better account for the vol-vol smile implied in volatility option prices as well as for jumps, we add a log-normal jump compnent to the SRD process to end up with a square-root jump diffusion (SRJD):
$$ dv_{t}=\kappa (\theta -v_{t})dt+\sigma \sqrt{v_{t}}dZ_{t} + J_{t} v_{t} dN_{t} -r_{J}dt $$
Taking the term structure, i.e. futures prices, into account and calibrating the model to multiple maturities simulataneously. Cf. CIR+ model by Brigo Mercurio (2001).
Calibration over all maturities with +/-40% otm/itm options (total of 129 options).
To be launched rather soon with the following topics covered:
Python Quant Platform | http://quant-platform.com
Derivatives Analytics with Python | Derivatives Analytics @ Wiley Finance
Python for Finance | Python for Finance @ O'Reilly