diff options
Diffstat (limited to 'python/analytics/curve_trades.py')
| -rw-r--r-- | python/analytics/curve_trades.py | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/python/analytics/curve_trades.py b/python/analytics/curve_trades.py index b989bd69..555194ba 100644 --- a/python/analytics/curve_trades.py +++ b/python/analytics/curve_trades.py @@ -8,6 +8,7 @@ from statsmodels.sandbox.regression.predstd import wls_prediction_std from scipy.interpolate import interp1d from itertools import chain from copy import deepcopy +from matplotlib import cm import pandas as pd import math @@ -30,7 +31,7 @@ def curve_spread_diff(index='IG', rolling=6, years=3, percentage=False, percenta # look at spreads df = get_index_quotes(index, list(range(otr - rolling, otr + 1)), tenor=['3yr', '5yr', '7yr', '10yr'], years=years) - spreads = df.groupby(level=['date', 'tenor']).nth(-1)['closespread'].unstack(-1) + spreads = df.groupby(level=['date', 'tenor']).nth(-1)['close_spread'].unstack(-1) spreads_diff = spreads.diff(axis=1) del spreads_diff['3yr'] spreads_diff.columns = ['3-5', '5-7', '7-10'] @@ -55,7 +56,8 @@ 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 + #now get_index_quotes are all based on theta2/duration2 + df['theta_per_dur'] = df.theta / df.duration theta_matrix = df.groupby(level=['date', 'tenor','series']).nth(-1)['theta_per_dur'] theta_matrix = theta_matrix.loc[theta_matrix.index[-1][0]].unstack(0) return theta_matrix[['3yr', '5yr', '7yr', '10yr']] @@ -78,7 +80,7 @@ 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 + df['theta_per_dur'] = df.theta/df.duration theta_matrix = df.groupby(level=['date', 'tenor']).nth(-1)['theta_per_dur'] theta_matrix.unstack(-1).plot() @@ -145,8 +147,8 @@ def cross_series_curve(index='IG', rolling=6): 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, close_spread, "\ + "close_spread*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]) @@ -162,16 +164,16 @@ def forward_loss(index='IG'): def curve_model(tenor_1='5yr', tenor_2='10yr'): #OLS model - df = ratio_within_series(param='closespread') + df = ratio_within_series(param='close_spread') df = pd.concat([df.duration[tenor_1], df.duration[tenor_2], - df.closespread[tenor_1], - df.closespread_ratio_to_5yr[tenor_2], + df.close_spread[tenor_1], + df.close_spread_ratio_to_5yr[tenor_2], df.theta[tenor_1], df.theta[tenor_2]], axis=1, - keys=['duration1', 'duration2', 'closespread', + keys=['duration1', 'duration2', 'close_spread', 'ratio', 'theta1', 'theta2']) df = np.log(df) - ols_model = smf.ols('ratio ~ closespread + duration1 + theta1 + theta2', + ols_model = smf.ols('ratio ~ close_spread + duration1 + theta1 + theta2', data=df).fit() return df, ols_model @@ -184,13 +186,13 @@ def curve_model_results(df, model): df = df.join(b) df = df.join(c) #dr/dspread = exp(k) + spread_coeff * duration ^ dur_coeff * spread ^ (spread_coeff-1) - cols = ['ratio', 'closespread', 'down_2_stdev', 'up_2_stdev'] + cols = ['ratio', 'close_spread', 'down_2_stdev', 'up_2_stdev'] df[cols] = np.exp(df[cols]) df['predicted'] = np.exp(model.predict()) df[['predicted', 'down_2_stdev', 'up_2_stdev']]=\ - df[['predicted', 'down_2_stdev', 'up_2_stdev']].multiply(df['closespread'].values, axis=0) + df[['predicted', 'down_2_stdev', 'up_2_stdev']].multiply(df['close_spread'].values, axis=0) ax = df[['predicted', 'down_2_stdev', 'up_2_stdev']].reset_index(level='series', drop=True).plot() - df['dr_dspread'] = np.exp(model.params[0]) * model.params[2] * df.duration1 ** model.params[1] * df.closespread ** (model.params[2] - 1) + df['dr_dspread'] = np.exp(model.params[0]) * model.params[2] * df.duration1 ** model.params[1] * df.close_spread ** (model.params[2] - 1) return df @@ -199,7 +201,7 @@ def spread_fin_crisis(index='IG'): # look at spreads df = get_index_quotes(index, list(range(8, otr + 1)), tenor=['3yr', '5yr', '7yr', '10yr'], years=20) - spreads = df.groupby(level=['date', 'tenor']).nth(-1)['closespread'].unstack(-1) + spreads = df.groupby(level=['date', 'tenor']).nth(-1)['close_spread'].unstack(-1) spreads_diff = spreads.diff(axis=1) to_plot = pd.DataFrame() to_plot['spread'] = spreads['5yr'] @@ -314,6 +316,28 @@ def curve_shape(value_date, index='IG', percentile=.95, spread=None): return interp1d(np.hstack([0, df.year_frac]), np.hstack([0, df.spread])) +def plot_curve_shape(date): + + ''' + Plots the curve shape that's being used for the scenarios''' + + curve_per = np.arange(.01, .99, .1) + time_per = np.arange(.1, 10.1, .5) + r=[] + for per in curve_per: + shape = curve_shape(date, percentile = per) + r.append(shape(time_per)) + df = pd.DataFrame(r, index=curve_per, columns=time_per) + fig = plt.figure() + ax = fig.gca(projection='3d') + xx, yy = np.meshgrid(curve_per, time_per) + z = np.vstack(r).transpose() + surf = ax.plot_surface(xx, yy, z, cmap=cm.viridis) + ax.set_xlabel("steepness percentile") + ax.set_ylabel("tenor") + ax.set_zlabel("spread") + + def pos_pnl_abs(portf, value_date, index='IG', rolling=6, years=3): ''' @@ -323,7 +347,7 @@ def pos_pnl_abs(portf, value_date, index='IG', rolling=6, years=3): series = on_the_run(index) df = get_index_quotes(index, list(range(series - rolling, series + 1)), tenor=['3yr', '5yr', '7yr', '10yr'], years=years) - df = df.groupby(level=['date', 'tenor']).nth(-1)['closespread'].unstack(-1) + df = df.groupby(level=['date', 'tenor']).nth(-1)['close_spread'].unstack(-1) sql_string = "SELECT tenor, maturity FROM index_maturity where index = %s and series = %s" lookup_table = pd.read_sql_query(sql_string, serenitasdb, parse_dates=['maturity'], |
