diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/exploration/curve_trades.py | 57 | ||||
| -rw-r--r-- | python/notebooks/Curve Trades.ipynb | 42 |
2 files changed, 82 insertions, 17 deletions
diff --git a/python/exploration/curve_trades.py b/python/exploration/curve_trades.py index fbdbf7ec..aee30dcd 100644 --- a/python/exploration/curve_trades.py +++ b/python/exploration/curve_trades.py @@ -2,12 +2,12 @@ from index_data import get_index_quotes, index_returns 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 import matplotlib.pyplot as plt -index = 'IG' -on_the_run = 28 - def curve_spread_diff(index = 'IG', on_the_run = 28): ## look at spreads df = get_index_quotes(index, list(range(on_the_run-6,on_the_run+1)), tenor=['3yr', '5yr', '7yr', '10yr']) @@ -38,29 +38,27 @@ def theta_matrix_by_series(index = 'IG', on_the_run = 28): theta_matrix_1 = theta_matrix.xs(theta_matrix.index.max()[0], level = 0).unstack(0) return theta_matrix_1[['3yr', '5yr', '7yr', '10yr']] -def theta_ratio_within_series(index = 'IG', on_the_run = 28): +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=['date', 'series']): - five_yr = g.xs('5yr', level = 'tenor')['duration'] - r[i] = g.duration/five_yr[0] + 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('ratio_to_5yr')) + 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 curve_3_5_10(theta_ratio_within_series): - df = theta_ratio_within_series +def curve_3_5_10(df): #buy 3y, sell 5y, buy 10y - df['3_5_10'] = - df.theta2['3yr'] / df.ratio_to_5yr['3yr'] \ + df['3_5_10'] = - df.theta2['3yr'] / df.duration_ratio_to_5yr['3yr'] \ + 2 * df.theta2['5yr'] \ - - df.theta2['10yr'] / df.ratio_to_5yr['10yr'] + - df.theta2['10yr'] / df.duration_ratio_to_5yr['10yr'] df['3_5_10'].dropna().unstack(-1).plot() -def curve_5_10(theta_ratio_within_series): - df = theta_ratio_within_series +def curve_5_10(df): #buy sell 5y, buy 10y - df['5_10'] = df.theta2['5yr'] - df.theta2['10yr'] / df.ratio_to_5yr['10yr'] + 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): @@ -136,4 +134,31 @@ def forward_loss(): # annual change, to take out some noise df['fwd_loss_rate'] = df.indexel.diff(2)/df.duration.diff(2) +def read_IG_curve_pos(): + from analytics import Index, Portfolio + trade_1 = Index.from_tradeid(886) + trade_2 = Index.from_tradeid(885) + trade_3 = Index.from_tradeid(884) + portf = Portfolio([trade_1, trade_2, trade_3]) + +def curve_model(): + + #OLS model + df = ratio_within_series(param = 'closespread', groupby_level = ['date', 'series']) + 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']) + results = smf.ols('np.log(ratio) ~ np.log(duration) + np.log(closespread)', data=df).fit() + df['predicted'] = np.exp(results.predict()) + results.summary() + prstd_ols, iv_l, iv_u = wls_prediction_std(results) + 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) + 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 + diff --git a/python/notebooks/Curve Trades.ipynb b/python/notebooks/Curve Trades.ipynb index 5d1a1bec..6042ccc6 100644 --- a/python/notebooks/Curve Trades.ipynb +++ b/python/notebooks/Curve Trades.ipynb @@ -94,7 +94,7 @@ "outputs": [], "source": [ "#Theta with 3-5-10 Strategy\n", - "theta_ratio_within_series = ct.theta_ratio_within_series()\n", + "theta_ratio_within_series = ct.ratio_within_series(param = 'duration')\n", "ct.curve_3_5_10(theta_ratio_within_series)" ] }, @@ -113,6 +113,46 @@ "execution_count": null, "metadata": {}, "outputs": [], + "source": [ + "#Relative Spread Difference\n", + "spread_ratio = ct.ratio_within_series(param = 'closespread')\n", + "spread_ratio.groupby(level = ['date']).last()['closespread_ratio_to_5yr'].plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model = ct.curve_model()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ax = model[['ratio','predicted']].plot()\n", + "ax.plot(model.index, model.up_2_stdev, 'r--')\n", + "ax.plot(model.index, model.down_2_stdev, 'b--')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model.iloc[-1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [] } ], |
