aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/exploration/swaption_calendar_spread.py165
-rw-r--r--python/notebooks/Option Trades.ipynb142
-rw-r--r--python/option_trades_et.py336
3 files changed, 169 insertions, 474 deletions
diff --git a/python/exploration/swaption_calendar_spread.py b/python/exploration/swaption_calendar_spread.py
index 3cf23b52..304e7be9 100644
--- a/python/exploration/swaption_calendar_spread.py
+++ b/python/exploration/swaption_calendar_spread.py
@@ -11,6 +11,7 @@ from scipy.interpolate import SmoothBivariateSpline
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
+from operator import attrgetter
import os
import numpy as np
@@ -88,16 +89,16 @@ def plot_df(df, spread_shock, vol_shock, attr="pnl"):
ax.set_zlabel("PnL")
ax.set_title('{} of Trade on {}'.format(attr.title(), val_date))
-def plot_color_map(df, spread_shock, vol_shock, attr="pnl", path="."):
+def plot_color_map(df, spread_shock, vol_shock, attr="pnl", path=".", index ='IG'):
val_date = df.index[0].date()
#rows are spread, columns are volatility surface shift
fig, ax = plt.subplots()
#We are plotting an image, so we have to sort from high to low on the Y axis
- df.sort_values(by=['spread','vol_shock'], ascending = [True,False], inplace = True)
+ ascending = [False,False] if index == 'HY' else [True,False]
+ df.sort_values(by=['spread','vol_shock'], ascending = ascending, inplace = True)
series = df[attr]
- #import pdb; pdb.set_trace()
midpoint = 1 - series.max() / (series.max() + abs(series.min()))
shifted_cmap = shiftedColorMap(cm.RdYlGn, midpoint=midpoint, name='shifted')
@@ -106,21 +107,23 @@ def plot_color_map(df, spread_shock, vol_shock, attr="pnl", path="."):
vol_shock.min(), vol_shock.max()),
aspect='auto', interpolation='bilinear', cmap=shifted_cmap)
- ax.set_xlabel('Spread')
+ ax.set_xlabel('Price') if index == 'HY' else ax.set_xlabel('Spread')
ax.set_ylabel('Volatility shock')
ax.set_title('{} of Trade on {}'.format(attr.title(), val_date))
fig.colorbar(chart, shrink=.8)
#fig.savefig(os.path.join(path, "vol_spread_color_map"+ attr+ "_{}.png".format(val_date)))
-def plot_time_color_map(df, spread_shock, attr="pnl", path=".", color_map = cm.RdYlGn):
+def plot_time_color_map(df, spread_shock, attr="pnl", path=".", color_map = cm.RdYlGn, index ='IG'):
val_date = df.index[0].date()
df = df.reset_index()
df['days'] = (df['date'] - val_date).dt.days
- df.sort_values(by=['date','spread'], ascending = [True,False], inplace = True)
+ ascending = [True,True] if index == 'HY' else [True,False]
+ df.sort_values(by=['date','spread'], ascending = ascending, inplace = True)
date_range = df.days.unique()
+ #plt.style.use('seaborn-whitegrid')
fig, ax = plt.subplots()
series = df[attr]
midpoint = 1 - series.max() / (series.max() + abs(series.min()))
@@ -131,152 +134,38 @@ def plot_time_color_map(df, spread_shock, attr="pnl", path=".", color_map = cm.R
spread_shock.min(), spread_shock.max()),
aspect='auto', interpolation='bilinear', cmap=shifted_cmap)
+ #chart = ax.contour(date_range, spread_shock, series.values.reshape(date_range.size, spread_shock.size).T)
+
ax.set_xlabel('Days')
- ax.set_ylabel('Spread')
+ ax.set_ylabel('Price') if index == 'HY' else ax.set_ylabel('Spread')
ax.set_title('{} of Trade'.format(attr.title()))
fig.colorbar(chart, shrink=.8)
#fig.savefig(os.path.join(path, "spread_time_color_map_"+ attr+ "_{}.png".format(val_date)))
-def dec_jan_2017_trade():
- option_delta = Index.from_tradeid(864)
- option1 = BlackSwaption.from_tradeid(3, option_delta)
- option2 = BlackSwaption.from_tradeid(4, option_delta)
-
- portf = Portfolio([option1, option2, option_delta])
- date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-01-18') - BDay(), freq = '2B')
- vol_shock = np.arange(-0.15, 0.3, 0.01)
- spread_shock = np.arange(-0.2, 0.3, 0.01)
- vs = VolatilitySurface("IG", 27, trade_date=option_delta.trade_date)
- vol_select = vs.list('BAML', 'payer', 'black')[-1]
- vol_surface = vs[vol_select]
-
- df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock,
- vol_surface, params=["pnl", "delta"], vol_time_roll=False)
- plot_time_color_map(df[round(df.vol_shock,2)==0], option_delta.spread * (1 + spread_shock), 'pnl')
-
-def april_may_2017_trade(what='pnl'):
- option_delta = Index.from_tradeid(870)
- option1 = BlackSwaption.from_tradeid(5, option_delta)
- option2 = BlackSwaption.from_tradeid(6, option_delta)
-
- portf = Portfolio([option1, option2, option_delta])
- date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-04-19') - BDay(), freq = '2B')
- vol_shock = np.arange(-0.15, 0.3, 0.01)
- spread_shock = np.arange(-0.2, 0.3, 0.01)
- vs = VolatilitySurface("IG", 27, trade_date=option_delta.trade_date)
- vol_select = vs.list('BAML', 'payer', 'black')[-1]
- vol_surface = vs[vol_select]
-
- df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock,
- vol_surface, params=[what], vol_time_roll=False)
- plot_time_color_map(df[abs(df.vol_shock)<1e-3], option_delta.spread * (1 + spread_shock), what)
-
-
-def june_july_2017_trade():
- option_delta_pf = Index.from_tradeid(874)
- option_delta2_pf = Index.from_tradeid(879)
-
- option1_pf = BlackSwaption.from_tradeid(7, option_delta_pf)
- option2_pf = BlackSwaption.from_tradeid(9, option_delta_pf)
- #option_delta.notional = option_delta.notional - option_delta2.notional
- option_delta_pf.notional = 50_335_169
-
- portf = Portfolio([option1_pf, option2_pf, option_delta_pf])
- portf.trade_date = datetime.date(2017, 5, 17)
- portf.mark()
- portf.reset_pv()
-
- date_range = pd.bdate_range(option_delta_pf.trade_date, pd.Timestamp('2017-06-21') - BDay(), freq = '2B')
- vol_shock = np.arange(-0.15, 0.3, 0.01)
- spread_shock = np.arange(-0.2, 0.3, 0.01)
- vs = VolatilitySurface("IG", 28, trade_date=option_delta_pf.trade_date)
- vol_select = vs.list('BAML', 'payer', 'black')[-1]
- vol_surface = vs[vol_select]
-
- df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface,
- params=["pnl", "delta"], vol_time_roll=True)
+def plot_trade_scenarios(portf):
- #period = -4
- #plot_df(df.loc[date_range[period]], spread_plot_range, vol_shock_range)
- #plot_color_map(df.loc[date_range[period]], option_delta.spread * (1 + spread_shock), vol_shock, 'pnl')
- plot_time_color_map(df[round(df.vol_shock,2)==0], option_delta_pf.spread * (1 + spread_shock), 'pnl')
- #plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'delta', color_map = cm.coolwarm_r)
- return df
-
-def hy_trade_scenario():
-
- #Manually Load trades
- option_delta = Index.from_name('hy', 28, '5yr')
- option_delta.price = 107.5
- option1 = BlackSwaption(option_delta, datetime.date(2017, 8, 16), 106, option_type="payer")
- option2 = BlackSwaption(option_delta, datetime.date(2017, 8, 16), 104, option_type="payer")
- option1.sigma = .331
- option2.sigma = .388
- option1.notional = 20_000_000
- option2.notional = 40_000_000
- option2.direction = 'Short'
- option_delta.notional = -(option1.delta * option1.notional + option2.delta*option2.notional)
- if option_delta.notional < 0:
- option_delta.direction = 'Seller'
- option_delta.notional = abs(option_delta.notional)
-
- portf = Portfolio([option1, option2, option_delta])
portf.reset_pv()
- date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-08-16') - BDay(), freq = '5B')
+ earliest_date = min(portf.swaptions,key=attrgetter('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.1, 0.4, 0.01)
- vs = VolatilitySurface("HY", 28, trade_date=option_delta.trade_date)
- vol_select = vs.list('BAML', 'payer', 'black')[-1]
+ 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 = VolatilitySurface(index, series, trade_date=portf.indices[0].trade_date)
+ vol_select = vs.list(option_type='payer', model='black')[-1]
vol_surface = vs[vol_select]
- df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface, params=["pnl", "delta"], vol_time_roll=True)
-
- #period = -4
- #plot_df(df.loc[date_range[period]], spread_plot_range, vol_shock_range)
- #plot_color_map(df.loc[date_range[period]], option_delta.spread * (1 + spread_shock), vol_shock, 'pnl')
- #plot_time_color_map(df[round(df.vol_shock,2)==0], option_delta.spread * (1 + spread_shock), 'pnl')
- hy_plot_range = 100 + (500- option_delta.spread * (1 + spread_shock))*option_delta.DV01/option_delta.notional*100
- plot_time_color_map(df[round(df.vol_shock,2)==0], hy_plot_range, 'pnl')
- #Delta in protection terms: Blue = going short, red = going long
- #plot_time_color_map(df[round(df.vol_shock,2)==0], option_delta.spread * (1 + spread_shock), 'delta', color_map = cm.coolwarm_r)
+ df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface, params=["pnl","delta"], vol_time_roll=True)
- return df
+ hy_plot_range = 100 - (500- portf.indices[0].spread * (1 + spread_shock))*portf.indices[0].DV01/portf.indices[0].notional*100
-def portfolio():
- option_delta = Index.from_tradeid(874)
- option1 = BlackSwaption.from_tradeid(7, option_delta)
- option2 = BlackSwaption.from_tradeid(8, option_delta)
+ shock = hy_plot_range if index == 'HY' else portf.indices[0].spread * (1 + spread_shock)
- portf = Portfolio([option1, option2, option3, option_delta, option_delta1, option_delta2, option_delta3])
- date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-05-17') - BDay(), freq = '2B')
- vol_shock = np.arange(-0.15, 0.3, 0.01)
- spread_shock = np.arange(-0.2, 0.3, 0.01)
- vs = VolatilitySurface("IG", 28, trade_date=option_delta.trade_date)
- vol_select = vs.list('BAML', 'payer', 'black')[-1]
- vol_surface = vs[vol_select]
-
- df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface, params=["pnl", "delta"], vol_time_roll=False)
-
- #plot it
period = -4
- #plot_df(df.loc[date_range[period]], spread_plot_range, vol_shock_range)
- plot_color_map(df.loc[date_range[period]], option_delta.spread * (1 + spread_shock), vol_shock, 'pnl')
- plot_time_color_map(df[round(df.vol_shock,2)==0], option_delta.spread * (1 + spread_shock), 'pnl')
- plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'delta', color_map = cm.coolwarm_r)
-
-def probabilities():
- from scipy.stats import lognorm
-
- option_delta = Index.from_tradeid(874)
- vs = VolatilitySurface("IG", 28, trade_date=option_delta.trade_date)
- vol_select = max([t for t in vs.list() if t[1] == 'BAML' and t[2] == 'payer' and t[3] == 'black'])
- vol_surface = vs[vol_select]
- t = .1
- mon = 1
+ 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)==0], shock, 'delta', color_map = cm.coolwarm_r, index=index)
+ plot_color_map(df.loc[date_range[period]], shock, vol_shock, 'pnl', index=index)
+ #plot_df(df.loc[date_range[period]], shock, vol_shock)
- date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-05-17') - BDay(), freq = 'B')
- curr_vols = np.maximum(vol_surface.ev(t, mon), 0)
- dist = lognorm(curr_vols, scale)
- lognorm.ppf(.5, curr_vols, scale = np.exp(64))
diff --git a/python/notebooks/Option Trades.ipynb b/python/notebooks/Option Trades.ipynb
new file mode 100644
index 00000000..4440d5f2
--- /dev/null
+++ b/python/notebooks/Option Trades.ipynb
@@ -0,0 +1,142 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from analytics import Swaption, BlackSwaption, Index, VolatilitySurface, Portfolio\n",
+ "from analytics.scenarios import run_swaption_scenarios, run_index_scenarios, run_portfolio_scenarios\n",
+ "import datetime\n",
+ "\n",
+ "import swaption_calendar_spread as spread"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Delta Chart: Red = Long Risk, Blue = Short Risk"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Ad hoc\n",
+ "option_delta = Index.from_name('HY', 28, '5yr')\n",
+ "option_delta.price = 107.625\n",
+ "option1 = BlackSwaption(option_delta, datetime.date(2017, 9, 20), 107, option_type=\"payer\")\n",
+ "option2 = BlackSwaption(option_delta, datetime.date(2017, 9, 20), 105, option_type=\"payer\")\n",
+ "option1.sigma = .270\n",
+ "option2.sigma = .3625\n",
+ "option1.notional = 20_000_000\n",
+ "option2.notional = 40_000_000\n",
+ "option1.direction = 'Long'\n",
+ "option2.direction = 'Short'\n",
+ "option_delta.notional = -2000000\n",
+ "#option_delta.notional = option_delta.notional - option_delta2.notional\n",
+ "if option_delta.notional < 0:\n",
+ " option_delta.direction = 'Seller'\n",
+ " option_delta.notional = abs(option_delta.notional)\n",
+ "portf = Portfolio([option1, option2, option_delta])\n",
+ "spread.plot_trade_scenarios(portf)"
+ ]
+ },
+ {
+ "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",
+ "option2 = BlackSwaption.from_tradeid(4, option_delta)\n",
+ "portf = Portfolio([option1, option2, option_delta])\n",
+ "spread.plot_trade_scenarios(portf)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#Feb 2017: Sell May Buy April Calendar Trade\n",
+ "option_delta = Index.from_tradeid(870)\n",
+ "option1 = BlackSwaption.from_tradeid(5, option_delta)\n",
+ "option2 = BlackSwaption.from_tradeid(6, option_delta)\n",
+ "portf = Portfolio([option1, option2, option_delta])\n",
+ "spread.plot_trade_scenarios(portf)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#April 2017: Sell May Buy June Calendar Trade\n",
+ "option_delta = Index.from_tradeid(874)\n",
+ "option1 = BlackSwaption.from_tradeid(7, option_delta)\n",
+ "option2 = BlackSwaption.from_tradeid(8, option_delta)\n",
+ "portf = Portfolio([option1, option2, option_delta])\n",
+ "spread.plot_trade_scenarios(portf)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#June July 2017 Calendar Trade\n",
+ "option_delta_pf = Index.from_tradeid(874)\n",
+ "option_delta2_pf = Index.from_tradeid(879)\n",
+ "\n",
+ "option1_pf = BlackSwaption.from_tradeid(7, option_delta_pf)\n",
+ "option2_pf = BlackSwaption.from_tradeid(9, option_delta_pf)\n",
+ "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.mark()\n",
+ "spread.plot_trade_scenarios(portf)"
+ ]
+ },
+ {
+ "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.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/python/option_trades_et.py b/python/option_trades_et.py
deleted file mode 100644
index 8b64e7b7..00000000
--- a/python/option_trades_et.py
+++ /dev/null
@@ -1,336 +0,0 @@
-import analytics.option as opt
-import pandas as pd
-import numpy as np
-import matplotlib.pyplot as plt
-import numpy as np
-import matplotlib.colors as colors
-import math
-
-from matplotlib import cm
-from exploration.option_trades import *
-from pandas.tseries.offsets import *
-from analytics import Index, ForwardIndex
-from db import dbengine, dbconn
-from scipy.interpolate import *
-
-serenitasdb = dbengine('serenitasdb')
-
-def get_dfs(index="IG"):
- df0 = atm_vol(index, datetime.date(2014, 6, 11))
- df = rolling_vol(df0, 'atm_vol', term=[1,2,3,4,5,6])
- df1 = rolling_vol(df0, 'otm_vol', term=[1,2,3,4,5,6])
- return (df,df1)
-
-def calendar_spread():
- df = get_dfs()[0]
- df['cal 3m-1m'] = df['3m']-df['1m']
- df['cal 5m-3m'] = df['5m']-df['3m']
- df = df.sort_index()
- df = df.groupby(df.index.date).nth(-1)
- df[['cal 3m-1m','cal 5m-3m']].plot()
- #last 100,100-200,200-300 days
- avg = pd.DataFrame([df[-100:].mean(),df[-200:-100].mean(),df[-300:-200].mean()])
- return (df[-1:], avg)
-
-def put_spread(index = "IG"):
- dfs = get_dfs()
- df = pd.concat([dfs[0], dfs[1]], axis = 1, keys=['atm','otm'])
- steepness = df['otm'] - df['atm']
- steepness.plot()
- #last 100,100-200,200-300 days
- avg = pd.DataFrame([steepness[-100:].mean(),steepness[-200:-100].mean(),steepness[-300:-200].mean()])
- return (steepness[-1:], avg)
-
-def swaption_analysis():
- cal = calendar_spread()
- cal_otm = calendar_spread(moneyness = "otm_vol")
- vol_df = atm_vol('IG',27).groupby(level = 'quotedate').last().dropna()
-
-def beta_calc():
- am = arch_model(10000*index_price_returns(index='IG'))
- res = am.fit(update_freq=0, disp='off')
-
- amIG = arch_model(100*index_returns())
- resIG = amIG.fit(update_freq=0, disp='off')
- ltvar = lr_var(resIG)
-
- amHY = arch_model(1000*index_returns(index = 'HY'))
- resHY = amHY.fit(update_freq=0, disp='off')
- ltvar = lr_var(resHY)
- graphit = compute_allocation(all_tenors)
-
-def build_swaption(index, series, expiry, strike, ref, trade_date, t_range= None, spread_range = None):
- index_obj = Index.from_name(index, series, '5yr', trade_date)
- swap_obj = opt.Swaption(index_obj, expiry, strike, option_type="payer")
- swap_obj.notional = 100000000
-
- if t_range is None:
- t_range = pd.bdate_range(trade_date, expiry- BDay(), freq = '5B')
- if spread_range is None:
- spread_range = pd.Series(np.arange(ref - 10, ref +19, 5))
-
- vol_range = pd.Series(np.arange(25, 60, 5)) #not inclusive of end point
-
- df = pd.DataFrame(index = pd.MultiIndex.from_product([t_range, spread_range, vol_range], names = ['date', 'spread', 'vol']), columns = ['pv'])
- df = df.reset_index()
-
- def aux(row, index, swap):
- index.spread = row.spread
- manual_index_update(index, row.date.date())
- swap.sigma = row.vol/100
- swap._update()
- return swap.pv
-
- df['pv'] = df.apply(aux, axis=1, args=(index_obj, swap_obj))
-
- #calculate mapped vol
- df['moneyness'] = (strike- df.spread)/df.spread
- df['days_to_expiry'] = (expiry - df.date).dt.days
- vol_surface = build_vol_surface_functions(trade_date, index, series)
- df['mapped_vol'] = df.apply(vol_from_surface, axis = 1, args=(vol_surface[0], vol_surface[1]))
- df['mapping_shift'] = pd.to_numeric(df.vol/100 - df.mapped_vol, errors = 'ignore')
- df = df.set_index(['date', 'spread', 'vol'])
-
- return df
-
-def calc_delta_pnl(index, series, ref, trade_date, notional, t_range, spread_range):
-
- index_obj = Index.from_name(index, series, '5yr', trade_date)
- index_obj.spread = ref
- index_obj.notional = notional
- startingpv = -index_obj.clean_pv
-
- index_pv = {}
- for date in t_range:
- for spread in spread_range:
- index_obj.spread = spread
- manual_index_update(index_obj, date)
- #import pdb; pdb.set_trace()
- index_pv[(date, spread)] = -index_obj.clean_pv + notional* (date.date()-trade_date).days/360* index_obj.fixed_rate/10000
-
- df = pd.DataFrame.from_dict(index_pv, orient = 'index').reset_index()
- df['date'] = df['index'].apply(lambda x: x[0])
- df['spread'] = df['index'].apply(lambda x: x[1])
- del df['index']
- df = df.set_index(['date','spread']).sort_index()
- df = (df - startingpv).unstack(-1)
- df.columns = df.columns.droplevel()
-
- return df
-
-def find_mapped_pv(bought, sold, date):
-
- sold = sold.xs(date).reset_index()
- bought = bought.xs(date).reset_index()
-
- #Bivariate B-Spline, instead of interp2d. Interp2d doesn't behave well and complains a lot. annoying
- x = bought.spread.unique()
- y = sorted(bought.mapping_shift.unique())
- grid = np.meshgrid(x,y)
- f_buy = SmoothBivariateSpline(bought.spread, bought.mapping_shift, bought.pv, kx = 4, ky = 4)
- f_sold = SmoothBivariateSpline(sold.spread, sold.mapping_shift, sold.pv, kx = 4, ky = 4)
- intp_buy = f_buy.ev(grid[0],grid[1])
- intp_sold = f_sold.ev(grid[0],grid[1])
- df = pd.DataFrame(intp_buy, index = grid[1][0:,0], columns = grid[0][0])
- df1 = pd.DataFrame(intp_sold, index = grid[1][0:,0], columns = grid[0][0])
-
- #Use NDInterpolate - not copmplete
- #f_buy = LinearNDInterpolator((bought.spread, bought.mapping_shift), bought.pv)
- #f_sold = LinearNDInterpolator((sold.spread, sold.mapping_shift), sold.pv)
-
- #Use interp2d
- #x = bought.spread.unique()
- #y = sorted(bought.mapping_shift.unique())
- #f_buy = interp2d(bought.spread, bought.mapping_shift, bought.pv)
- #f_sold = interp2d(sold.spread, sold.mapping_shift, sold.pv)
- #intp_buy = f_buy(x,y)
- #intp_sold = f_sold(x,y)
- #df = pd.DataFrame(data = intp_buy, index = y, columns = x)
- #df1 = pd.DataFrame(data = intp_sold, index = y, columns = x)
-
- PNL = df - df1
-
- return PNL
-
-def result_fill(df, date):
-
- data = df.xs(date).reset_index()
- #make df.vol a variable to make this function more general
- f = interp2d(data.spread, data.vol, data.pv)
- x = np.arange(data.spread.min(), data.spread.max(), .5)
- y = np.arange(data.vol.min(), data.vol.max(), .5)
- intp_result = f(x,y)
- df1 = pd.DataFrame(data = intp_result, index = y, columns = x)
-
- return df1
-
-def plot_color_map(df, val_date):
-
- #rows are spread, columns are volatility surface shift
- fig, ax = plt.subplots()
-
- #Different ways to do a colormap: imshow and pcolormesh. using imshow here
- midpoint = 1 - df.max().max()/(df.max().max() + abs(df.min().min()))
- shifted_cmap = shiftedColorMap(cm.RdYlGn, midpoint=midpoint, name='shifted')
-
- chart = ax.imshow(df, extent=(df.columns.min(), df.columns.max(), df.index.min(), df.index.max()) \
- ,aspect= 'auto', interpolation='bilinear', cmap=shifted_cmap)
-
- ax.set_xlabel('Spread')
- ax.set_ylabel('Parallel Shift of Volatility Surface')
- ax.set_title('PV of Trade on ' + str(val_date.date()))
-
- fig.colorbar(chart, shrink = .8)
-
- fig.savefig("/home/serenitas/edwin/PythonGraphs/payer_swap_" + str(val_date.date()) + ".png")
-
-def build_vol_surface_functions(date = datetime.date(2017, 2, 23), index = 'IG', series = '27'):
- df1 = pd.read_sql_query('SELECT quotedate, expiry, series, strike, vol ' \
- 'FROM swaption_quotes ' \
- 'WHERE index = %s and series = %s and date(quotedate) = %s',
- serenitasdb,
- index_col=['quotedate', 'expiry', 'series'],
- params=(index.upper(), series, date), parse_dates=['quotedate', 'expiry'])
- index_data = pd.read_sql_query(
- 'SELECT quotedate, expiry, series, ref, fwdspread FROM swaption_ref_quotes ' \
- 'WHERE index= %s and date(quotedate) = %s',
- serenitasdb, index_col=['quotedate', 'expiry', 'series'],
- params=(index.upper(), date), parse_dates=['quotedate', 'expiry'])
-
- df1 = df1.join(index_data)
- df1 = df1.groupby(df1.index).filter(lambda x: len(x) >= 2)
- df1 = df1.reset_index()
- #once the dates are in the columns you need the use .dt to access dates functions
- df1['days_to_expiry'] = (df1.expiry - df1.quotedate.dt.normalize().dt.tz_localize(None)).dt.days
- df1['moneyness'] = (df1.strike - df1.ref)/df1.ref
- df1 = df1.groupby(['days_to_expiry','moneyness']).nth(-1).vol
- df1 = df1.reset_index()
- f = LinearNDInterpolator((df1.days_to_expiry, df1.moneyness), df1.vol)
- g = NearestNDInterpolator((df1.days_to_expiry, df1.moneyness), df1.vol)
- return (f,g)
-
-def vol_from_surface(row, f, g):
- vol = f(row.days_to_expiry, row.moneyness)
- if math.isnan(vol) is True:
- vol = g(row.days_to_expiry, row.moneyness)
- return vol
-
-def calc_and_plot(bought, sold, traded_price, week, lowerbound, upperbound, deltaPNL=None):
-
- if week > len(bought.index.get_level_values(0).unique()):
- week = len(bought.index.get_level_values(0).unique())-1
-
- date = bought.index.get_level_values(0).unique()[week]
-
- PNL = find_mapped_pv(bought, sold, date) - traded_price + deltaPNL.loc[date.date()]
-
- PNL = PNL[lowerbound:upperbound].sort_index(ascending = False)
-
- plot_color_map(PNL, date)
-
- return PNL
-
-def full_analysis():
- index = 'IG'
- series = 27,
- buy_expiry = datetime.date(2017, 4, 19)
- buy_strike = 65
- sell_expiry = datetime.date(2017, 5, 17)
- sell_strike = 72
- ref = 62
- trade_date = datetime.date(2017, 2, 23)
- delta_notional = 13000000
-
- t_range = pd.bdate_range(trade_date, buy_expiry- BDay(), freq = '5B')
- spread_range = pd.Series(np.arange(ref - 10, ref +19, 5))
-
- bought = build_swaption(index, series, buy_expiry, buy_strike, ref, trade_date, t_range, spread_range)
- sold = build_swaption(index, series, sell_expiry, sell_strike, ref, trade_date, t_range, spread_range)
-
- delta_PNL = calc_delta_pnl(index, series, ref, trade_date, delta_notional, t_range, spread_range)
-
- #Calc PNL and Plot:
- traded_price = 5000
- lowerbound = -.05 #parallel shift down 5% vol
- upperbound = .1 #parallel shift up 10% vol
- week = 1 #negative to count backwards
-
- PNL = calc_and_plot(bought, sold, traded_price, week, lowerbound, upperbound, delta_PNL)
-
- return (bought, sold, PNL, delta_PNL)
-
-
-
-
-
-
-
-
-
-def manual_index_update(index, date): #index as Index Object
- index._yc = index._yc.expected_forward_curve(date)
- index._trade_date = date
- index._step_in_date = index.trade_date + datetime.timedelta(days=1)
- index._accrued = index._fee_leg.accrued(index._step_in_date)
- index._value_date = (pd.Timestamp(index._trade_date) + 3* BDay()).date()
- index._update()
-
-
-import numpy as np
-import matplotlib
-import matplotlib.pyplot as plt
-from mpl_toolkits.axes_grid1 import AxesGrid
-
-def shiftedColorMap(cmap, start=0, midpoint=0.5, stop=1.0, name='shiftedcmap'):
- '''
- Function to offset the "center" of a colormap. Useful for
- data with a negative min and positive max and you want the
- middle of the colormap's dynamic range to be at zero
-
- Input
- -----
- cmap : The matplotlib colormap to be altered
- start : Offset from lowest point in the colormap's range.
- Defaults to 0.0 (no lower ofset). Should be between
- 0.0 and `midpoint`.
- midpoint : The new center of the colormap. Defaults to
- 0.5 (no shift). Should be between 0.0 and 1.0. In
- general, this should be 1 - vmax/(vmax + abs(vmin))
- For example if your data range from -15.0 to +5.0 and
- you want the center of the colormap at 0.0, `midpoint`
- should be set to 1 - 5/(5 + 15)) or 0.75
- stop : Offset from highets point in the colormap's range.
- Defaults to 1.0 (no upper ofset). Should be between
- `midpoint` and 1.0.
- '''
- cdict = {
- 'red': [],
- 'green': [],
- 'blue': [],
- 'alpha': []
- }
-
- # regular index to compute the colors
- reg_index = np.linspace(start, stop, 257)
-
- # shifted index to match the data
- shift_index = np.hstack([
- np.linspace(0.0, midpoint, 128, endpoint=False),
- np.linspace(midpoint, 1.0, 129, endpoint=True)
- ])
-
- for ri, si in zip(reg_index, shift_index):
- r, g, b, a = cmap(ri)
-
- cdict['red'].append((si, r, r))
- cdict['green'].append((si, g, g))
- cdict['blue'].append((si, b, b))
- cdict['alpha'].append((si, a, a))
-
- newcmap = matplotlib.colors.LinearSegmentedColormap(name, cdict)
- plt.register_cmap(cmap=newcmap)
-
- return newcmap
-
-
-