The Python Quants

DX Analytics Library

Portfolio Risk Statistics

In [1]:
import dx
import datetime as dt
import time
import numpy as np

Assets

In [2]:
# constant short rate
r = dx.constant_short_rate('r', 0.01)
In [3]:
# market environment
me_gbm_1 = dx.market_environment('gbm_1', dt.datetime(2015, 1, 1))
In [4]:
# geometric Brownian motion
me_gbm_1.add_constant('initial_value', 40.)
me_gbm_1.add_constant('volatility', 0.2) 
me_gbm_1.add_constant('currency', 'EUR')
me_gbm_1.add_constant('model', 'gbm')
In [5]:
me_gbm_2 = dx.market_environment('gbm_2', me_gbm_1.pricing_date)
In [6]:
# valuation environment
val_env = dx.market_environment('val_env', dt.datetime(2015, 1, 1))
val_env.add_constant('paths', 25000)
    # 100,000 paths
val_env.add_constant('frequency', 'W')
    # weekly frequency
val_env.add_curve('discount_curve', r)
val_env.add_constant('starting_date', dt.datetime(2015, 1, 1))
val_env.add_constant('final_date', dt.datetime(2015, 12, 31))
In [7]:
# add valuation environment to market environments
me_gbm_1.add_environment(val_env)
me_gbm_2.add_environment(me_gbm_1)
me_gbm_2.add_constant('initial_value', 40.)
me_gbm_2.add_constant('volatility', 0.3)
In [8]:
underlyings = {'gbm_1' : me_gbm_1, 'gbm_2' : me_gbm_2}
  # market with two underlyings

Options Positions

Modelling

In [9]:
# market environment for the options
me_option = dx.market_environment('put', dt.datetime(2015, 1, 1))
me_option.add_constant('maturity', dt.datetime(2015, 12, 31))
me_option.add_constant('currency', 'EUR')
me_option.add_environment(val_env)

Portfolio Composition

In [10]:
positions = {}
half = 3  # 2 times that many options
for i in range(half):
    positions[i] = dx.derivatives_position('am_put_pos_%s' %i, 1, ['gbm_1'], me_option,
                'American single', 'np.maximum(instrument_values - 40., 0)')

multi_payoff = "np.maximum(np.maximum(maturity_value['gbm_1'], maturity_value['gbm_2']) - 40., 0)"
for i in range(half, 2 * half):
    positions[i] = dx.derivatives_position('multi_pos_%s' %i, 1, ['gbm_1', 'gbm_2'],
                                           me_option, 'European multi', multi_payoff)

Portfolio Valuation

In [11]:
portfolio = dx.derivatives_portfolio('portfolio', positions, val_env,
                         underlyings, correlations=None, parallel=False)
In [12]:
%time res = portfolio.get_values(fixed_seed=True)
CPU times: user 1.24 s, sys: 12 ms, total: 1.25 s
Wall time: 1.25 s

In [13]:
res
Out[13]:
position name quantity value currency pos_value
0 0 am_put_pos_0 1 3.268370 EUR 3.268370
1 1 am_put_pos_1 1 3.268370 EUR 3.268370
2 2 am_put_pos_2 1 3.268370 EUR 3.268370
3 3 multi_pos_3 1 7.359084 EUR 7.359084
4 4 multi_pos_4 1 7.359084 EUR 7.359084
5 5 multi_pos_5 1 7.359084 EUR 7.359084
In [14]:
portfolio.val_env.get_list('cholesky_matrix')
Out[14]:
array([[ 1.,  0.],
       [ 0.,  1.]])

Portfolio Risk

No Correlation

In [15]:
%time vegas = portfolio.get_port_risk(Greek='Vega', fixed_seed=True)
CPU times: user 10.8 s, sys: 4 ms, total: 10.8 s
Wall time: 10.9 s

In [16]:
dx.risk_report(vegas)

gbm_1_Vega
           0.8    0.9    1.0    1.1    1.2
initial   0.16   0.18   0.20   0.22   0.24
value    28.46  30.16  31.88  33.64  35.40

gbm_2_Vega
           0.8    0.9    1.0    1.1    1.2
initial   0.24   0.27   0.30   0.33   0.36
value    29.19  30.53  31.88  33.25  34.64

In [17]:
%time deltas = portfolio.get_port_risk(Greek='Delta', fixed_seed=True)
CPU times: user 11.1 s, sys: 4 ms, total: 11.1 s
Wall time: 11.1 s

In [18]:
dx.risk_report(deltas)

gbm_1_Delta
           0.8    0.9    1.0    1.1    1.2
initial  32.00  36.00  40.00  44.00  48.00
value    17.41  22.44  31.88  45.51  62.61

gbm_2_Delta
           0.8    0.9    1.0    1.1    1.2
initial  32.00  36.00  40.00  44.00  48.00
value    23.38  26.86  31.88  38.37  46.15

In [19]:
portfolio.val_env.get_list('cholesky_matrix')
Out[19]:
array([[ 1.,  0.],
       [ 0.,  1.]])

With Correlation

In [20]:
correlations = [['gbm_1', 'gbm_2', -0.9]]
In [21]:
portfolio = dx.derivatives_portfolio('portfolio', positions, val_env,
                            underlyings, correlations, parallel=False)
In [22]:
portfolio.val_env.get_list('cholesky_matrix')
Out[22]:
array([[ 1.        ,  0.        ],
       [-0.9       ,  0.43588989]])
In [23]:
%time portfolio.get_values(fixed_seed=True)
CPU times: user 1.25 s, sys: 0 ns, total: 1.25 s
Wall time: 1.26 s

Out[23]:
position name quantity value currency pos_value
0 0 am_put_pos_0 1 3.225585 EUR 3.225585
1 1 am_put_pos_1 1 3.225585 EUR 3.225585
2 2 am_put_pos_2 1 3.225585 EUR 3.225585
3 3 multi_pos_3 1 8.153263 EUR 8.153263
4 4 multi_pos_4 1 8.153263 EUR 8.153263
5 5 multi_pos_5 1 8.153263 EUR 8.153263
In [24]:
%%time
deltas = portfolio.get_port_risk(Greek='Delta', fixed_seed=True,
                                       step=0.05)
CPU times: user 18.8 s, sys: 32 ms, total: 18.9 s
Wall time: 18.9 s

In [25]:
dx.risk_report(deltas)

gbm_1_Delta
          0.80   0.85   0.90  0.95   1.00   1.05   1.10   1.15   1.20
initial  32.00  34.00  36.00  38.0  40.00  42.00  44.00  46.00  48.00
value    17.54  19.87  23.37  28.1  34.14  41.16  49.16  57.76  67.17

gbm_2_Delta
          0.80   0.85   0.90  0.95   1.00   1.05   1.10   1.15   1.20
initial  32.00  34.00  36.00    38  40.00  42.00  44.00  46.00  48.00
value    24.01  25.91  28.24    31  34.14  37.62  41.39  45.42  49.66