The Python Quants

DX Analytics Library

Model Classes

The following models are available:

  • geometric_brownian_motion: Black-Scholes-Merton (1973) geometric Brownian motion
  • jump_diffusion: Merton (1976) jump diffusion
  • stoch_vol_jump_diffusion: Bates (1996) stochastic volatility jump diffusion
  • square_root_diffusion: Cox-Ingersoll-Ross (1985) square-root diffusion
  • square_root_jump_diffusion: square-root jump diffusion
  • square_root_jump_diffusion_plus: square-root jump diffusion plus term structure
In [1]:
from dx import *
In [2]:
np.set_printoptions(precision=3)
In [3]:
r = constant_short_rate('r', 0.06)

geometric_brownian_motion

In [4]:
me = market_environment('me', dt.datetime(2015, 1, 1))
In [5]:
me.add_constant('initial_value', 36.)
me.add_constant('volatility', 0.2)
me.add_constant('final_date', dt.datetime(2015, 12, 31))
me.add_constant('currency', 'EUR')
me.add_constant('frequency', 'M')
  # monthly frequency
me.add_constant('paths', 10000)
In [6]:
me.add_curve('discount_curve', r)
In [7]:
gbm = geometric_brownian_motion('gbm', me)
In [8]:
gbm.generate_time_grid()
In [9]:
gbm.time_grid
Out[9]:
array([datetime.datetime(2015, 1, 1, 0, 0),
       datetime.datetime(2015, 1, 31, 0, 0),
       datetime.datetime(2015, 2, 28, 0, 0),
       datetime.datetime(2015, 3, 31, 0, 0),
       datetime.datetime(2015, 4, 30, 0, 0),
       datetime.datetime(2015, 5, 31, 0, 0),
       datetime.datetime(2015, 6, 30, 0, 0),
       datetime.datetime(2015, 7, 31, 0, 0),
       datetime.datetime(2015, 8, 31, 0, 0),
       datetime.datetime(2015, 9, 30, 0, 0),
       datetime.datetime(2015, 10, 31, 0, 0),
       datetime.datetime(2015, 11, 30, 0, 0),
       datetime.datetime(2015, 12, 31, 0, 0)], dtype=object)
In [10]:
paths = gbm.get_instrument_values()
In [11]:
paths[:, :2]
Out[11]:
array([[ 36.   ,  36.   ],
       [ 37.403,  38.12 ],
       [ 39.521,  42.255],
       [ 42.618,  35.909],
       [ 41.901,  35.88 ],
       [ 40.316,  31.446],
       [ 41.314,  31.707],
       [ 39.202,  31.282],
       [ 40.99 ,  30.124],
       [ 40.868,  31.473],
       [ 40.492,  33.443],
       [ 42.483,  36.925],
       [ 43.766,  37.805]])
In [12]:
%matplotlib inline
colormap='coolwarm'
lw=1.25
figsize=(8, 4)
legend=False
no_paths=10
In [13]:
pdf = pd.DataFrame(paths, index=gbm.time_grid)
In [14]:
pdf[pdf.columns[:no_paths]].plot(colormap=colormap, lw=lw,
                           figsize=figsize, legend=legend)
Out[14]:
<matplotlib.axes.AxesSubplot at 0x109217d90>

jump_diffusion

In [15]:
me.add_constant('lambda', 0.7)
me.add_constant('mu', -0.8)
me.add_constant('delta', 0.1)
In [16]:
jd = jump_diffusion('jd', me)
In [17]:
paths = jd.get_instrument_values()
In [18]:
pdf = pd.DataFrame(paths, index=jd.time_grid)
In [19]:
pdf[pdf.columns[:no_paths]].plot(colormap=colormap, lw=lw,
                           figsize=figsize, legend=legend)
Out[19]:
<matplotlib.axes.AxesSubplot at 0x109252790>

stoch_vol_jump_diffusion

In [20]:
me.add_constant('rho', -.5)
me.add_constant('kappa', 2.5)
me.add_constant('theta', 0.1)
me.add_constant('vol_vol', 0.1)
In [21]:
svjd = stoch_vol_jump_diffusion('svjd', me)
In [22]:
paths = svjd.get_instrument_values()
In [23]:
pdf = pd.DataFrame(paths, index=svjd.time_grid)
In [24]:
# index level paths
pdf[pdf.columns[:no_paths]].plot(colormap=colormap, lw=lw,
                           figsize=figsize, legend=legend)
Out[24]:
<matplotlib.axes.AxesSubplot at 0x1096dcf50>
In [25]:
vols = svjd.get_volatility_values()
In [26]:
pdf = pd.DataFrame(vols, index=svjd.time_grid)
In [27]:
# volatility paths
pdf[pdf.columns[:no_paths]].plot(colormap=colormap, lw=lw,
                           figsize=figsize, legend=legend)
Out[27]:
<matplotlib.axes.AxesSubplot at 0x10a0ba490>

square_root_diffusion

In [28]:
# short rate like parameters
me.add_constant('initial_value', 0.05)
me.add_constant('volatility', 0.1)
me.add_constant('kappa', 2.5)
me.add_constant('theta', 0.01)
In [29]:
srd = square_root_diffusion('srd', me)
In [30]:
paths = srd.get_instrument_values()
In [31]:
pdf = pd.DataFrame(paths, index=srd.time_grid)
In [32]:
pdf[pdf.columns[:no_paths]].plot(colormap=colormap, lw=lw,
                           figsize=figsize, legend=legend)
Out[32]:
<matplotlib.axes.AxesSubplot at 0x10ab8ff10>

square_root_jump_diffusion

Experimental Status

In [33]:
# volatility index like parameters
me.add_constant('initial_value', 25.) 
me.add_constant('theta', 20.)
me.add_constant('volatility', 1.)
me.add_constant('mu', 0.4)
In [34]:
srjd = square_root_jump_diffusion('srjd', me)
In [35]:
paths = srjd.get_instrument_values()
In [36]:
pdf = pd.DataFrame(paths, index=srjd.time_grid)
In [37]:
pdf[pdf.columns[:no_paths]].plot(colormap=colormap, lw=lw,
                           figsize=figsize, legend=legend)
Out[37]:
<matplotlib.axes.AxesSubplot at 0x10ae8bb90>

square_root_jump_diffusion_plus

Experimental Status

In [38]:
srjd = square_root_jump_diffusion_plus('srjd', me)
  # no particular term structure provided
Missing Term Structure.

In [39]:
srjd.update_forward_rates()
In [40]:
srjd.forward_rates
  # term structure resulting from parameters
Out[40]:
array([[datetime.datetime(2015, 1, 1, 0, 0), 25.0],
       [datetime.datetime(2015, 1, 31, 0, 0), 22.147819508788491],
       [datetime.datetime(2015, 2, 28, 0, 0), 19.885819936252695],
       [datetime.datetime(2015, 3, 31, 0, 0), 17.792707674476073],
       [datetime.datetime(2015, 4, 30, 0, 0), 16.12979618769257],
       [datetime.datetime(2015, 5, 31, 0, 0), 14.731840583856311],
       [datetime.datetime(2015, 6, 30, 0, 0), 13.639356798619165],
       [datetime.datetime(2015, 7, 31, 0, 0), 12.732665107729368],
       [datetime.datetime(2015, 8, 31, 0, 0), 12.010424516692789],
       [datetime.datetime(2015, 9, 30, 0, 0), 11.453652384994699],
       [datetime.datetime(2015, 10, 31, 0, 0), 10.996470732640216],
       [datetime.datetime(2015, 11, 30, 0, 0), 10.645744263620665],
       [datetime.datetime(2015, 12, 31, 0, 0), 10.358848875231516]], dtype=object)