aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics/curve_trades.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics/curve_trades.py')
-rw-r--r--python/analytics/curve_trades.py54
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'],