{ "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", "