aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/exploration/beta_trade.py101
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,))