import sys sys.path.append("..") import math import os import pandas as pd try: import feather except ImportError: pass from analytics.index_data import index_returns, get_index_quotes from arch import arch_model from math import log, exp, sqrt import numpy as np from scipy.optimize import minimize_scalar from statsmodels.tsa.ar_model import AR import matplotlib.pyplot as plt def calc_returns(index_list=['HY', 'IG'], save_feather=False): returns = (index_returns(index=index_list, tenor='5yr', years=None). reset_index(['tenor'], drop=True). swaplevel(1, 0)) returns = returns.groupby(level=['date','index']).nth(-1)['price_return'] returns = returns.unstack().dropna() #if save_feather: # feather.write_dataframe(returns.reset_index(), # os.path.join(os.environ["DATA_DIR"], "index_returns.fth")) return returns def calc_betas(returns=None, spans=[5, 20], index_list=['HY', 'IG']): if returns is None: returns = calc_returns(index_list=index_list) return pd.concat([(returns. ewm(span=span). cov(). groupby(level='date'). apply(lambda df: df / np.diag(df))) for span in spans], axis=1, keys=spans) def plot_betas(betas=None): spans = [5, 20] if betas is None: betas = calc_betas(spans=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(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 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: am = arch_model(scale * returns[index].dropna()) res = am.fit() 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")) 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) model = AR(x, missing='drop') fit = model.fit(maxlag=2) return - fit.llf 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,))