diff options
Diffstat (limited to 'python/exploration/swaption_calendar_spread.py')
| -rw-r--r-- | python/exploration/swaption_calendar_spread.py | 165 |
1 files changed, 27 insertions, 138 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)) |
