aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/analytics/scenarios.py5
-rw-r--r--python/exploration/swaption_calendar_spread.py111
2 files changed, 79 insertions, 37 deletions
diff --git a/python/analytics/scenarios.py b/python/analytics/scenarios.py
index 0c132076..ab0cdde3 100644
--- a/python/analytics/scenarios.py
+++ b/python/analytics/scenarios.py
@@ -9,7 +9,7 @@ from functools import partial
from multiprocessing import Pool
def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock,
- vol_surface, params=["pv"]):
+ vol_surface, params=["pv"], vol_time_roll=True):
"""computes the pv of a swaption for a range of scenarios
Parameters
@@ -24,11 +24,12 @@ def run_swaption_scenarios(swaption, date_range, spread_shock, vol_shock,
"""
swaption = deepcopy(swaption)
spreads = swaption.ref * (1 + spread_shock)
+ T = swaption.T
r = []
for date in date_range:
swaption.index.trade_date = date.date()
- T = swaption.T
+ if vol_time_roll: T = swaption.T
for s in spreads:
swaption.ref = s
curr_vol = max(0, float(vol_surface(T, swaption.moneyness)))
diff --git a/python/exploration/swaption_calendar_spread.py b/python/exploration/swaption_calendar_spread.py
index f399a931..8eaaad0a 100644
--- a/python/exploration/swaption_calendar_spread.py
+++ b/python/exploration/swaption_calendar_spread.py
@@ -89,8 +89,11 @@ def plot_color_map(df, spread_shock, vol_shock, attr="pv", path="."):
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_shock','vol_shock'], ascending = [True,False], inplace = True)
series = df[attr]
- #Different ways to do a colormap: imshow and pcolormesh. using imshow here
+
+ #import pdb; pdb.set_trace()
midpoint = 1 - series.max() / (series.max() + abs(series.min()))
shifted_cmap = shiftedColorMap(cm.RdYlGn, midpoint=midpoint, name='shifted')
@@ -104,22 +107,20 @@ def plot_color_map(df, spread_shock, vol_shock, attr="pv", path="."):
ax.set_title('{} of Trade on {}'.format(attr.title(), val_date))
fig.colorbar(chart, shrink=.8)
- #fig.savefig(os.path.join(path, "payer_swap_", attr, "_{}.png".format(val_date)))
+ fig.savefig(os.path.join(path, "payer_swap_", attr, "_{}.png".format(val_date)))
-def plot_time_color_map(df, spread_shock, attr="pv", path="."):
+def plot_time_color_map(df, spread_shock, attr="pv", path=".", color_map = cm.RdYlGn):
val_date = df.index[0].date()
- dftemp = df.reset_index()
- dftemp['days'] = (dftemp['date'] - val_date).dt.days
- date_range = dftemp.days.unique()
+ df = df.reset_index()
+ df['days'] = (df['date'] - val_date).dt.days
+ df.sort_values(by=['date','spread_shock'], ascending = [True,False], inplace = True)
+ date_range = df.days.unique()
- #rows are spread, columns are volatility surface shift
fig, ax = plt.subplots()
series = df[attr]
- #Different ways to do a colormap: imshow and pcolormesh. using imshow here
midpoint = 1 - series.max() / (series.max() + abs(series.min()))
- #import pdb; pdb.set_trace()
- shifted_cmap = shiftedColorMap(cm.RdYlGn, midpoint=midpoint, name='shifted')
+ shifted_cmap = shiftedColorMap(color_map, midpoint=midpoint, name='shifted')
chart = ax.imshow(series.values.reshape(date_range.size, spread_shock.size).T,
extent=(date_range.min(), date_range.max(),
@@ -137,17 +138,22 @@ def april_may_2017_trade():
option_delta = Index.from_tradeid(870)
ref = option_delta.spread
payer1 = BlackSwaption(option_delta, datetime.date(2017, 4, 19), 65)
- payer2 = BlackSwaption(option_delta, datetime.date(2017, 5, 17), 72)
+ payer2 = BlackSwaption(option_delta, datetime.date(2017, 5, 17), 72.5)
+ payer1.sigma = .348
+ payer2.sigma = .466
payer1.notional = 100_000_000
payer2.notional = 100_000_000
+
+ cost = 5000
+
date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-04-19') - BDay(), freq = '5B')
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_surface = vs[vs.list()[-1]]
# #
- df1 = run_swaption_scenarios(payer1, date_range, spread_shock, vol_shock, vol_surface)
- df2 = run_swaption_scenarios(payer2, date_range, spread_shock, vol_shock, vol_surface)
+ df1 = run_swaption_scenarios(payer1, date_range, spread_shock, vol_shock, vol_surface, ['pv','delta'])
+ df2 = run_swaption_scenarios(payer2, date_range, spread_shock, vol_shock, vol_surface, ['pv','delta'])
df3 = run_index_scenarios(option_delta, date_range, spread_shock)
# #plot it
@@ -156,55 +162,90 @@ def april_may_2017_trade():
df3 = df3.reset_index()
df = df.merge(df3, on=['date','spread_shock'])
df = df.set_index('date')
- df = df.assign(pv=df1.pv-df2.pv+df.pnl)
+ df = df.assign(pv=df1.pv-df2.pv+df.pnl-cost)
+ df = df.assign(delta=df1.delta*payer1.notional-df2.delta*payer2.notional+option_delta.notional)
spread_plot_range = ref * (1 + np.arange(-0.2, 0.3, 0.001))
vol_shock_range = np.arange(-0.15, 0.3, 0.001)
plot_df(df.loc[date_range[week]], spread_plot_range, vol_shock_range)
plot_color_map(df.loc[date_range[week]], ref * (1 + spread_shock), vol_shock)
+ plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'delta')
+ plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'pv')
+
-#def june_july_2017_trade():
option_delta = Index.from_name('ig', 28, '5yr')
-option_delta.spread = 67
-payer1 = BlackSwaption(option_delta, datetime.date(2017, 7, 19), 80)
-payer2 = BlackSwaption(option_delta, datetime.date(2017, 5, 17), 80)
-payer1.sigma = .438
-payer2.sigma = .479
-payer1.notional = 100_000_000
-payer2.notional = 100_000_000
+option_delta.spread = 68
+
+payer1 = BlackSwaption(option_delta, datetime.date(2017, 6, 21), 65)
+payer2 = BlackSwaption(option_delta, datetime.date(2017, 5, 17), 75)
+payer3 = BlackSwaption(option_delta, datetime.date(2017, 7, 19), 75)
+payer1.sigma = .388
+payer2.sigma = .503
+payer3.sigma = .43
+payer1.notional = 150_000_000
+payer2.notional = -100_000_000
+payer3.notional = 100_000_000 *0
+vol_time_roll = False
+no_delta = False
ref = option_delta.spread
-option_delta.notional = payer1.notional * payer1.delta - payer2.notional * payer2.delta
+
+if payer2.notional == 0:
+ option_delta.notional = payer1.notional * payer1.delta
+elif payer3.notional == 0:
+ option_delta.notional = payer1.notional * payer1.delta + payer2.notional * payer2.delta
+else:
+ option_delta.notional = payer1.notional * payer1.delta + payer2.notional * payer2.delta + payer3.notional * payer3.delta
+
+#option_delta.notional = -100_000_000
if option_delta.notional > 0: option_delta.direction = 'Seller'
+
+if no_delta: option_delta.notional = 0.01
option_delta._original_clean_pv = option_delta._clean_pv
option_delta._original_trade_date = option_delta.trade_date
-cost = payer1.pv - payer2.pv
+cost = payer1.pv + payer2.pv + payer3.pv
-date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-05-17') - BDay(), freq = '3B')
+date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-05-16') - BDay(), freq = '3B')
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 = max([t for t in vs.list() if t[1] == 'BAML' and t[2] == 'payer' and t[3] == 'black'])
vol_surface = vs[vol_select]
# #
-df1 = run_swaption_scenarios(payer1, date_range, spread_shock, vol_shock, vol_surface, ['pv','delta'])
-df2 = run_swaption_scenarios(payer2, date_range, spread_shock, vol_shock, vol_surface, ['pv','delta'])
-df3 = run_index_scenarios(option_delta, date_range, spread_shock)
+
+df1 = run_swaption_scenarios(payer1, date_range, spread_shock, vol_shock, vol_surface, ['pv','delta'], vol_time_roll)
+if payer2.notional != 0: df2 = run_swaption_scenarios(payer2, date_range, spread_shock, vol_shock, vol_surface, ['pv','delta'], vol_time_roll)
+if payer3.notional != 0: df3 = run_swaption_scenarios(payer3, date_range, spread_shock, vol_shock, vol_surface, ['pv','delta'], vol_time_roll)
+
+dfdelta = run_index_scenarios(option_delta, date_range, spread_shock)
# #plot it
-week = -2
+week = -4
df = df1.reset_index()
-df3 = df3.reset_index()
-df = df.merge(df3, on=['date','spread_shock'])
+dfdelta = dfdelta.reset_index()
+df = df.merge(dfdelta, on=['date','spread_shock'])
df = df.set_index('date')
-df = df.assign(pv=df1.pv-df2.pv+df.pnl-cost)
-df = df.assign(delta=df1.delta*payer1.notional-df2.delta*payer2.notional+option_delta.notional)
+
+if payer2.notional == 0:
+ df = df.assign(pv=df1.pv+df.pnl-cost)
+ df = df.assign(delta=df1.delta*payer1.notional+option_delta.notional)
+elif payer3.notional == 0:
+ df = df.assign(pv=df1.pv+df2.pv+df.pnl-cost)
+ df = df.assign(delta=df1.delta*payer1.notional+df2.delta*payer2.notional+option_delta.notional)
+else:
+ df = df.assign(pv=df1.pv+df2.pv+df3.pv+df.pnl-cost)
+ df = df.assign(delta=df1.delta*payer1.notional+df2.delta*payer2.notional+df3.delta*payer3.notional+option_delta.notional)
spread_plot_range = ref * (1 + np.arange(-0.2, 0.3, 0.001))
vol_shock_range = np.arange(-0.15, 0.3, 0.001)
#plot_df(df.loc[date_range[week]], spread_plot_range, vol_shock_range)
-plot_color_map(df.loc[date_range[week]], ref * (1 + spread_shock), vol_shock)
-plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'delta')
+#plot_color_map(df.loc[date_range[week]], ref * (1 + spread_shock), vol_shock)
plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'pv')
+plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'delta', color_map = cm.coolwarm)
+
+#down 10% vol
+#plot_time_color_map(df[round(df.vol_shock,2)==-.1], ref * (1 + spread_shock), 'pv')
+#plot_time_color_map(df[round(df.vol_shock,2)==-.1], ref * (1 + spread_shock), 'delta')
+