diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/analytics/scenarios.py | 4 | ||||
| -rw-r--r-- | python/exploration/swaption_calendar_spread.py | 99 |
2 files changed, 96 insertions, 7 deletions
diff --git a/python/analytics/scenarios.py b/python/analytics/scenarios.py index ed534144..84505101 100644 --- a/python/analytics/scenarios.py +++ b/python/analytics/scenarios.py @@ -1,4 +1,5 @@ from analytics import ATMstrike +from joblib import delayed, Parallel import pandas as pd def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock, vol_surface, @@ -31,7 +32,8 @@ def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock, vol_su swaption.sigma = vol return prepend + [getattr(swaption, p) for p in params] r.append(Parallel(-1)( - delayed(aux(swaption, curr_vol * (1 + vs), params, prepend)) for vs in vol_shock) + delayed(aux(swaption, curr_vol * (1 + vs), params, [date, spread, vs])) \ + for vs in vol_shock)) swaption.index.spread = spread_start df = pd.DataFrame.from_records(r, columns=['date', 'spread_shock', diff --git a/python/exploration/swaption_calendar_spread.py b/python/exploration/swaption_calendar_spread.py index 1da708ec..5a798e5b 100644 --- a/python/exploration/swaption_calendar_spread.py +++ b/python/exploration/swaption_calendar_spread.py @@ -12,6 +12,62 @@ from matplotlib import cm from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt +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 + def plot_df(df, spread_shock, vol_shock): fig = plt.figure() ax = fig.gca(projection='3d') @@ -21,9 +77,35 @@ def plot_df(df, spread_shock, vol_shock): 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 shock") + ax.set_ylabel("spread") ax.set_zlabel("PV") +def plot_color_map(df): + + val_date = df.index[0] + df = df.set_index(['spread_shock','vol_shock'])['pv'].unstack(-2) + df = df.sort_index(ascending = False) + + #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('Volatility shock') + 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") + + + trade_date = datetime.date(2017, 2, 23) ig27 = Index.from_name("IG", 27, '5yr', trade_date=trade_date) ig27.ref = 62 @@ -37,12 +119,17 @@ spread_shock = np.arange(-0.2, 0.3, 0.01) vs = VolatilitySurface("IG", 27, trade_date=trade_date) vol_surface = vs[vs.list()[-1]] -df1 = run_swaption_scenarios(payer1, date_range, spread_shock, vol_shock, vol_surface, - params=['pv_black', 'delta']) -df2 = run_swaption_scenarios(payer2, date_range, spread_shock, vol_shock, vol_surface, - params=['pv_black', 'delta']) +df1 = run_swaption_scenarios(payer1, date_range, spread_shock, vol_shock, vol_surface) + #params=['pv_black', 'delta']) +df2 = run_swaption_scenarios(payer2, date_range, spread_shock, vol_shock, vol_surface) + #plot it +week = -1 df = df1 df = df.assign(pv=df1.pv_black-df2.pv_black) -plot_df(df.loc[date_range[-1]], np.arange(-0.2, 0.3, 0.001), +spread_plot_range = np.arange((1-0.2)*ig27.ref, (1+0.3)*ig27.ref, 0.001*ig27.ref) +plot_df(df.loc[date_range[week]], spread_plot_range, np.arange(-0.15, 0.3, 0.001)) +plot_color_map(df.loc[date_range[week]]) + + |
