diff options
| -rw-r--r-- | python/exploration/tranches.py | 15 | ||||
| -rw-r--r-- | python/graphics.py | 33 |
2 files changed, 42 insertions, 6 deletions
diff --git a/python/exploration/tranches.py b/python/exploration/tranches.py index 7b475821..430e8492 100644 --- a/python/exploration/tranches.py +++ b/python/exploration/tranches.py @@ -7,7 +7,7 @@ import analytics.basket_index as idx_bkt import numpy as np import pandas as pd -from analytics import Swaption, BlackSwaption, Index, BlackSwaptionVolSurface, Portfolio +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 @@ -99,14 +99,19 @@ def dispersion(): 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(portf.indices[0].trade_date, - earliest_expiry - pd.offsets.BDay(), freq='5B') - vs = BlackSwaptionVolSurface(portf.indices[0].index_type, - portf.indices[0].series, trade_date=portf.indices[0].trade_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 diff --git a/python/graphics.py b/python/graphics.py index f9935b5d..cc538aa8 100644 --- a/python/graphics.py +++ b/python/graphics.py @@ -3,6 +3,10 @@ import matplotlib.pyplot as plt from matplotlib import cm from matplotlib.colors import LinearSegmentedColormap +from scipy.interpolate import griddata +from scipy.stats import norm +from scipy.optimize import curve_fit + def shiftedColorMap(cmap, start=0, midpoint=0.5, stop=1.0, name='shiftedcmap'): ''' Function to offset the "center" of a colormap. Useful for @@ -54,7 +58,6 @@ def shiftedColorMap(cmap, start=0, midpoint=0.5, stop=1.0, name='shiftedcmap'): return newcmap - def plot_time_color_map(df, spread_shock, attr="pnl", path=".", color_map=cm.RdYlGn, index='IG', centered = True): val_date = df.index[0].date() @@ -111,3 +114,31 @@ def plot_color_map(df, spread_shock, vol_shock, attr="pnl", path=".", index='IG' fig.colorbar(chart, shrink=.8) #fig.savefig(os.path.join(path, "vol_spread_color_map"+ attr+ "_{}.png".format(val_date))) + +def plot_prob_map(df, 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 + series = df[attr] + + days_defined = np.linspace(df.days.min(), df.days.max(), 1000) + prob_defined = np.linspace(0.001, .999, 1000) + + midpoint = 1 - series.max() / (series.max() + abs(series.min())) + shifted_cmap = shiftedColorMap(color_map, midpoint=midpoint, name='shifted') + + resampled = griddata((df.days, df.prob), series, (days_defined[None, :], + prob_defined[:, None]), method='linear') + + #plot + fig, ax = plt.subplots() + chart = ax.imshow(resampled.reshape(days_defined.size, prob_defined.size), + extent=(df.days.min(), df.days.max(), 0, 1), + aspect='auto', interpolation='bilinear', cmap=shifted_cmap) + + ax.set_xlabel('Days') + ax.set_ylabel('Probability') + ax.set_title('{} of Trade'.format(attr.title())) + + fig.colorbar(chart, shrink=.8)
\ No newline at end of file |
