aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/analytics/portfolio.py4
-rw-r--r--python/exploration/swaption_calendar_spread.py89
-rw-r--r--python/graphics.py17
-rw-r--r--python/notebooks/Option Trades.ipynb150
4 files changed, 65 insertions, 195 deletions
diff --git a/python/analytics/portfolio.py b/python/analytics/portfolio.py
index 809b49a2..43d9b5e7 100644
--- a/python/analytics/portfolio.py
+++ b/python/analytics/portfolio.py
@@ -88,11 +88,11 @@ class Portfolio:
vs = BlackSwaptionVolSurface(index_type, series, tenor, index.value_date)
if surface_id is None:
for source in source_list:
- if len(vs.list(source, option_type, model)) >=1:
+ if len(vs.list(source)) >=1:
break
else:
raise ValueError("No market data available for this day")
- self._vs[k] = vs[vs.list(source, option_type, model)[-1]]
+ self._vs[k] = vs[vs.list(source)[-1]]
else:
self._vs[k] = vs[surface_id]
for swaption in self.swaptions:
diff --git a/python/exploration/swaption_calendar_spread.py b/python/exploration/swaption_calendar_spread.py
deleted file mode 100644
index e21ffd66..00000000
--- a/python/exploration/swaption_calendar_spread.py
+++ /dev/null
@@ -1,89 +0,0 @@
-import sys
-#don't do this at home
-sys.path.append("..")
-from analytics import (Swaption, BlackSwaption, BlackSwaptionVolSurface,
- Index, ProbSurface, Portfolio)
-from analytics.scenarios import run_swaption_scenarios, run_index_scenarios, run_portfolio_scenarios
-from pandas.tseries.offsets import BDay
-import datetime
-import numpy as np
-import pandas as pd
-from scipy.interpolate import SmoothBivariateSpline
-
-import os
-import numpy as np
-import matplotlib
-import matplotlib.pyplot as plt
-from graphics import plot_time_color_map, plot_color_map
-
-from db import dbengine
-engine = dbengine('serenitasdb')
-
-def plot_df(df, spread_shock, vol_shock, attr="pnl"):
- val_date = df.index[0].date()
- fig = plt.figure()
-
- ax = fig.gca(projection='3d')
- ## use smoothing spline on a finer grid
- series = df[attr]
- f = SmoothBivariateSpline(df.vol_shock.values, df.spread_shock.values, series.values)
- xx, yy = np.meshgrid(vol_shock, spread_shock)
- surf = ax.plot_surface(xx, yy, f(vol_shock, spread_shock).T, cmap=cm.viridis)
- ax.set_xlabel("Volatility shock")
- ax.set_ylabel("Spread")
- ax.set_zlabel("PnL")
- ax.set_title('{} of Trade on {}'.format(attr.title(), val_date))
-
-def plot_trade_scenarios(portf, shock_min=-.15, shock_max=.2, period=-1, vol_time_roll=True):
- portf.reset_pv()
- earliest_date = min(portf.swaptions, key=lambda x: x.exercise_date).exercise_date
- date_range = pd.bdate_range(portf.indices[0].trade_date,
- earliest_date - BDay(), freq='3B')
- vol_shock = np.arange(-0.15, 0.3, 0.01)
- spread_shock = np.arange(shock_min, shock_max, 0.01)
- index = portf.indices[0].name.split()[1]
- series = portf.indices[0].name.split()[3][1:]
- vs = BlackSwaptionVolSurface(index, series, trade_date=portf.indices[0].trade_date)
- vol_surface = vs[vs.list(option_type='payer')[-1]]
-
- df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface,
- params=["pnl","delta"])
-
- hy_plot_range = 100 + (500 - portf.indices[0].spread * (1 + spread_shock)) * \
- abs(portf.indices[0].DV01) / portf.indices[0].notional * 100
-
- shock = hy_plot_range if index == 'HY' else portf.indices[0].spread * (1 + spread_shock)
-
- plot_time_color_map(df[round(df.vol_shock,2)==0], shock, 'pnl', index=index)
- plot_time_color_map(df[round(df.vol_shock,2)==.2], shock, 'pnl', index=index)
- plot_color_map(df.loc[date_range[period]], shock, vol_shock, 'pnl', index=index)
- return df
-
-def exercise_probability():
- engine = dbengine('serenitasdb')
- #Ad hoc
- option_delta = Index.from_name('HY', 29, '5yr')
- option_delta.price = 107.875
- option1 = BlackSwaption(option_delta, datetime.date(2017, 12, 20), 107, option_type="payer")
- option2 = BlackSwaption(option_delta, datetime.date(2017, 12, 20), 105, option_type="payer")
- option1.sigma = .280
- option2.sigma = .371
- option1.notional = 20_000_000
- option2.notional = 40_000_000
- option1.direction = 'Long'
- option2.direction = 'Short'
- option_delta.notional = option1.notional * option1.delta + option2.notional * option2.delta
- option_delta.direction = 'Seller' if option_delta.notional > 0 else 'Buyer'
- option_delta.notional = abs(option_delta.notional)
- portf = Portfolio([option1, option2, option_delta])
-
- portf.reset_pv()
- earliest_date = min(portf.swaptions, key=lambda x: x.exercise_date).exercise_date
- date_range = pd.bdate_range(portf.indices[0].trade_date, earliest_date - BDay(), freq='5B')
- vol_shock = np.arange(-0.15, 0.3, 0.01)
- spread_shock = np.arange(-0.15, 0.35, 0.01)
- index = portf.indices[0].name.split()[1]
- series = portf.indices[0].name.split()[3][1:]
-
- vs = ProbSurface(index, series, trade_date=portf.indices[0].trade_date)
- vs.plot(vs.list()[-1])
diff --git a/python/graphics.py b/python/graphics.py
index cc538aa8..fc9764bb 100644
--- a/python/graphics.py
+++ b/python/graphics.py
@@ -141,4 +141,19 @@ def plot_prob_map(df, attr="pnl", path=".", color_map=cm.RdYlGn, index='IG'):
ax.set_ylabel('Probability')
ax.set_title('{} of Trade'.format(attr.title()))
- fig.colorbar(chart, shrink=.8) \ No newline at end of file
+ fig.colorbar(chart, shrink=.8)
+
+def plot_swaption_df(df, spread_shock, vol_shock, attr="pnl"):
+ val_date = df.index[0].date()
+ fig = plt.figure()
+
+ ax = fig.gca(projection='3d')
+ ## use smoothing spline on a finer grid
+ series = df[attr]
+ f = SmoothBivariateSpline(df.vol_shock.values, df.spread_shock.values, series.values)
+ xx, yy = np.meshgrid(vol_shock, spread_shock)
+ surf = ax.plot_surface(xx, yy, f(vol_shock, spread_shock).T, cmap=cm.viridis)
+ ax.set_xlabel("Volatility shock")
+ ax.set_ylabel("Spread")
+ ax.set_zlabel("PnL")
+ ax.set_title('{} of Trade on {}'.format(attr.title(), val_date)) \ No newline at end of file
diff --git a/python/notebooks/Option Trades.ipynb b/python/notebooks/Option Trades.ipynb
index f550923d..ff4c6525 100644
--- a/python/notebooks/Option Trades.ipynb
+++ b/python/notebooks/Option Trades.ipynb
@@ -6,11 +6,15 @@
"metadata": {},
"outputs": [],
"source": [
+ "import datetime\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "\n",
+ "from graphics import plot_time_color_map, plot_color_map\n",
"from analytics import Swaption, BlackSwaption, BlackSwaptionVolSurface, Index, Portfolio\n",
"from analytics.scenarios import run_swaption_scenarios, run_index_scenarios, run_portfolio_scenarios\n",
- "import datetime\n",
"\n",
- "from exploration.swaption_calendar_spread import plot_trade_scenarios\n",
+ "#from exploration.swaption_calendar_spread import plot_trade_scenarios\n",
"#import swaption_calendar_spread as spread"
]
},
@@ -29,17 +33,48 @@
"metadata": {},
"outputs": [],
"source": [
+ "def plot_trade_scenarios(portf, shock_min=-.15, shock_max=.2, period=-1, vol_time_roll=True):\n",
+ " portf.reset_pv()\n",
+ " earliest_date = min(portf.swaptions, key=lambda x: x.exercise_date).exercise_date\n",
+ " date_range = pd.bdate_range(portf.indices[0].value_date,\n",
+ " earliest_date - pd.tseries.offsets.BDay(), freq='3B')\n",
+ " vol_shock = np.arange(-0.15, 0.3, 0.01)\n",
+ " spread_shock = np.arange(shock_min, shock_max, 0.01)\n",
+ " index = portf.indices[0].name.split()[1]\n",
+ " series = portf.indices[0].name.split()[3][1:]\n",
+ " vs = BlackSwaptionVolSurface(index, series, value_date=portf.indices[0].value_date)\n",
+ " vol_surface = vs[vs.list(option_type='payer')[-1]]\n",
+ "\n",
+ " df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface,\n",
+ " params=[\"pnl\",\"delta\"])\n",
+ "\n",
+ " hy_plot_range = 100 + (500 - portf.indices[0].spread * (1 + spread_shock)) * \\\n",
+ " abs(portf.indices[0].DV01) / portf.indices[0].notional * 100\n",
+ "\n",
+ " shock = hy_plot_range if index == 'HY' else portf.indices[0].spread * (1 + spread_shock)\n",
+ "\n",
+ " plot_time_color_map(df[round(df.vol_shock,2)==0], shock, 'pnl', index=index)\n",
+ " plot_time_color_map(df[round(df.vol_shock,2)==.2], shock, 'pnl', index=index)\n",
+ " plot_color_map(df.loc[date_range[period]], shock, vol_shock, 'pnl', index=index)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
"#Ad hoc\n",
- "option_delta = Index.from_name('IG', 29, '5yr', trade_date=datetime.date(2018, 1, 3))\n",
- "option_delta.spread = 50\n",
- "option1 = BlackSwaption(option_delta, datetime.date(2018, 2, 21), 55, option_type=\"payer\")\n",
- "option2 = BlackSwaption(option_delta, datetime.date(2018, 2, 21), 67.5, option_type=\"payer\")\n",
- "option3 = BlackSwaption(option_delta, datetime.date(2018, 2, 21), 80, option_type=\"payer\")\n",
- "option1.sigma = .38\n",
- "option2.sigma = .61\n",
+ "option_delta = Index.from_name('IG', 30, '5yr', value_date=datetime.date(2018, 5, 17))\n",
+ "option_delta.spread = 61\n",
+ "option1 = BlackSwaption(option_delta, datetime.date(2018, 8, 15), 60, option_type=\"payer\")\n",
+ "option2 = BlackSwaption(option_delta, datetime.date(2018, 8, 15), 80, option_type=\"payer\")\n",
+ "option3 = BlackSwaption(option_delta, datetime.date(2018, 8, 15), 80, option_type=\"payer\")\n",
+ "option1.sigma = .381\n",
+ "option2.sigma = .545\n",
"option3.sigma = .69\n",
"option1.notional = 100_000_000\n",
- "option2.notional = 200_000_000\n",
+ "option2.notional = 300_000_000\n",
"option3.notional = 1\n",
"option1.direction = 'Long'\n",
"option2.direction = 'Short'\n",
@@ -68,34 +103,6 @@
"metadata": {},
"outputs": [],
"source": [
- "portf.trade_date = datetime.date(2018,2,1)\n",
- "portf.ref = 52\n",
- "#portf.swaptions[0].sigma = .25\n",
- "#portf.swaptions[1].sigma = .31\n",
- "#portf.swaptions[2].sigma = .46\n",
- "portf.swaptions[0].sigma = .38\n",
- "portf.swaptions[1].sigma = .61\n",
- "#portf.swaptions[2].sigma = .69\n",
- "portf"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "df.spread = df.spread.round(2)\n",
- "df1= df.set_index('spread', append=True)\n",
- "df1.xs(('2018-01-16', '66.0'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
"#Dec Jan 2017 Trade\n",
"option_delta = Index.from_tradeid(864)\n",
"option1 = BlackSwaption.from_tradeid(3, option_delta)\n",
@@ -147,7 +154,7 @@
"option_delta_pf.notional = 50_335_169\n",
"\n",
"portf = Portfolio([option1_pf, option2_pf, option_delta_pf])\n",
- "portf.trade_date = datetime.date(2017, 5, 17)\n",
+ "portf.value_date = datetime.date(2017, 5, 17)\n",
"portf.mark()\n",
"plot_trade_scenarios(portf)"
]
@@ -171,69 +178,6 @@
"execution_count": null,
"metadata": {},
"outputs": [],
- "source": [
- "#Ad hoc\n",
- "option_delta = Index.from_name('IG', 29, '5yr')\n",
- "option_delta.spread = 49.5\n",
- "option1 = BlackSwaption(option_delta, datetime.date(2018, 2, 21), 55, option_type=\"payer\")\n",
- "option2 = BlackSwaption(option_delta, datetime.date(2018, 2, 21), 67.5, option_type=\"payer\")\n",
- "option3 = BlackSwaption(option_delta, datetime.date(2018, 1, 21), 52.5, option_type=\"payer\")\n",
- "option4 = BlackSwaption(option_delta, datetime.date(2018, 1, 21), 60, option_type=\"payer\")\n",
- "option1.sigma = .38\n",
- "option2.sigma = .61\n",
- "option3.sigma = .371\n",
- "option4.sigma = .581\n",
- "option1.notional = 100_000_000\n",
- "option2.notional = 200_000_000\n",
- "option3.notional = 100_000_000\n",
- "option4.notional = 100_000_000\n",
- "option1.direction = 'Long'\n",
- "option2.direction = 'Short'\n",
- "option3.direction = 'Short'\n",
- "option4.direction = 'Long'\n",
- "#option_delta.notional = 1\n",
- "option_delta.notional = option1.notional * option1.delta + option2.notional * option2.delta \n",
- "option_delta.direction = 'Seller' if option_delta.notional > 0 else 'Buyer'\n",
- "option_delta.notional = abs(option_delta.notional)\n",
- "portf = Portfolio([option1, option2, option3, option4, option_delta])\n",
- "#Plot Scenarios Inputs: Portfolio, spread shock tightening%, spread shock widening%, snapshot period)\n",
- "plot_trade_scenarios(portf, -.15, .8, -4, vol_time_roll=False)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "portf"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "portf.pv"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "portf.trade_date = datetime.date(2018,1,16)\n",
- "portf.ref = 47\n",
- "portf.pnl"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
"source": []
}
],
@@ -253,7 +197,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.4"
+ "version": "3.6.5"
}
},
"nbformat": 4,