diff options
| -rw-r--r-- | python/exploration/beta_trade.py | 21 | ||||
| -rw-r--r-- | python/exploration/curve_trades.py | 38 |
2 files changed, 34 insertions, 25 deletions
diff --git a/python/exploration/beta_trade.py b/python/exploration/beta_trade.py index 4b895c94..8563f11b 100644 --- a/python/exploration/beta_trade.py +++ b/python/exploration/beta_trade.py @@ -11,23 +11,24 @@ from statsmodels.tsa.ar_model import AR import matplotlib.pyplot as plt -def calc_returns(): - returns = index_returns(index=['IG', 'HY'], tenor='5yr') +def calc_returns(save_feather=False): + returns = (index_returns(index=['IG', 'HY'], tenor='5yr', years=None). + reset_index('tenor', drop=True)) returns_hy = (returns. xs('HY', level=1). dropna(). - reset_index(level='series'). - groupby(level=['date']). + groupby(level=['date'], as_index=False). nth(-1)) - returns_hy = returns_hy.set_index('series', append=True) - returns_ig = returns.xs('IG', level=1).reset_index('tenor', drop=True) + returns_ig = returns.xs('IG', level=1) # hy starts trading later than ig, so we line it up based on hy series df = pd.merge(returns_hy, returns_ig, left_index=True, right_index=True, - suffixes=('_hy','_ig')) + suffixes=('_hy','_ig')) returns = df[['price_return_hy', 'price_return_ig']] returns.columns = ['hy', 'ig'] - #feather.write_dataframe(returns.reset_index(), - # os.path.join(os.environ["DATA_DIR"], "index_returns.fth")) + returns = returns.dropna()['2009-03-20':] + if save_feather: + feather.write_dataframe(returns.reset_index(), + os.path.join(os.environ["DATA_DIR"], "index_returns.fth")) return returns.reset_index('series', drop=True) def calc_betas(returns=None, spans=[5, 20]): @@ -81,7 +82,7 @@ def spreads_ratio(series=list(range(22, 29)), index=['IG', 'HY'], tenor='5yr'): def loglik(beta, returns): x = (returns.hy - beta*returns.ig) model = AR(x, missing='drop') - fit = model.fit(maxlag=1) + fit = model.fit(maxlag=2) return - fit.llf if __name__ == "__main__": diff --git a/python/exploration/curve_trades.py b/python/exploration/curve_trades.py index 353f5bbc..7a7d29c2 100644 --- a/python/exploration/curve_trades.py +++ b/python/exploration/curve_trades.py @@ -51,8 +51,9 @@ def ratio_within_series(index='IG', rolling=6, param='duration'): ratio = (df[param]. apply(lambda s: s / df[param]['5yr'].values, raw=True)) ratio.columns = pd.MultiIndex.from_product([[param + '_ratio_to_5yr'], ratio.columns]) - df = df.join(ratio) - return df.groupby(['date', 'index']).nth(-1) + df = df.join(ratio).groupby(['date']).tail(1) + df = df.reset_index(level=['index', 'version'], drop=True) + return df def curve_3_5_10(df): """ @@ -86,12 +87,12 @@ def curve_returns(index='IG', rolling=6): ## on-the-run returns returns = df.price_return.unstack(-1).dropna().groupby(level='date').nth(-1) - strategy = ['35','510', '710', '3510'] strategies_return = pd.DataFrame( - {'3-5': -.64 * returns['3yr'] + returns['5yr'], - '5-10': 1.78 * returns['5yr'] - returns['10yr'], + {'5-10': 1.78 * returns['5yr'] - returns['10yr'], '7-10': 1.33 * returns['7yr'] - returns['10yr'], - '3-5-10': -2 * returns['3yr'] + 3 * returns['5yr'] - returns['10yr']}) + '3-5-10': -2 * returns['3yr'] + 3 * returns['5yr'] - returns['10yr'], + '3-5': returns['5yr'] - 1.56 * returns['3yr'], + '3-7': returns['7yr'] - 2.07 * returns['3yr']}) strategies_return_monthly = (strategies_return. groupby(pd.TimeGrouper(freq='M')). agg(lambda df: (1 + df).prod() - 1)) @@ -152,21 +153,28 @@ def read_IG_curve_pos(): def curve_model(tenor_1='5yr', tenor_2='10yr'): #OLS model df = ratio_within_series(param='closespread') - df = df.groupby(level='date').last() - df = pd.concat([df.duration[tenor_1], df.closespread[tenor_1], - df.closespread_ratio_to_5yr[tenor_2]], axis=1, - keys=['duration', 'closespread', 'ratio']) - ols_model = smf.ols('np.log(ratio) ~ np.log(duration) + np.log(closespread)', data=df).fit() - df['predicted'] = np.exp(results.predict()) + df = pd.concat([df.duration[tenor_1], df.duration[tenor_2], + df.closespread[tenor_1], + df.closespread_ratio_to_5yr[tenor_2], + df.theta[tenor_1], df.theta[tenor_2]], + axis=1, + keys=['duration1', 'duration2', 'closespread', + 'ratio', 'theta1', 'theta2']) + df = np.log(df) + ols_model = smf.ols('ratio ~ closespread + duration1 + theta1 + theta2', + data=df).fit() return df, ols_model def curve_model_results(df, model): prstd_ols, df['down_2_stdev'], df['up_2_stdev'] = wls_prediction_std(model) #dr/dspread = exp(k) + spread_coeff * duration ^ dur_coeff * spread ^ (spread_coeff-1) - df['down_2_stdev'] = np.exp(df['down_2_stdev']) - df['up_2_stdev'] = np.exp(df['up_2_stdev']) + cols = ['ratio', 'closespread', 'down_2_stdev', 'up_2_stdev'] + df[cols] = np.exp(df[cols]) df['predicted'] = np.exp(model.predict()) - df['dr_dspread'] = np.exp(model.params[0]) * model.params[2] * df.duration ** model.params[1] * df.closespread ** (model.params[2] - 1) + df[['predicted', 'down_2_stdev', 'up_2_stdev']]=\ + df[['predicted', 'down_2_stdev', 'up_2_stdev']].multiply(df['closespread'].values, axis=0) + ax = df[['predicted', 'down_2_stdev', 'up_2_stdev']].reset_index(level='series', drop=True).plot() + df['dr_dspread'] = np.exp(model.params[0]) * model.params[2] * df.duration1 ** model.params[1] * df.closespread ** (model.params[2] - 1) return df def curve_var(): |
