diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/exploration/beta_trade.py | 101 |
1 files changed, 45 insertions, 56 deletions
diff --git a/python/exploration/beta_trade.py b/python/exploration/beta_trade.py index bc53c33d..335e6b98 100644 --- a/python/exploration/beta_trade.py +++ b/python/exploration/beta_trade.py @@ -7,18 +7,18 @@ from arch import arch_model from math import log, exp, sqrt import numpy as np from scipy.optimize import minimize_scalar -from scipy.optimize import minimize +from statsmodels.tsa.ar_model import AR import matplotlib.pyplot as plt def calc_returns(): returns = index_returns(index=['IG', 'HY'], tenor='5yr') returns_hy = (returns. - xs('HY', level=1). - dropna(). - reset_index(level='series'). - groupby(level=['date']). - nth(-1)) + xs('HY', level=1). + dropna(). + reset_index(level='series'). + groupby(level=['date']). + nth(-1)) returns_hy = returns_hy.set_index('series', append=True) returns_ig = returns.xs('IG', level=1).reset_index('tenor', drop=True) # hy starts trading later than ig, so we line it up based on hy series @@ -30,61 +30,53 @@ def calc_returns(): # os.path.join(os.environ["DATA_DIR"], "index_returns.fth")) return returns.reset_index('series', drop=True) -def calc_betas(): - returns = calc_returns() - beta_ewma = (returns. - ewm(span=20). - cov(). - groupby(level='date'). - apply(lambda df: df.values[0,1]/df.values[1,1])) - - beta_ewma5 = (returns. - ewm(span=5). - cov(). - groupby(level='date'). - apply(lambda df: df.values[0,1]/df.values[1,1])) +def calc_betas(returns=None, spans=[5, 20]): + if returns is None: + returns = calc_returns() + return [(returns. + ewm(span=span). + cov(). + groupby(level='date'). + apply(lambda df: df.values[0,1]/df.values[1,1])) for span in spans] - return (beta_ewma, beta_ewma5) - -def plot_betas(): - betas = calc_betas() - plt.plot(betas[0], label = 'EWMA20') - plt.plot(betas[1], label = 'EWMA5') +def plot_betas(betas=None): + spans = [5, 20] + if betas is None: + betas = calc_betas(spans) + for beta, span in zip(betas, spans): + plt.plot(beta, label = 'EWMA'+str(span)) plt.xlabel('date') plt.ylabel('beta') plt.legend() -def calc_realized_vol(): +def calc_realized_vol(returns=None): # three ways of computing the volatility # 1) 20 days simple moving average # 2) exponentially weighted moving average # 3) GARCH(1,1), we scale returns by 10 to help with the fitting - returns = calc_returns() - vol_sma = pd.DataFrame() - vol_ewma = pd.DataFrame() + if returns is None: + returns = calc_returns() + + vol_sma = returns.rolling(20).std() * math.sqrt(252) + vol_ewma = returns.ewm(span=20).std() * math.sqrt(252) + scale = 10 + vol_garch = pd.DataFrame() for index in returns: - vol_sma[index] = returns[index].rolling(20).std() * math.sqrt(252) - vol_ewma[index] = returns[index].ewm(span=20).std() * math.sqrt(252) - scale = 10 - am = arch_model(scale * returns.hy.dropna()) + am = arch_model(scale * returns[index].dropna()) res = am.fit() - vol_garch = res.conditional_volatility * math.sqrt(252)/scale - vol = pd.concat([vol_sma, vol_ewma, vol_garch], axis=1, keys=['sma', 'ewma', 'garch']) - - ## 2 standard deviation - vol.quantile(.95) + vol_garch[index] = res.conditional_volatility * math.sqrt(252)/scale + vol = pd.concat([vol_sma, vol_ewma, vol_garch], axis=1, keys=['sma', 'ewma', 'garch']) + return vol #feather.write_dataframe(beta_ewma.to_frame('beta'), - # os.path.join(os.environ['DATA_DIR'], "beta.fth")) + # os.path.join(os.environ['DATA_DIR'], "beta.fth")) -def spreads_ratio(): - df = get_index_quotes(series = list(range(22,29))) - df1 = pd.DataFrame() - for index in ['IG', 'HY']: - df1[index] = df.modelspread.xs((index, '5yr'), level=[1,4]).groupby('date').last() - df1['ratio'] = df1.HY/df1.IG - return df1 +def spreads_ratio(series=list(range(22, 29)), index=['IG', 'HY'], tenor='5yr'): + df = get_index_quotes(series=series, index=index, tenor=tenor) + df = df['modelspread'].groupby(['date', 'index']).last().unstack() + df['ratio'] = df.HY / df.IG + return df def loglik(beta, returns): x = (returns.hy - beta*returns.ig) @@ -92,13 +84,10 @@ def loglik(beta, returns): fit = model.fit(maxlag=1) return - fit.llf -# r = [] -# for beta in np.arange(3, 5, 0.01): -# prog = minimize(loglik, np.array([0.1, 0.1, 0.1]), args=(returns, beta), -# bounds=[(None, None), (1e-6, None), (None, None)], -# method='L-BFGS-B') -# r.append(prog.fun) - -# r = [] -# for beta in np.arange(3, 5, 0.01): -# r.append(test(returns, beta)) +if __name__ == "__main__": + returns = calc_returns() + betas = calc_betas(returns) + plot_betas(betas) + vol = calc_realized_vol(returns) + ratios = spreads_ratio() + prog = minimize_scalar(loglik, bracket=(3, 5), args=(returns,)) |
