aboutsummaryrefslogtreecommitdiffstats
path: root/python/exploration
diff options
context:
space:
mode:
Diffstat (limited to 'python/exploration')
-rw-r--r--python/exploration/curve_trades.py157
1 files changed, 82 insertions, 75 deletions
diff --git a/python/exploration/curve_trades.py b/python/exploration/curve_trades.py
index aee30dcd..89149306 100644
--- a/python/exploration/curve_trades.py
+++ b/python/exploration/curve_trades.py
@@ -1,16 +1,23 @@
-from index_data import get_index_quotes, index_returns
+from index_data import get_index_quotes, index_returns, _serenitas_engine
import pandas as pd
import math
-from scipy.stats.mstats import zscore
-import datetime
import statsmodels.formula.api as smf
-from statsmodels.sandbox.regression.predstd import wls_prediction_std
import numpy as np
+from statsmodels.sandbox.regression.predstd import wls_prediction_std
+
import matplotlib.pyplot as plt
-def curve_spread_diff(index = 'IG', on_the_run = 28):
+def on_the_run(index):
+ r = _serenitas_engine.execute("SELECT max(series) FROM index_version WHERE index=%s",
+ (index,))
+ series, = r.fetchone()
+ return series
+
+def curve_spread_diff(index='IG', rolling=6):
+ otr = on_the_run(index)
## look at spreads
- df = get_index_quotes(index, list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
+ df = get_index_quotes(index, list(range(otr - rolling, otr + 1)),
+ tenor=['3yr', '5yr', '7yr', '10yr'])
spreads = df.groupby(level=['date', 'tenor']).nth(-1)['closespread'].unstack(-1)
# remove 'yr'
spreads.columns = [int(col[:-2]) for col in spreads.columns]
@@ -22,34 +29,38 @@ def curve_spread_diff(index = 'IG', on_the_run = 28):
return spreads_diff
def spreads_diff_table(spreads_diff):
- df = pd.DataFrame()
- df['min'] = spreads_diff.min()
- df['max'] = spreads_diff.max()
- df['average'] = spreads_diff.mean()
- df['current'] = spreads_diff.iloc[-1]
- df['zscore'] = pd.Series(zscore(spreads_diff)[-1], index = df.index)
- pd.DataFrame(zscore(spreads_diff), index=spreads_diff.index, columns=spreads_diff.columns).plot()
+ def current(s):
+ return s.iat[-1]
+ def zscore(s):
+ return (s.iat[-1] - s.mean()) / s.std()
+ df = spreads_diff.agg(['min', 'max','mean', current, zscore])
+ ((spreads_diff - spreads_diff.mean())/spreads_diff.std()).plot()
return df
-def theta_matrix_by_series(index = 'IG', on_the_run = 28):
- df = get_index_quotes(index, list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
- df['theta_per_dur'] = df.theta2/df.duration2
+def theta_matrix_by_series(index='IG', rolling=6):
+ otr = on_the_run(index)
+ df = get_index_quotes(index, list(range(otr - rolling, otr + 1)),
+ tenor=['3yr', '5yr', '7yr', '10yr'])
+ df['theta_per_dur'] = df.theta2 / df.duration2
theta_matrix = df.groupby(level=['date', 'tenor','series']).nth(-1)['theta_per_dur']
- theta_matrix_1 = theta_matrix.xs(theta_matrix.index.max()[0], level = 0).unstack(0)
- return theta_matrix_1[['3yr', '5yr', '7yr', '10yr']]
+ theta_matrix = theta_matrix.loc[theta_matrix.index[-1][0]].unstack(0)
+ return theta_matrix[['3yr', '5yr', '7yr', '10yr']]
-def ratio_within_series(index = 'IG', on_the_run = 28, param = 'duration', groupby_level = ['date', 'series']):
- df = get_index_quotes(index, list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
- r = {}
- for i,g in df.groupby(level=groupby_level):
- five_yr = g.xs('5yr', level = 'tenor')[param]
- r[i] = g[param]/five_yr[-1]
- df1 = pd.concat(r)
- dftemp= pd.DataFrame(df1.groupby(level=['date', 'tenor','series']).nth(-1).rename(param+'_ratio_to_5yr'))
- df2 = df.groupby(level=['date', 'tenor','series']).nth(-1).merge(dftemp, left_index=True, right_index=True)
- return df2.unstack(-2)
+def ratio_within_series(index='IG', rolling=6, param='duration'):
+ otr = on_the_run(index)
+ df = get_index_quotes(index, list(range(otr - rolling, otr + 1)),
+ tenor=['3yr', '5yr', '7yr', '10yr']).unstack()
+ 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)
def curve_3_5_10(df):
+ """
+ Parameters
+ ----------
+ df: duration ratio within series"""
#buy 3y, sell 5y, buy 10y
df['3_5_10'] = - df.theta2['3yr'] / df.duration_ratio_to_5yr['3yr'] \
+ 2 * df.theta2['5yr'] \
@@ -61,72 +72,70 @@ def curve_5_10(df):
df['5_10'] = df.theta2['5yr'] - df.theta2['10yr'] / df.duration_ratio_to_5yr['10yr']
df['5_10'].dropna().unstack(-1).plot()
-def on_the_run_theta(index = 'IG', on_the_run = 28):
- df = get_index_quotes(index, list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
+def on_the_run_theta(index='IG', rolling=6):
+ otr = on_the_run(index)
+ df = get_index_quotes(index, list(range(otr - rolling, otr + 1)),
+ tenor=['3yr', '5yr', '7yr', '10yr'])
df['theta_per_dur'] = df.theta2/df.duration2
theta_matrix = df.groupby(level=['date', 'tenor']).nth(-1)['theta_per_dur']
theta_matrix.unstack(-1).plot()
-def curve_returns(index = 'IG', on_the_run = 28):
+def curve_returns(index='IG', rolling=6):
## look at returns
- df = index_returns(index= index, series=list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
+ otr = on_the_run(index)
+ df = index_returns(index= index, series=list(range(otr - rolling, otr + 1)),
+ tenor=['3yr', '5yr', '7yr', '10yr'])
## on-the-run returns
returns = df.price_return.unstack(-1).dropna().groupby(level='date').nth(-1)
strategy = ['510', '710', '3510']
+ strategies_return = pd.DataFrame(
+ {'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']})
+ strategies_return_monthly = (strategies_return.
+ groupby(pd.TimeGrouper(freq='M')).
+ agg(lambda df: (1 + df).prod() - 1))
- strategies_return = pd.DataFrame()
- strategies_return[strategy[0]] = 1.78 * returns['5yr'] - returns['10yr']
- strategies_return[strategy[1]] = 1.33 * returns['7yr'] - returns['10yr']
- strategies_return[strategy[2]] = -2 * returns['3yr']+ 3 * returns['5yr'] - 1 * returns['10yr']
-
- strategies_return_monthly = pd.DataFrame()
- for strat in strategy:
- strategies_return_monthly[strat] = strategies_return[strat].groupby(pd.TimeGrouper(freq='M')).agg(lambda df:(1+df).prod()-1)
-
- results = pd.DataFrame()
- sharpe = {}
- monthly_sharpe = {}
- for strat in strategy:
- sharpe[strat] = strategies_return[strat].mean()/strategies_return[strat].std()*math.sqrt(252)
- monthly_sharpe[strat] = strategies_return_monthly[strat].mean()/strategies_return_monthly[strat].std()*math.sqrt(12)
+ def sharpe(df, period="daily"):
+ if period == "daily":
+ return df.mean() / df.std() * math.sqrt(252)
+ else:
+ return df.mean() / df.std() * math.sqrt(12)
- worst_drawdown = {}
- for strat in strategy:
- worst_drawdown[strat] = strategies_return[strat].nsmallest(10).mean()
+ results = strategies_return.agg([sharpe, lambda df: df.nsmallest(10).mean()])
+ sharpe_monthly = strategies_return_monthly.agg(sharpe, period="monthly")
+ sharpe_monthly.name = 'Monthly Sharpe'
+ results.index=['Sharpe', 'Mean Worst 10 Days DrawDown']
+ return results.append(sharpe_monthly)
- results = results.append(sharpe, ignore_index=True)
- results = results.append(monthly_sharpe, ignore_index=True)
- results = results.append(worst_drawdown, ignore_index=True)
- results['results'] = ['Sharpe','Monthly Sharpe','Mean Worst 10 Days Drawdown']
-
- return results.set_index('results')
-
-def cross_series_curve(index = 'IG', on_the_run = 28):
-
- df = index_returns(index= index, series=list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr'])
+def cross_series_curve(index='IG', rolling=6):
+ otr = on_the_run(index)
+ df = index_returns(index= index, series=list(range(otr - rolling, otr + 1)),
+ tenor=['3yr', '5yr', '7yr', '10yr'])
## look cross series - 3y to 5y
returns1 = df.xs(['5yr', index], level = ['tenor','index']).price_return.unstack(-1)
price_diff = pd.DataFrame()
- for ind in list(range(on_the_run-2, on_the_run+1)):
- price_diff[ind] = returns1[ind] - 1.6* returns1[ind - 4]
+ for ind in list(range(otr - 2, otr + 1)):
+ price_diff[ind] = returns1[ind] - 1.6 * returns1[ind - 4]
price_diff = price_diff.stack().groupby(level = 'date').nth(-1)
- monthly_returns_cross_series = price_diff.groupby(pd.TimeGrouper(freq='M')).agg(lambda df:(1+df).prod()-1)
+ monthly_returns_cross_series = (price_diff.
+ groupby(pd.TimeGrouper(freq='M')).
+ agg(lambda df: (1 + df).prod() - 1))
plt.plot(monthly_returns_cross_series)
-def forward_loss():
- from db import dbengine, dbconn
- serenitasdb = dbengine('serenitasdb')
- index = 'IG'
+def forward_loss(index='IG'):
start_date = (pd.Timestamp.now() - pd.DateOffset(years=3)).date()
- df = pd.read_sql_query("SELECT date, index, series, tenor, duration, closespread, closespread*duration/100 as indexel " \
+ df = pd.read_sql_query("SELECT date, index, series, tenor, duration, closespread, "\
+ "closespread*duration / 100 AS indexel " \
"FROM index_quotes WHERE index=%s AND date >= %s " \
"ORDER BY date DESC, series ASC, duration ASC",
serenitasdb, parse_dates=['date'], params=[index, start_date])
- df1 = pd.read_sql_query("select index, series, tenor, maturity from index_maturity", serenitasdb, parse_dates=['maturity'])
+ df1 = pd.read_sql_query("SELECT index, series, tenor, maturity FROM index_maturity",
+ serenitasdb, parse_dates=['maturity'])
df = df.merge(df1, on=['index','series','tenor'])
df = df.set_index(['date','index', 'maturity']).dropna()
@@ -142,12 +151,12 @@ def read_IG_curve_pos():
portf = Portfolio([trade_1, trade_2, trade_3])
def curve_model():
-
#OLS model
- df = ratio_within_series(param = 'closespread', groupby_level = ['date', 'series'])
+ df = ratio_within_series(param='closespread')
df = df.groupby(level='date').last()
- df = pd.concat([df.duration['5yr'],df.closespread['5yr'], df.closespread_ratio_to_5yr['10yr']], axis = 1, keys=['duration', 'closespread', 'ratio'])
+ df = pd.concat([df.duration['5yr'], df.closespread['5yr'], df.closespread_ratio_to_5yr['10yr']],
+ axis=1, keys=['duration', 'closespread', 'ratio'])
results = smf.ols('np.log(ratio) ~ np.log(duration) + np.log(closespread)', data=df).fit()
df['predicted'] = np.exp(results.predict())
results.summary()
@@ -155,10 +164,8 @@ def curve_model():
df['up_2_stdev'] = np.exp(iv_u)
df['down_2_stdev'] = np.exp(iv_l)
- #dr/dspread = exp(k) + spread_coeff * duration ^ dur_coeff * spread ^ (spread_coeff-1)
+ #dr/dspread = exp(k) * spread_coeff * duration ^ dur_coeff * spread ^ (spread_coeff-1)
df['dr_dspread'] = np.exp(results.params[0]) * results.params[2] * df.duration ** results.params[1] * df.closespread ** (results.params[2] -1)
df['beta'] = df.dr_dspread * df.closespread
return df
-
-