aboutsummaryrefslogtreecommitdiffstats
path: root/python/exploration/option_trades.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/exploration/option_trades.py')
-rw-r--r--python/exploration/option_trades.py91
1 files changed, 57 insertions, 34 deletions
diff --git a/python/exploration/option_trades.py b/python/exploration/option_trades.py
index 611fdc83..f9685fbb 100644
--- a/python/exploration/option_trades.py
+++ b/python/exploration/option_trades.py
@@ -8,11 +8,12 @@ from pandas.tseries.offsets import BDay
from arch import arch_model
from db import dbengine, dbconn
from scipy.interpolate import interp1d
-from analytics import Index
+from analytics import Index, ForwardIndex
from index_data import index_returns
+
serenitasdb = dbengine('serenitasdb')
-def realized_vol(index, series, tenor='5yr', date=None, years=None):
+def realized_vol(index, series, tenor='5yr', date=None, years=None, return_type='spread'):
"""computes the realized spread volatility"""
if date is None:
if years is None:
@@ -20,7 +21,7 @@ def realized_vol(index, series, tenor='5yr', date=None, years=None):
date = (pd.Timestamp.now() - pd.DateOffset(years=years)).date()
returns = index_returns(index=index, series=series, tenor=tenor, years=None)
# GARCH(1,1) volatility process with constant mean
- am = arch_model(returns)
+ am = arch_model(returns[return_type+'_return'])
res = am.fit(update_freq=0, disp='off')
return (res.conditional_volatility * math.sqrt(252), res)
@@ -37,45 +38,67 @@ def lr_var(res):
var = res.params[names[0]]/(1 - res.params[names[1:]])
return math.sqrt(var * 252)
-def atm_vol_fun(v, ref_is_price=False, moneyness=0.2):
+def atm_vol_fun(v, moneyness=0.2, index=None):
f = interp1d(v.strike.values, v.vol.values, fill_value='extrapolate')
- atm_val = v['fwdspread'].iat[0]
- otm_val = atm_val * (1 + moneyness) ## doesn't make sense for HY
+ if index is None:
+ atm_val = v['fwdspread'].iat[0]
+ otm_val = atm_val * (1 + moneyness)
+ else:
+ if 'HY' in index.name:
+ index.price = v['ref'].iat[0]
+ atm_val = ForwardIndex(index, v.index.get_level_values('expiry')[0], ref_is_price=True).forward_spread
+ otm_val = atm_val * (1 + moneyness)
+ index.spread = atm_val
+ atm_val = index.price
+ index.spread = otm_val
+ otm_val = index.price
+ else:
+ index.spread = v['ref'].iat[0]
+ atm_val = ForwardIndex(index, v.index.get_level_values('expiry')[0], ref_is_price=False).forward_spread
+ otm_val = atm_val * (1 + moneyness)
return pd.Series(f(np.array([atm_val, otm_val])), index = ['atm_vol', 'otm_vol'])
-def atm_vol(index, series, moneyness=0.2):
- df = pd.read_sql_query('SELECT quotedate, expiry, strike, vol from swaption_quotes ' \
- 'WHERE index = %s and series = %s',
- serenitasdb, index_col=['quotedate', 'expiry'],
- params = (index.upper(), series))
- index_data = pd.read_sql_query(
- 'SELECT quotedate, expiry, fwdspread from swaption_ref_quotes ' \
- 'WHERE index= %s and series = %s',
- serenitasdb, index_col = ['quotedate', 'expiry'],
- params = (index.upper(), series))
-
- df = df.join(index_data)
- df = df.groupby(level=['quotedate', 'expiry']).filter(lambda x: len(x)>=2)
- df = df.groupby(level=['quotedate', 'expiry']).apply(atm_vol_fun, index=="HY", moneyness)
- df = df.reset_index(level=-1) #move expiry back to the column
- return df
-
-def atm_vol_date(index, date):
- df = pd.read_sql_query('SELECT quotedate, series, expiry, strike, vol ' \
+def atm_vol(index, date, series = None, moneyness=0.2):
+ if series is None:
+ df = pd.read_sql_query('SELECT quotedate, series, expiry, strike, vol ' \
'FROM swaption_quotes ' \
'WHERE index = %s and quotedate >= %s',
serenitasdb,
index_col=['quotedate', 'expiry', 'series'],
params=(index.upper(), date), parse_dates=['quotedate'])
- index_data = pd.read_sql_query(
- 'SELECT quotedate, expiry, series, fwdspread FROM swaption_ref_quotes ' \
- 'WHERE index= %s and quotedate >= %s',
- serenitasdb, index_col=['quotedate', 'expiry', 'series'],
- params = (index.upper(), date), parse_dates=['quotedate'])
+ index_data = pd.read_sql_query(
+ 'SELECT quotedate, expiry, series, ref, fwdspread FROM swaption_ref_quotes ' \
+ 'WHERE index= %s and quotedate >= %s',
+ serenitasdb, index_col=['quotedate', 'expiry', 'series'],
+ params=(index.upper(), date), parse_dates=['quotedate'])
+ else:
+ df = pd.read_sql_query('SELECT quotedate, series, expiry, strike, vol from swaption_quotes ' \
+ 'WHERE index = %s and series = %s and quotedate >= %s',
+ serenitasdb, index_col=['quotedate', 'expiry', 'series'],
+ params = (index.upper(), series, date))
+ index_data = pd.read_sql_query(
+ 'SELECT quotedate, series, expiry, ref, fwdspread from swaption_ref_quotes ' \
+ 'WHERE index= %s and series = %s and quotedate >= %s',
+ serenitasdb, index_col = ['quotedate', 'expiry', 'series'],
+ params = (index.upper(), series, date))
+
df = df.join(index_data)
- df = df.groupby(df.index).filter(lambda x: len(x)>=2)
- df = df.groupby(level=['quotedate', 'expiry', 'series']).apply(atm_vol_fun)
- df = df.reset_index(level=['expiry', 'series']) #move expiry and series back to the columns
+ df = df.groupby(df.index).filter(lambda x: len(x) >= 2)
+
+ df1 = atm_vol_calc(df, index)
+ return df1
+
+def atm_vol_calc(df, index):
+ g_temp = {}
+ for s, g1 in df.groupby(level='series'):
+ index_obj = Index.from_name(index, s, '5yr')
+ for date, g2 in g1.groupby(g1.index.get_level_values(0)):
+ index_obj.trade_date = date.date()
+ for expiry, g3 in g2.groupby(g2.index.get_level_values(1)):
+ g_temp[(date, expiry, s)] = atm_vol_fun(g3, index=index_obj)
+ df = pd.concat(g_temp, names=['quotedate', 'expiry', 'series'])
+ df = df.unstack(-1)
+ df = df.reset_index(level=['expiry', 'series'])
return df
def rolling_vol(df, col='atm_vol', term=[3]):
@@ -93,7 +116,7 @@ def rolling_vol(df, col='atm_vol', term=[3]):
return df.dropna()
def vol_var(percentile=0.99, index='IG'):
- df = atm_vol_date("IG", datetime.date(2014, 6, 11))
+ df = atm_vol(index, datetime.date(2014, 6, 11))
df = rolling_vol(df, term=[1,2,3])
df = df.sort_index()
df = df.groupby(df.index.date).nth(-1)