{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Multi-Risk Derivatives Portfolios"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The step from multi-risk derivatives instruments to multi-risk derivatives instrument portfolios is not a too large one. This part of the tutorial shows how to model an economy with three risk factors"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from dx import *\n",
"from pylab import plt\n",
"plt.style.use('seaborn')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Risk Factors"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This sub-section models the single risk factors. We start with definition of the risk-neutral discounting object."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# constant short rate\n",
"r = constant_short_rate('r', 0.02)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Three risk factors** ares modeled:\n",
"\n",
"* geometric Brownian motion\n",
"* jump diffusion\n",
"* stochastic volatility process"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# market environments\n",
"me_gbm = market_environment('gbm', dt.datetime(2015, 1, 1))\n",
"me_jd = market_environment('jd', dt.datetime(2015, 1, 1))\n",
"me_sv = market_environment('sv', dt.datetime(2015, 1, 1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Assumptions for the `geometric_brownian_motion` object."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# geometric Brownian motion\n",
"me_gbm.add_constant('initial_value', 36.)\n",
"me_gbm.add_constant('volatility', 0.2) \n",
"me_gbm.add_constant('currency', 'EUR')\n",
"me_gbm.add_constant('model', 'gbm')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Assumptions for the `jump_diffusion` object."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# jump diffusion\n",
"me_jd.add_constant('initial_value', 36.)\n",
"me_jd.add_constant('volatility', 0.2)\n",
"me_jd.add_constant('lambda', 0.5)\n",
" # probability for jump p.a.\n",
"me_jd.add_constant('mu', -0.75)\n",
" # expected jump size [%]\n",
"me_jd.add_constant('delta', 0.1)\n",
" # volatility of jump\n",
"me_jd.add_constant('currency', 'EUR')\n",
"me_jd.add_constant('model', 'jd')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Assumptions for the `stochastic_volatility` object."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# stochastic volatility model\n",
"me_sv.add_constant('initial_value', 36.)\n",
"me_sv.add_constant('volatility', 0.2)\n",
"me_sv.add_constant('vol_vol', 0.1)\n",
"me_sv.add_constant('kappa', 2.5)\n",
"me_sv.add_constant('theta', 0.4)\n",
"me_sv.add_constant('rho', -0.5)\n",
"me_sv.add_constant('currency', 'EUR')\n",
"me_sv.add_constant('model', 'sv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, the unifying valuation assumption for the **valuation environment**."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# valuation environment\n",
"val_env = market_environment('val_env', dt.datetime(2015, 1, 1))\n",
"val_env.add_constant('paths', 10000)\n",
"val_env.add_constant('frequency', 'W')\n",
"val_env.add_curve('discount_curve', r)\n",
"val_env.add_constant('starting_date', dt.datetime(2015, 1, 1))\n",
"val_env.add_constant('final_date', dt.datetime(2015, 12, 31))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These are added to the single `market_environment` objects of the risk factors."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# add valuation environment to market environments\n",
"me_gbm.add_environment(val_env)\n",
"me_jd.add_environment(val_env)\n",
"me_sv.add_environment(val_env)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, the **market model** with the risk factors and the correlations between them."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"risk_factors = {'gbm' : me_gbm, 'jd' : me_jd, 'sv' : me_sv}\n",
"correlations = [['gbm', 'jd', 0.66], ['jd', 'sv', -0.75]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Derivatives"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this sub-section, we model the single derivatives instruments."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### American Put Option"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The first derivative instrument is an **American put option**."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"gbm = geometric_brownian_motion('gbm_obj', me_gbm)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"me_put = market_environment('put', dt.datetime(2015, 1, 1))\n",
"me_put.add_constant('maturity', dt.datetime(2015, 12, 31))\n",
"me_put.add_constant('strike', 40.)\n",
"me_put.add_constant('currency', 'EUR')\n",
"me_put.add_environment(val_env)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"am_put = valuation_mcs_american_single('am_put', mar_env=me_put, underlying=gbm,\n",
" payoff_func='np.maximum(strike - instrument_values, 0)')"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5.012"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"am_put.present_value(fixed_seed=True, bf=5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### European Maximum Call on 2 Assets"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The second derivative instrument is a **European maximum call option on two risk factors**."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"jd = jump_diffusion('jd_obj', me_jd)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"me_max_call = market_environment('put', dt.datetime(2015, 1, 1))\n",
"me_max_call.add_constant('maturity', dt.datetime(2015, 9, 15))\n",
"me_max_call.add_constant('currency', 'EUR')\n",
"me_max_call.add_environment(val_env)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"payoff_call = \"np.maximum(np.maximum(maturity_value['gbm'], maturity_value['jd']) - 34., 0)\""
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"assets = {'gbm' : me_gbm, 'jd' : me_jd}\n",
"asset_corr = [correlations[0]]"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[['gbm', 'jd', 0.66]]"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"asset_corr"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"max_call = valuation_mcs_european_multi('max_call', me_max_call, assets, asset_corr,\n",
" payoff_func=payoff_call)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"8.334"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"max_call.present_value(fixed_seed=False)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.7596"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"max_call.delta('jd')"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.2824"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"max_call.delta('gbm')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### American Minimum Put on 2 Assets"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The third derivative instrument is an **American minimum put on two risk factors**."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"sv = stochastic_volatility('sv_obj', me_sv)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"me_min_put = market_environment('min_put', dt.datetime(2015, 1, 1))\n",
"me_min_put.add_constant('maturity', dt.datetime(2015, 6, 17))\n",
"me_min_put.add_constant('currency', 'EUR')\n",
"me_min_put.add_environment(val_env)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"payoff_put = \"np.maximum(32. - np.minimum(instrument_values['jd'], instrument_values['sv']), 0)\""
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[['jd', 'sv', -0.75]]"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"assets = {'jd' : me_jd, 'sv' : me_sv}\n",
"asset_corr = [correlations[1]]\n",
"asset_corr"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"min_put = valuation_mcs_american_multi(\n",
" 'min_put', val_env=me_min_put, risk_factors=assets,\n",
" correlations=asset_corr, payoff_func=payoff_put)"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4.296"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"min_put.present_value(fixed_seed=True)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"-0.0981"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"min_put.delta('jd')"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"-0.2102"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"min_put.delta('sv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Portfolio"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To compose a derivatives portfolio, `derivatives_position` objects are needed."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [],
"source": [
"am_put_pos = derivatives_position(\n",
" name='am_put_pos',\n",
" quantity=2,\n",
" underlyings=['gbm'],\n",
" mar_env=me_put,\n",
" otype='American single',\n",
" payoff_func='np.maximum(instrument_values - 36., 0)')"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"max_call_pos = derivatives_position(\n",
" 'max_call_pos', 3, ['gbm', 'jd'],\n",
" me_max_call, 'European multi',\n",
" payoff_call)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"min_put_pos = derivatives_position(\n",
" 'min_put_pos', 5, ['sv', 'jd'],\n",
" me_min_put, 'American multi',\n",
" payoff_put)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These objects are to be collected in `dictionary` objects."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [],
"source": [
"positions = {'am_put_pos' : am_put_pos, 'max_call_pos' : max_call_pos,\n",
" 'min_put_pos' : min_put_pos}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All is together to instantiate the `derivatives_portfolio` class."
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [],
"source": [
"port = derivatives_portfolio(name='portfolio',\n",
" positions=positions,\n",
" val_env=val_env,\n",
" risk_factors=risk_factors,\n",
" correlations=correlations)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us have a look at the major **portfolio statistics**."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Totals\n",
" pos_value 51.769\n",
"dtype: float64\n",
"CPU times: user 1.42 s, sys: 124 ms, total: 1.55 s\n",
"Wall time: 1.48 s\n"
]
},
{
"data": {
"text/html": [
"
\n", " | position | \n", "name | \n", "quantity | \n", "otype | \n", "risk_facts | \n", "value | \n", "currency | \n", "pos_value | \n", "pos_delta | \n", "pos_vega | \n", "
---|---|---|---|---|---|---|---|---|---|---|
0 | \n", "am_put_pos | \n", "am_put_pos | \n", "2 | \n", "American single | \n", "[gbm] | \n", "3.182 | \n", "EUR | \n", "6.364 | \n", "1.2184 | \n", "30.5422 | \n", "
1 | \n", "max_call_pos | \n", "max_call_pos | \n", "3 | \n", "European multi | \n", "[gbm, jd] | \n", "8.165 | \n", "EUR | \n", "24.495 | \n", "{'gbm': 0.8646, 'jd': 2.2662} | \n", "{'gbm': 14.9805, 'jd': 10.35} | \n", "
2 | \n", "min_put_pos | \n", "min_put_pos | \n", "5 | \n", "American multi | \n", "[sv, jd] | \n", "4.182 | \n", "EUR | \n", "20.910 | \n", "{'sv': -1.1675, 'jd': -0.6225} | \n", "{'sv': 8.322, 'jd': 11.352} | \n", "