aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/analytics/scenarios.py7
-rw-r--r--python/exploration/swaption_calendar_spread.py270
2 files changed, 178 insertions, 99 deletions
diff --git a/python/analytics/scenarios.py b/python/analytics/scenarios.py
index 334a27a1..1cc4fb7f 100644
--- a/python/analytics/scenarios.py
+++ b/python/analytics/scenarios.py
@@ -63,7 +63,7 @@ def MaybePool(nproc):
yield Pool(nproc) if nproc > 0 else None
def run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock,
- vol_surface, params=["pnl"], nproc=-1):
+ vol_surface, params=["pnl"], nproc=-1, vol_time_roll=True):
"""computes the pnl of a portfolio for a range of scenarios
Parameters
@@ -80,13 +80,14 @@ def run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock,
"""
portf = deepcopy(portf)
spreads = np.hstack([index.spread * (1 + spread_shock) for index in portf.indices])
-
+ t = [swaption.T for swaption in portf.swaptions]
r = []
with MaybePool(nproc) as pool:
pmap = pool.map if pool else map
for date in date_range:
portf.trade_date = date.date()
- t = [swaption.T for swaption in portf.swaptions]
+ if vol_time_roll:
+ t = [swaption.T for swaption in portf.swaptions]
for s in spreads:
portf.ref = s
mon = [swaption.moneyness for swaption in portf.swaptions]
diff --git a/python/exploration/swaption_calendar_spread.py b/python/exploration/swaption_calendar_spread.py
index 8eaaad0a..cc548874 100644
--- a/python/exploration/swaption_calendar_spread.py
+++ b/python/exploration/swaption_calendar_spread.py
@@ -1,8 +1,8 @@
import sys
#don't do this at home
sys.path.append("..")
-from analytics import Swaption, BlackSwaption, Index, VolatilitySurface
-from analytics.scenarios import run_swaption_scenarios, run_index_scenarios
+from analytics import Swaption, BlackSwaption, Index, VolatilitySurface, Portfolio
+from analytics.scenarios import run_swaption_scenarios, run_index_scenarios, run_portfolio_scenarios
from pandas.tseries.offsets import BDay
import datetime
import numpy as np
@@ -18,6 +18,10 @@ import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import AxesGrid
+import re
+from db import dbengine
+engine = dbengine('serenitasdb')
+
def shiftedColorMap(cmap, start=0, midpoint=0.5, stop=1.0, name='shiftedcmap'):
'''
Function to offset the "center" of a colormap. Useful for
@@ -69,7 +73,7 @@ def shiftedColorMap(cmap, start=0, midpoint=0.5, stop=1.0, name='shiftedcmap'):
return newcmap
-def plot_df(df, spread_shock, vol_shock, attr="pv"):
+def plot_df(df, spread_shock, vol_shock, attr="pnl"):
val_date = df.index[0].date()
fig = plt.figure()
@@ -84,7 +88,7 @@ def plot_df(df, spread_shock, vol_shock, attr="pv"):
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="pv", path="."):
+def plot_color_map(df, spread_shock, vol_shock, attr="pnl", path="."):
val_date = df.index[0].date()
#rows are spread, columns are volatility surface shift
@@ -107,9 +111,9 @@ 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, "vol_spread_color_map"+ attr+ "_{}.png".format(val_date)))
-def plot_time_color_map(df, spread_shock, attr="pv", path=".", color_map = cm.RdYlGn):
+def plot_time_color_map(df, spread_shock, attr="pnl", path=".", color_map = cm.RdYlGn):
val_date = df.index[0].date()
df = df.reset_index()
@@ -132,120 +136,194 @@ def plot_time_color_map(df, spread_shock, attr="pv", path=".", color_map = cm.Rd
ax.set_title('{} of Trade'.format(attr.title()))
fig.colorbar(chart, shrink=.8)
- #fig.savefig(os.path.join(path, "payer_swap_", attr, "_{}.png".format(val_date)))
+ #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 = max([t for t in vs.list() if t[1] == 'BAML' and t[2] == 'payer' and t[3] == 'black'])
+ 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():
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.5)
- payer1.sigma = .348
- payer2.sigma = .466
- payer1.notional = 100_000_000
- payer2.notional = 100_000_000
+ option1 = BlackSwaption.from_tradeid(5, option_delta)
+ option2 = BlackSwaption.from_tradeid(6, option_delta)
- cost = 5000
+ 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 = max([t for t in vs.list() if t[1] == 'BAML' and t[2] == 'payer' and t[3] == 'black'])
+ 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():
+ option_delta = Index.from_tradeid(870)
+ option1 = BlackSwaption.from_tradeid(5, option_delta)
+ option2 = BlackSwaption.from_tradeid(6, option_delta)
- date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-04-19') - BDay(), freq = '5B')
+ 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_surface = vs[vs.list()[-1]]
- # #
- 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)
+ 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]
+
+ 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')
- # #plot it
- week = -1
- df = df1.reset_index()
- 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-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 may_june_2017_trade():
+ option_delta = Index.from_tradeid(874)
+ option1 = BlackSwaption.from_tradeid(7, option_delta)
+ option2 = BlackSwaption.from_tradeid(8, option_delta)
+ portf = Portfolio([option1, option2, option_delta])
+ 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 = max([t for t in vs.list() if t[1] == 'BAML' and t[2] == 'payer' and t[3] == 'black'])
+ 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)
-option_delta = Index.from_name('ig', 28, '5yr')
-option_delta.spread = 68
+ #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)
-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
+def portfolio_scenario_2():
-ref = option_delta.spread
+ #Manually Load trades
+ option_delta = Index.from_name('ig', 28, '5yr')
+ option_delta.spread = 67
+ option1 = BlackSwaption(option_delta, datetime.date(2017, 6, 21), 65, option_type="receiver")
+ option2 = BlackSwaption(option_delta, datetime.date(2017, 5, 17), 65, option_type="receiver")
+ option1.sigma = .39
+ option2.sigma = .424
+ option1.notional = 100_000_000
+ option2.notional = -100_000_000
+ 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)
+ #setting original pvs for pnl calc
+ option1._original_pv = option1.pv
+ option2._original_pv = option2.pv
+ option_delta._original_clean_pv = option_delta._clean_pv
+ option_delta._original_trade_date = option_delta._trade_date
-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
+ portf = Portfolio([option1, option2, option_delta])
+ 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 = max([t for t in vs.list() if t[1] == 'BAML' and t[2] == 'payer' and t[3] == 'black'])
+ vol_surface = vs[vol_select]
-#option_delta.notional = -100_000_000
-if option_delta.notional > 0: option_delta.direction = 'Seller'
+ df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface, params=["pnl", "delta"], vol_time_roll=False)
-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 + payer3.pv
+ #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')
+ #Delta in protection terms: Blue = going short, red = going long
+ plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'delta', color_map = cm.coolwarm_r)
-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]
-# #
+def portfolio():
+ option_delta = Index.from_tradeid(874)
+ option1 = BlackSwaption.from_tradeid(7, option_delta)
+ option2 = BlackSwaption.from_tradeid(8, option_delta)
-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)
+ 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 = max([t for t in vs.list() if t[1] == 'BAML' and t[2] == 'payer' and t[3] == 'black'])
+ 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 portfolio_today():
+ option_deltas = {}
+ options = {}
+ for trade_id in [870,872,873]:
+ option_deltas[trade_id] = Index.from_tradeid(trade_id)
+ option_deltas[trade_id].trade_date = datetime.date.today()
+ index_type = re.search('CDX (\w+) ', option_deltas[trade_id].name).group(1)
+ series = re.search('\d+', option_deltas[trade_id].name).group(0)
+ spread = pd.read_sql_query(
+ "SELECT closespread FROM index_quotes " \
+ "WHERE date <= %s and index= %s and series = %s and tenor = '5yr'" \
+ "ORDER BY date DESC limit 1",
+ engine,
+ params=(option_deltas[trade_id].trade_date, index_type, series))
+ option_deltas[trade_id].spread = spread.iloc[0][0]
+ option_deltas[trade_id].set_original_pv()
+
+ for trade_id in [6]:
+ options[trade_id] = BlackSwaption.from_tradeid(trade_id, option_deltas[870])
+ #options[trade_id].trade_date = datetime.date.today()
+ options[trade_id].sigma = .5
+ options[trade_id].set_original_pv()
+ #index_type = re.search('CDX (\w+) ', options[trade_id].index.name).group(1)
+ #series = re.search('\d+', options[trade_id].index.name).group(0)
+ #import pdb; pdb.set_trace()
+
+ portf = Portfolio([*option_deltas, *options])
+ 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 = max([t for t in vs.list() if t[1] == 'BAML' and t[2] == 'payer' and t[3] == 'black'])
+ vol_surface = vs[vol_select]
-dfdelta = run_index_scenarios(option_delta, date_range, spread_shock)
+ df = run_portfolio_scenarios(portf, date_range, spread_shock, vol_shock, vol_surface, params=["pnl", "delta"], vol_time_roll=False)
-# #plot it
-week = -4
-df = df1.reset_index()
-dfdelta = dfdelta.reset_index()
-df = df.merge(dfdelta, on=['date','spread_shock'])
-df = df.set_index('date')
+ #plot it
+ plot_time_color_map(df[round(df.vol_shock,2)==0], option_delta.spread * (1 + spread_shock), 'pnl')
-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)
+def probabilities():
+ from scipy.stats import lognorm
-spread_plot_range = ref * (1 + np.arange(-0.2, 0.3, 0.001))
-vol_shock_range = np.arange(-0.15, 0.3, 0.001)
+ 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_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), 'pv')
-plot_time_color_map(df[round(df.vol_shock,2)==0], ref * (1 + spread_shock), 'delta', color_map = cm.coolwarm)
+ date_range = pd.bdate_range(option_delta.trade_date, pd.Timestamp('2017-05-17') - BDay(), freq = 'B')
-#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')
+ curr_vols = np.maximum(vol_surface.ev(t, mon), 0)
+ dist = lognorm(curr_vols, scale)
+ lognorm.ppf(.5, curr_vols, scale = np.exp(64))