A Subjective and Biased Overview
Dr. Yves J. Hilpisch | The Python Quants GmbH
team@tpq.io | www.quant-platform.com
Quant Insights, London, 30. October 2015
From the Financial Times, 30. October 2015.
Black-Scholes-Merton (1973) SDE of geometric Brownian motion.
$$ dS_t = rS_tdt + \sigma S_t dZ_t $$Monte Carlo simulation: draw $I$ standard normally distributed random numbers $z_t^i$ and apply them to the following by Euler disctretization scheme to simulate $I$ end values of the GBM:
$$ S_{T} = S_0 \exp \left(\left( r - \frac{1}{2} \sigma^2\right) T + \sigma \sqrt{T} z_T \right) $$Latex description of Euler discretization.
S_T = S_0 \exp (( r - 0.5 \sigma^2 ) T + \sigma \sqrt{T} z_T)
Python implementation of algorithm.
import seaborn as sns; sns.set()
import warnings; warnings.simplefilter('ignore')
from pylab import *
S_0 = 100.; r = 0.01; T = 0.5; sigma = 0.2
z_T = standard_normal(10000)
S_T = S_0 * exp((r - 0.5 * sigma ** 2) * T + sigma * sqrt(T) * z_T)
Again, Latex for comparison:
S_T = S_0 \exp (( r - 0.5 \sigma^2 ) T + \sigma \sqrt{T} z_T)
Interactive visualization of simulation results.
%matplotlib inline
pyfig = figure()
hist(S_T, bins=40);
By others:
By us:
DX Analytics is a Python library for advanced financial and derivatives analytics written by The Python Quants. It is particularly suited to model multi-risk derivatives and to do a consistent valuation of portfolios of complex derivatives. It mainly uses Monte Carlo simulation since it is the only numerical method capable of valuing and risk managing complex, multi-risk derivatives books.
An example with an European maximum call option on two underlyings.
%%time
import dx
%run dx_example.py
# sets up market environments
# and defines derivative instrument
# calculates a number of numerical results
CPU times: user 5.87 s, sys: 422 ms, total: 6.29 s Wall time: 7.01 s
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)"
max_call.vega('jd')
# numerical Vega with respect
# to one risk factor
0.7999999999999119
A Vega surface for one risk factor with respect to the initial values of both risk factors.
dx.plot_greeks_3d([a_1, a_2, vega_gbm], ['gbm', 'jd', 'vega gbm'])
# Vega surface plot
This example values a portfolio with 50 (correlated) risk factors and 250 options (European/American exercise) via Monte Carlo simulation in risk-neutral fashion with stochastic short rates.
From http://www.risk.net:
"Murex provides a complete cross-asset and front-to-back offering for structured products, combining out-of-the box complex payoffs and models with structuring tools, and model and products catalogue extensors.
Key features include:
We analyze the statistical correlation between the EURO STOXX 50 stock index and the VSTOXX volatility index.
First the EURO STOXX 50 data.
import pandas as pd
cols = ['Date', 'SX5P', 'SX5E', 'SXXP', 'SXXE',
'SXXF', 'SXXA', 'DK5F', 'DKXF', 'DEL']
es_url = 'http://www.stoxx.com/download/historical_values/hbrbcpe.txt'
try:
es = pd.read_csv(es_url, # filename
header=None, # ignore column names
index_col=0, # index column (dates)
parse_dates=True, # parse these dates
dayfirst=True, # format of dates
skiprows=4, # ignore these rows
sep=';', # data separator
names=cols) # use these column names
# deleting the helper column
del es['DEL']
except:
# read stored data if there is no Internet connection
es = pd.HDFStore('data/SX5E.h5', 'r')['SX5E']
Second, the VSTOXX data.
vs_url = 'http://www.stoxx.com/download/historical_values/h_vstoxx.txt'
try:
vs = pd.read_csv(vs_url, # filename
index_col=0, # index column (dates)
parse_dates=True, # parse date information
dayfirst=True, # day before month
header=2) # header/column names
except:
# read stored data if there is no Internet connection
vs = pd.HDFStore('data/V2TX.h5', 'r')['V2TX']
Generating log returns with Python and pandas.
import numpy as np
# log returns for the major indices' time series data
datv = pd.DataFrame({'SX5E' : es['SX5E'], 'V2TX': vs['V2TX']}).dropna()
rets = np.log(datv / datv.shift(1)).dropna()
ES = rets['SX5E'].values
VS = rets['V2TX'].values
Bridging to R from within IPython Notebook and pushing Python data to the R run-time.
%load_ext rpy2.ipython
%Rpush ES VS
Plotting with R in IPython Notebook.
%R plot(ES, VS, pch=19, col='blue'); grid(); title("Log returns ES50 & VSTOXX")
Linear regression with R.
%R c = coef(lm(VS~ES))
array([ 9.15896671e-06, -2.83354384e+00])
%R print(summary(lm(VS~ES)))
Call: lm(formula = VS ~ ES) Residuals: Min 1Q Median 3Q Max -0.32413 -0.02188 -0.00207 0.02042 0.53806 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 9.159e-06 6.038e-04 0.015 0.988 ES -2.834e+00 3.996e-02 -70.910 <2e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 0.03951 on 4281 degrees of freedom Multiple R-squared: 0.5401, Adjusted R-squared: 0.54 F-statistic: 5028 on 1 and 4281 DF, p-value: < 2.2e-16
Regression line visualized.
%R plot(ES, VS, pch=19, col='blue'); grid(); abline(c, col='red', lwd=5)
Pulling data from R to Python and using it.
%Rpull c
plt.figure(figsize=(10, 6))
plt.plot(ES, VS, 'b.')
plt.plot(ES, c[0] + c[1] * ES, 'r', lw=3)
plt.xlabel('ES'); plt.ylabel('VS')
<matplotlib.text.Text at 0x10b7e1410>
If you want to have it nicer, interactive and embeddable anywhere – use plot.ly
import plotly.plotly as py
py.sign_in('Python-Demo-Account', 'gwt101uhh0')
Let us generate a plot with a bit fewer data points.
pyfig = plt.figure(figsize=(9, 6)); n = 100
plt.plot(ES[:n], VS[:n], 'b.')
plt.plot(ES[:n], c[0] + c[1] * ES[:n], 'r', lw=3)
plt.xlabel('ES'); plt.ylabel('VS')
<matplotlib.text.Text at 0x110259390>
Only single line of code needed to convert matplotlib plot into interactive D3 plot.
py.iplot_mpl(pyfig) # convert mpl plot into interactive D3
Finance algorithms are loop-heavy; Python loops are slow; Python is too slow for finance.
def counting_py(N):
s = 0
for i in xrange(N):
for j in xrange(N):
s += int(cos(log(1)))
return s
N = 2000
%time counting_py(N)
# memory efficient but slow
CPU times: user 8.19 s, sys: 75.3 ms, total: 8.27 s Wall time: 8.66 s
4000000
First approach: vectorization with NumPy.
%%time
from pylab import *
arr = ones((N, N))
print int(sum(cos(log(arr))))
4000000 CPU times: user 84.4 ms, sys: 45 ms, total: 129 ms Wall time: 130 ms
arr.nbytes # much faster but NOT memory efficient
32000000
Second approach: dynamic compiling with Numba.
import numba
counting_nb = numba.jit(counting_py)
%time counting_nb(N)
# some overhead the first time
CPU times: user 141 ms, sys: 16.8 ms, total: 158 ms Wall time: 151 ms
4000000
%timeit counting_nb(N)
# even faster AND memory efficient
10 loops, best of 3: 52.5 ms per loop
Hardware-bound IO operations are standard for Python.
%time one_gb = standard_normal((12500, 10000))
one_gb.nbytes
# a giga byte worth of data
CPU times: user 6.3 s, sys: 486 ms, total: 6.79 s Wall time: 7.04 s
1000000000
%time save('one_gb', one_gb)
CPU times: user 59.6 ms, sys: 2.73 s, total: 2.79 s Wall time: 3.94 s
!ls -n one_gb*
-rw-r--r-- 1 501 20 1000000080 Oct 30 09:30 one_gb.npy
!rm one_gb*
Integrating it all and adding collaboration and scalability (http://quant-platform.com).
At the moment, the Python Quant Platform comprises the following components and features:
rpy2
and IPython NotebookQuant Platform/datapark.io are fully integrated with Dropbox. Use the platform as a cloud-based execution environment for code and data stored on Dropbox.
from IPython.display import HTML
HTML('<iframe src=http://web.quant-platform.com/trial/yves/ \
width=100% height=550></iframe>')
490 Python Jobs in Greenwich, CT – obviously a famous hedge fund place.
Automated Trading powerd by Python.
Trading and Risk Management powered by Python.
Python-based tutorials by Eurex (http://www.eurexchange.com/vstoxx/).
By others:
By myself:
Published in December 2014.
Published in July 2015.
Forthcoming in 2016.
"The appendices present an implementation in Python of our experiments." (p. 3)
"Knowledge and Skills: Our graduates have working experience with C++, VBA, Python, R, and Matlab for financial applications. They share an exceptionally strong work ethic and possess excellent interpersonal, teamwork, and communication skills."
By others:
By myself:
HTML('<iframe src=http://quantshub.com/content/python-finance-yves-j-hilpisch \
width=100% height=550></iframe>')
HTML('<iframe src="http://fpq.io" \
width=100% height=650></iframe>')
My wish for Python in the future: to become THE glue language and platform in Quant Finance for
Python has the potential to accomplish what MMA has done for the Martial Arts.
Please contact us if you have any questions or want to get involved in our Python community events.
Python Quant Platform | http://quant-platform.com
Derivatives Analytics with Python | Derivatives Analytics @ Wiley Finance
Python for Finance | Python for Finance @ O'Reilly