aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/notebooks/Reto Report.ipynb210
1 files changed, 91 insertions, 119 deletions
diff --git a/python/notebooks/Reto Report.ipynb b/python/notebooks/Reto Report.ipynb
index 03e5c06f..f05d63b2 100644
--- a/python/notebooks/Reto Report.ipynb
+++ b/python/notebooks/Reto Report.ipynb
@@ -7,21 +7,21 @@
"outputs": [],
"source": [
"import datetime\n",
- "from pandas.tseries.offsets import BDay, MonthEnd\n",
"import globeop_reports as go\n",
"import pandas as pd\n",
"import analytics\n",
"import numpy as np\n",
"\n",
+ "from pandas.tseries.offsets import BDay, MonthEnd\n",
"from analytics.index_data import get_index_quotes\n",
"from analytics.scenarios import run_portfolio_scenarios\n",
+ "from analytics.utils import run_local\n",
"from analytics import BlackSwaption, CreditIndex, BlackSwaptionVolSurface, Portfolio,DualCorrTranche\n",
"from copy import deepcopy\n",
- "\n",
+ "from analytics.curve_trades import on_the_run\n",
"from risk.tranches import get_tranche_portfolio\n",
"from risk.swaptions import get_swaption_portfolio\n",
"from risk.bonds import subprime_risk, clo_risk, crt_risk\n",
- "\n",
"from utils.db import dbconn, dbengine, serenitas_engine, dawn_engine"
]
},
@@ -31,7 +31,11 @@
"metadata": {},
"outputs": [],
"source": [
- "#PNL Allocation\n",
+ "#Set dates\n",
+ "analytics._local = False\n",
+ "position_date = (datetime.date.today() - BDay(1)).date()\n",
+ "spread_date = position_date\n",
+ "analytics.init_ontr(spread_date)\n",
"date = datetime.date.today() - BDay(1)\n",
"report_date = date - MonthEnd(1)\n",
"report_date"
@@ -66,15 +70,6 @@
"metadata": {},
"outputs": [],
"source": [
- "rolling_return"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
"################################### Average Portfolio Sales Turnover - as of last monthend from today\n",
"#(total Bond Sales Proceeds + paydown)/average starting 12 months NAV\n",
"#Actually: Rolling 12 months sum of (total bond sales proceeds + paydown)/monthly NAV\n",
@@ -105,40 +100,7 @@
"df_1['paydown'] = df_1.apply(lambda df: df.endqty/df.principal_bal * df.principal, axis=1)\n",
"paydowns = df_1.paydown.groupby(pd.Grouper(freq='M')).sum()\n",
"temp = pd.concat([paydowns, df.principal_payment, df.accrued_payment], axis=1).fillna(0)\n",
- "turnover = (temp.sum(axis=1)/nav.begbooknav).rolling(12).sum()\n",
- "turnover[12:].plot()\n",
- "turnover.min(), turnover.max(), turnover.mean()\n",
- "turnover[-1]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "################################### BRINKER: Average Portfolio Sales Turnover - as of last monthend from today\n",
- "#(total Bond Sales Proceeds + paydown)/average starting 12 months NAV\n",
- "#Actually: Rolling 12 months sum of (total bond sales proceeds + paydown)/monthly NAV\n",
- "nav = go.get_net_navs()\n",
- "fund='BRINKER'\n",
- "sql_string = \"SELECT * FROM bonds WHERE buysell IS False and fund = %s\"\n",
- "df = pd.read_sql_query(sql_string, dawn_engine,\n",
- " parse_dates={'lastupdate':{'utc':True}, 'trade_date': {}, 'settle_date':{}},\n",
- " params=[fund,],\n",
- " index_col = 'trade_date')\n",
- "df = df.groupby(pd.Grouper(freq='M')).sum()\n",
- "\n",
- "cf = pd.read_sql_query(\"SELECT * FROM cashflow_history\", dawn_engine,\n",
- " parse_dates=['date'],\n",
- " index_col=['date']).sort_index()\n",
- "sql_string = \"SELECT description, identifier, notional, price, factor FROM risk_positions(%s, %s, 'BRINKER')\"\n",
- "pos = {}\n",
- "for d in cf.index.unique():\n",
- " for ac in ['Subprime', 'CRT']:\n",
- " pos[d, ac] = pd.read_sql_query(sql_string, dawn_engine, params=[d.date(), ac])\n",
- "pos = pd.concat(pos, names=['date', 'asset_class'])\n",
- "pos = pos.reset_index(level=[1,2])"
+ "turnover = (temp.sum(axis=1)/nav.begbooknav).rolling(12).sum()"
]
},
{
@@ -289,8 +251,21 @@
"monthend_portfolio = portfolio.groupby(pd.Grouper(freq=\"M\"), group_keys=False).apply(\n",
" lambda df: df.loc[df.index[-1]]\n",
" )\n",
- "monthend_byinvid = monthend_portfolio.groupby(['periodenddate','invid']).sum()\n",
- "positive = monthend_byinvid['endbooknav'].groupby(['periodenddate']).agg(lambda x: x[x>0].sum())\n",
+ "options_list = ['IGPAYER', 'HYPAYER', 'IGREC', 'HYREC']\n",
+ "syn_list = ['CSO_TRANCH', 'LQD_TRANCH', 'HEDGE_CLO', 'HEDGE_CSO', 'HEDGE_MAC', 'HEDGE_MBS',\n",
+ " 'IGMEZ','HYMEZ', 'IGINX', 'MBSCDS', 'IGCURVE', 'IGOPTDEL', 'HYOPTDEL',\n",
+ " 'ITRXCURVE', 'IGEQY', 'IGSNR', 'BSPK', 'HYINX', 'HYEQY', 'XCURVE', 'XOMEZ', 'XOINX', 'EUMEZ']\n",
+ "\n",
+ "monthend_syn = monthend_portfolio[monthend_portfolio.strat.isin(syn_list)]\n",
+ "monthend_syn = monthend_syn[monthend_syn['endqty'] < 0]\n",
+ "monthend_syn = monthend_syn.groupby(['periodenddate','invid']).sum()\n",
+ "\n",
+ "monthend_cash = monthend_portfolio[~monthend_portfolio.strat.isin(syn_list)]\n",
+ "monthend_cash = monthend_cash.groupby(['periodenddate','invid']).sum()\n",
+ "\n",
+ "positive = pd.concat([monthend_syn, monthend_cash])\n",
+ "positive = positive['endbooknav'].groupby(['periodenddate']).agg(lambda x: x[x>0].sum())\n",
+ "\n",
"nav = nav.merge(positive, left_index=True, right_index=True)\n",
"nav['leverage'] = nav.endbooknav_y/nav.endbooknav_x\n",
"nav['leverage'].plot()"
@@ -344,6 +319,28 @@
"metadata": {},
"outputs": [],
"source": [
+ "#Historical max widening\n",
+ "analytics.init_ontr()\n",
+ "df = get_index_quotes('HY', list(range(on_the_run('HY', spread_date) - 10, on_the_run('HY', spread_date) + 1)),\n",
+ " tenor=['5yr'], years=5)\n",
+ "df = df.xs('5yr', level='tenor')['close_spread'].groupby(['date', 'series']).last()\n",
+ "df=df.loc[:'2020-2-28']\n",
+ "\n",
+ "widen, tighten = [], []\n",
+ "#approximately 1,3,6 months move (22 each months)\n",
+ "for days in [22, 66, 132]: \n",
+ " calc = df.unstack().pct_change(freq= str(days)+'B').stack().groupby('date').last()\n",
+ " widen.append(calc.max())\n",
+ " tighten.append(calc.min())\n",
+ "pd.DataFrame([widen, tighten], columns=['1M', '3M', '6M'], index=['widen', 'tighten'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
"################################## Historical Notioinals and HY Equiv\n",
"dates = pd.date_range(datetime.date(2013, 1, 30), pd.datetime.today() - MonthEnd(1), freq=\"BM\")\n",
"#look for a day with HY quotes... we need that to construct HY Equiv\n",
@@ -371,10 +368,13 @@
" if spread_date is None:\n",
" spread_date=position_date\n",
" conn = dawn_engine.raw_connection()\n",
+ " conn.autocommit = True\n",
+ " \n",
" mysql_engine = dbengine('rmbs_model')\n",
" mysqlcrt_engine = dbengine('crt')\n",
" \n",
- " on_the_run_index = CreditIndex('HY', on_the_run('HY', position_date), '5yr', value_date=position_date)\n",
+ " on_the_run_index = analytics._ontr['HY']\n",
+ " on_the_run_index.value_date = position_date\n",
"\n",
" #tranche positions\n",
" portf = get_tranche_portfolio(position_date, conn, False, 'SERCGMAST')\n",
@@ -437,41 +437,10 @@
"metadata": {},
"outputs": [],
"source": [
- "################################### Calculate stress scenario \n",
- "position_date = (datetime.date.today() - BDay(1)).date()\n",
- "spread_date = position_date\n",
- "analytics.init_ontr(spread_date)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "#Calculate amount of stress for reports\n",
- "from analytics.curve_trades import on_the_run\n",
- "df = get_index_quotes('HY', list(range(on_the_run('HY', spread_date) - 10, on_the_run('HY', spread_date) + 1)),\n",
- " tenor=['5yr'], years=5)\n",
- "df = df.xs('5yr', level='tenor')['close_spread'].groupby(['date', 'series']).last()\n",
- "df=df.loc[:'2020-2-28']\n",
- "\n",
- "widen, tighten = [], []\n",
- "#approximately 1,3,6 months move (22 each months)\n",
- "for days in [22, 66, 132]: \n",
- " calc = df.unstack().pct_change(freq= str(days)+'B').stack().groupby('date').last()\n",
- " widen.append(calc.max())\n",
- " tighten.append(calc.min())\n",
- "pd.DataFrame([widen, tighten], columns=['1M', '3M', '6M'], index=['widen', 'tighten'])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
"#tranche/swaption positions\n",
+ "curr_spread = analytics._ontr['HY'].spread\n",
+ "spread_shock = [100, 200]\n",
+ "spread_shock = [x / curr_spread for x in spread_shock]\n",
"portf = build_portf(position_date, spread_date)\n",
"\n",
"vol_surface = {}\n",
@@ -480,38 +449,21 @@
" vs = BlackSwaptionVolSurface(trade.index.index_type, trade.index.series, \n",
" value_date=spread_date, interp_method = \"bivariate_linear\")\n",
" except:\n",
- " vs = BlackSwaptionVolSurface(trade.index.index_type, trade.index.series + 1, \n",
- " value_date=spread_date, interp_method = \"bivariate_linear\")\n",
+ " vs = BlackSwaptionVolSurface(trade.index.index_type, trade.index.series, \n",
+ " value_date=spread_date- BDay(4), interp_method = \"bivariate_linear\")\n",
" vol_surface[(trade.index.index_type, trade.index.series, trade.option_type)] = vs[vs.list(source='MS', option_type=trade.option_type)[-1]]\n",
"\n",
+ "portf.reset_pv()\n",
"scens = run_portfolio_scenarios(portf, date_range=[pd.Timestamp(spread_date)], params=[\"pnl\"],\n",
- " spread_shock=widen,\n",
- " vol_shock=[0],\n",
+ " spread_shock=spread_shock,\n",
+ " vol_shock=[0, .3],\n",
" corr_shock = [0],\n",
" vol_surface=vol_surface)\n",
"\n",
"attrib = (scens.\n",
" reset_index(level=['date'], drop=True).\n",
" groupby(level=0, axis=1).sum())\n",
- "results = attrib.xs((widen[2], 0., 0.), level=['spread_shock', 'corr_shock', 'vol_shock']).T"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "results"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "results.to_csv('/home/serenitas/edwin/Python/reto_results.csv')"
+ "results = attrib.xs((spread_shock[1], 0., 0), level=['spread_shock', 'corr_shock', 'vol_shock']).T"
]
},
{
@@ -521,30 +473,50 @@
"outputs": [],
"source": [
"################################### Run set of scenario\n",
- "spread_shock = np.round(np.arange(-.2, 1, .05), 3)\n",
- "scens = run_portfolio_scenarios(portf, date_range=[pd.Timestamp(spread_date)], params=['pnl', 'delta'],\n",
+ "curr_spread = analytics._ontr['HY'].spread\n",
+ "spread_shock = [-100, -25, 1, +25 , 100]\n",
+ "spread_shock = [x / curr_spread for x in spread_shock]\n",
+ "vol_shock = 0.0\n",
+ "corr_shock = 0\n",
+ "portf = build_portf(position_date, spread_date)\n",
+ "\n",
+ "vol_surface = {}\n",
+ "for trade in portf.swaptions:\n",
+ " try:\n",
+ " vs = BlackSwaptionVolSurface(trade.index.index_type, trade.index.series, \n",
+ " value_date=spread_date, interp_method = \"bivariate_linear\")\n",
+ " except:\n",
+ " vs = BlackSwaptionVolSurface(trade.index.index_type, trade.index.series, \n",
+ " value_date=spread_date- BDay(4), interp_method = \"bivariate_linear\")\n",
+ " vol_surface[(trade.index.index_type, trade.index.series, trade.option_type)] = vs[vs.list(source='MS', option_type=trade.option_type)[-1]]\n",
+ "\n",
+ "portf.reset_pv()\n",
+ "scens = run_portfolio_scenarios(portf, date_range=[pd.Timestamp(spread_date)], params=['pnl'],\n",
" spread_shock=spread_shock,\n",
- " vol_shock=[.5],\n",
- " corr_shock=[0],\n",
+ " vol_shock=[vol_shock],\n",
+ " corr_shock=[corr_shock],\n",
" vol_surface=vol_surface)\n",
"\n",
"pnl = scens.xs('pnl', axis=1, level=2)\n",
- "pnl = pnl.xs((0,0), level=['vol_shock', 'corr_shock'])\n",
+ "pnl = pnl.xs((vol_shock, corr_shock), level=['vol_shock', 'corr_shock'])\n",
"\n",
"scenarios = (pnl.\n",
" reset_index(level=['date'], drop=True).\n",
" groupby(level=0, axis=1).sum())\n",
"\n",
"options = ['HYOPTDEL', 'HYPAYER', 'HYREC', 'IGOPTDEL', 'IGPAYER', 'IGREC']\n",
- "tranches = ['HYMEZ', 'HYINX', 'HYEQY', 'IGMEZ', 'IGINX', 'IGEQY', 'IGSNR', 'IGINX', 'BSPK', 'XOMEZ', 'XOINX']\n",
- "\n",
- "scenarios['options'] = scenarios[set(scenarios.columns).intersection(options)].sum(axis=1)\n",
- "scenarios['tranches'] = scenarios[set(scenarios.columns).intersection(tranches)].sum(axis=1)\n",
+ "tranches = ['HYMEZ', 'HYINX', 'HYEQY', 'IGMEZ', 'IGINX', 'IGEQY', 'IGSNR', 'IGINX', 'BSPK', 'XOMEZ', 'XOINX', 'EUMEZ']\n",
+ "hedges = ['HEDGE_CLO', 'HEDGE_MAC', 'HEDGE_MBS']\n",
"\n",
- "synthetic = scenarios[['options', 'tranches', 'curve_trades']]\n",
+ "synthetic =pd.DataFrame()\n",
+ "synthetic['options'] = scenarios[set(scenarios.columns).intersection(options)].sum(axis=1)\n",
+ "synthetic['tranches'] = scenarios[set(scenarios.columns).intersection(tranches)].sum(axis=1)\n",
+ "synthetic['curve_trades'] = scenarios['curve_trades']\n",
"synthetic['total'] = synthetic.sum(axis = 1)\n",
"nav = go.get_net_navs()\n",
- "(synthetic/nav.endbooknav[-1]).plot()"
+ "#(synthetic/nav.endbooknav[-1])\n",
+ "scenarios.sum(axis=1)\n",
+ "scenarios.sum(axis=1).to_clipboard()"
]
},
{
@@ -578,7 +550,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.1"
+ "version": "3.8.5"
}
},
"nbformat": 4,