aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/exploration/tranches.py76
-rw-r--r--python/notebooks/tranche and swaption portfolio strategy.ipynb205
2 files changed, 206 insertions, 75 deletions
diff --git a/python/exploration/tranches.py b/python/exploration/tranches.py
index 430e8492..a8e8d05e 100644
--- a/python/exploration/tranches.py
+++ b/python/exploration/tranches.py
@@ -9,7 +9,6 @@ import pandas as pd
from analytics import Swaption, BlackSwaption, Index, BlackSwaptionVolSurface, Portfolio, ProbSurface
from analytics.scenarios import run_swaption_scenarios, run_index_scenarios, run_portfolio_scenarios, run_tranche_scenarios
-import exploration.swaption_calendar_spread as spread
from scipy.interpolate import interp1d
from datetime import date
@@ -77,7 +76,7 @@ def dispersion():
maturities = {}
settings = Settings()
for series in [24, 25, 26, 27, 28, 29]:
- index_temp = idx_bkt.MarkitBasketIndex('IG', series, ["5yr",], trade_date=trade_date)
+ index_temp = idx_bkt.MarkitBasketIndex('IG', series, ["5yr",], value_date=trade_date)
maturities[series] = index_temp.maturities[0]
cds_schedule = Schedule.from_rule(settings.evaluation_date, Date.from_datetime(maturities[series]),
Period('3M'), WeekendsOnly(), date_generation_rule=Rule.CDS2015)
@@ -95,76 +94,3 @@ def dispersion():
dispersion = pd.concat(disp)
curve_df.groupby(['series', 'maturity']).mean()
curve_df.groupby(['series', 'maturity']).std()
-
-def run_scen(portf, tranche, spread_shock):
-
- #Start with swaptions
- index = portf.indices[0].index_type
- series = portf.indices[0].series
- trade_date=portf.indices[0].trade_date
-
- earliest_expiry = min(portf.swaptions, key=lambda x: x.exercise_date).exercise_date
- date_range = pd.bdate_range(trade_date, earliest_expiry - pd.offsets.BDay(), freq='5B')
- vs = BlackSwaptionVolSurface(index,series, trade_date=trade_date)
- ps = ProbSurface(index,series, trade_date=trade_date)
- vol_surface = vs[vs.list(option_type='payer')[-1]]
- df = run_portfolio_scenarios(portf, date_range, spread_shock, np.array([0]),
- vol_surface, params=["pnl", "delta"])
- df['frac_year'] = (df.index - pd.to_datetime(trade_date)).days/365
- df['prob'] = df.apply(lambda df: ps.tail_prob(df.frac_year, df.spread, ps.list()[-1]), axis=1)
-
- #now do the tranches
- spread_range = (1+ spread_shock) * portf.indices[0].spread
- results = run_tranche_scenarios(tranche, spread_range, date_range)
- results.date = pd.to_datetime(results.date)
- notional = 10000000
- results['delta_tranche'] = -notional * (results['0-3_delta'] - 6* results['7-15_delta'])
- results['pnl_tranche'] = notional * (results['0-3_pnl'] + results['0-3_carry'] -
- 6* (results['7-15_pnl'] + results['7-15_carry']))
- results.index.name = 'spread'
-
- #combine
- df = df.reset_index().merge(results.reset_index(), on=['date', 'spread'])
- df['final_pnl'] = df.pnl_tranche + df.pnl
- df['final_delta'] = df.delta_tranche + df.delta
-
- return df
-
-def set_port():
-
- #Construct Portfolio
- option_delta = Index.from_name('IG', 30, '5yr')
- option_delta.spread = 59
-
- option1 = BlackSwaption(option_delta, date(2018, 6, 20), 80, option_type="payer")
- option1.sigma = .621
- option1.direction = 'Short'
-
- option1.notional = 150_000_000
- option_delta.notional = 1
-
- portf = Portfolio([option1, option_delta])
- portf.reset_pv()
- trade_date = (pd.datetime.today() - pd.offsets.BDay(1)).normalize()
- tranche = bkt.TrancheBasket('IG', 29, '5yr', trade_date=trade_date)
-
- return portf, tranche
-
-def set_df():
-
- portf, tranche = set_port()
-
- shock_min = -.3
- shock_max = .8
- spread_shock = np.arange(shock_min, shock_max, 0.05)
- shock_range = (1+ spread_shock) * portf.indices[0].spread
-
- results = run_scen(portf, tranche, spread_shock)
- results = results.set_index('date')
- return results, shock_range
-
-def plot_scenarios():
-
- df, shock_range = set_df()
- plot_time_color_map(df, shock_range, attr="final_pnl")
- plot_time_color_map(df, shock_range, attr="final_delta", color_map= 'rainbow', centered = False)
diff --git a/python/notebooks/tranche and swaption portfolio strategy.ipynb b/python/notebooks/tranche and swaption portfolio strategy.ipynb
new file mode 100644
index 00000000..8e73f973
--- /dev/null
+++ b/python/notebooks/tranche and swaption portfolio strategy.ipynb
@@ -0,0 +1,205 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import analytics.tranche_basket as bkt\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "from analytics.scenarios import run_tranche_scenarios, run_portfolio_scenarios\n",
+ "from analytics import Swaption, BlackSwaption, Index, BlackSwaptionVolSurface, Portfolio, ProbSurface\n",
+ "from db import dbengine\n",
+ "from datetime import date\n",
+ "from graphics import plot_time_color_map\n",
+ "\n",
+ "dawnengine = dbengine('dawndb')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "value_date = (pd.datetime.today() - pd.offsets.BDay(1)).date()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Construct IG Swaption Portfolio\n",
+ "index = 'IG'\n",
+ "series = 30\n",
+ "option_delta = Index.from_name(index, series, '5yr')\n",
+ "option_delta.spread = 65\n",
+ "option1 = BlackSwaption(option_delta, date(2018, 10, 17), 60, option_type=\"payer\")\n",
+ "option1.sigma = .398\n",
+ "option1.direction = 'Long'\n",
+ "option2 = BlackSwaption(option_delta, date(2018, 10, 17), 100, option_type=\"payer\")\n",
+ "option2.sigma = .609\n",
+ "option2.direction = 'Short'\n",
+ "option1.notional = 100_000_000\n",
+ "option2.notional = 300_000_000\n",
+ "option_delta.notional = option1.notional * option1.delta + option2.notional * option2.delta\n",
+ "\n",
+ "portf = Portfolio([option1, option2, option_delta])\n",
+ "portf.value_date = value_date\n",
+ "portf.reset_pv()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Run Swaption sensitivities\n",
+ "#Set Shock range\n",
+ "shock_min = -.3\n",
+ "shock_max = 1.5\n",
+ "spread_shock = np.arange(shock_min, shock_max, 0.05)\n",
+ "#Set Date range\n",
+ "earliest_expiry = min(portf.swaptions, key=lambda x: x.exercise_date).exercise_date\n",
+ "date_range = pd.bdate_range(value_date, earliest_expiry - pd.offsets.BDay(), freq='20B')\n",
+ "#Setup Vol Surface\n",
+ "vs = BlackSwaptionVolSurface(index,series, value_date=value_date)\n",
+ "ps = ProbSurface(index,series, value_date=value_date)\n",
+ "vol_surface = vs[vs.list(option_type='payer')[-1]]\n",
+ "swaption_scens = run_portfolio_scenarios(portf, date_range, spread_shock, np.array([0]),\n",
+ " vol_surface, params=[\"pnl\", \"delta\"])\n",
+ "#swaption delta is in protection terms: switch to risk terms\n",
+ "swaption_scens.delta = -swaption_scens.delta"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Get current Tranche positions\n",
+ "sql_string = \"select * from list_tranche_marks(%s)\"\n",
+ "pos = pd.read_sql_query(sql_string, dawnengine, params=(value_date,), parse_dates=['maturity'])\n",
+ "tranche_port = []\n",
+ "for i, r in pos.iterrows():\n",
+ " tranche_port.append(bkt.TrancheBasket(r.p_index, r.p_series, '5yr'))\n",
+ " tranche_port[i].build_skew()\n",
+ "pos['basket'] = tranche_port\n",
+ "#Set Shock Range\n",
+ "spread_range = (1+ spread_shock) * option_delta.spread\n",
+ "#Run tranche scenarios\n",
+ "temp = []\n",
+ "for i, r in pos.iterrows():\n",
+ " df = run_tranche_scenarios(r.basket, spread_range, date_range, corr_map=False)\n",
+ " temp.append(r.notional*df.xs(str(r.attach) + \"-\" + str(r.detach), axis=1, level=1))\n",
+ "tranches_scens = sum(temp)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "total_scens = swaption_scens.reset_index().merge(tranches_scens.reset_index(), \n",
+ " left_on=['date', 'spread'], \n",
+ " right_on=['date', 'spread_range'], \n",
+ " suffixes=['_s', '_t'])\n",
+ "total_scens['pnl'] = total_scens['pnl_s'] + total_scens['pnl_t']\n",
+ "total_scens['delta'] = total_scens['delta_s'] + total_scens['delta_t']\n",
+ "total_scens_single_date = total_scens.set_index('date').xs(date_range[0])\n",
+ "total_scens_single_date = total_scens_single_date.set_index('spread', drop=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#tranche positions delta at different spreads \n",
+ "ax = total_scens_single_date.delta_t.plot()\n",
+ "ax.ticklabel_format(style='plain')\n",
+ "plt.tight_layout()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Tranche + Swaptions positions delta at different spreads\n",
+ "ax1 = total_scens_single_date.delta.plot()\n",
+ "ax1.ticklabel_format(style='plain')\n",
+ "plt.tight_layout()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "total_scens_single_date[['delta', 'delta_t', 'delta_s']].plot()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "total_scens_single_date[['pnl', 'pnl_t', 'pnl_s']].plot()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "total_scens.date = pd.to_datetime(total_scens.date)\n",
+ "total_scens = total_scens.set_index(['date'])\n",
+ "plot_time_color_map(total_scens, spread_range, attr=\"pnl\")\n",
+ "#plot_time_color_map(df, shock_range, attr=\"final_delta\", color_map= 'rainbow', centered = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}