diff options
Diffstat (limited to 'python/exploration/option_trades.py')
| -rw-r--r-- | python/exploration/option_trades.py | 91 |
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) |
