aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/thetas-durations.py68
1 files changed, 60 insertions, 8 deletions
diff --git a/python/thetas-durations.py b/python/thetas-durations.py
index 75f889ff..286a77b5 100644
--- a/python/thetas-durations.py
+++ b/python/thetas-durations.py
@@ -1,6 +1,13 @@
+import datetime
+import numpy as np
import pandas as pd
-from analytics import Index
+from analytics.utils import tenor_t
+from pandas.tseries.offsets import BDay
+from yieldcurve import get_curve
from db import dbengine
+from pyisda.legs import FeeLeg, ContingentLeg
+from pyisda.curve import SpreadCurve
+from pyisda.date import previous_twentieth
serenitas_engine = dbengine('serenitasdb')
tenors = {"IG": ("3yr", "5yr", "7yr", "10yr"),
@@ -10,12 +17,51 @@ tenors = {"IG": ("3yr", "5yr", "7yr", "10yr"),
sql_str = "INSERT INTO index_risk VALUES(%s, %s, %s)"
+def get_legs(index, series, tenors):
+ fee_legs = {}
+ contingent_legs = {}
+ coupons = []
+ end_dates = []
+ df = pd.read_sql_query("SELECT tenor, maturity, coupon, issue_date "
+ "FROM index_maturity "
+ "WHERE index=%s AND series=%s and tenor IN %s "
+ "ORDER BY maturity",
+ serenitas_engine,
+ params=(index, series, tenors),
+ parse_dates=['maturity', 'issue_date'])
+ df.coupon *= 1e-4
+ for tenor, maturity, coupon, issue_date in df.itertuples(index=False):
+ fee_legs[tenor] = FeeLeg(issue_date, maturity, True, 1., coupon * 1e-4)
+ contingent_legs[tenor] = ContingentLeg(issue_date, maturity, True)
+ coupons.append(coupon * 1e-4)
+ # number of seconds since epoch
+ df.maturity = df.maturity.view(int) // int(86400 * 1e9)
+ # number of days between 1900-1-1 and epoch
+ df.maturity += 134774
+ return fee_legs, contingent_legs, df
+
+def credit_curve(value_date, quotes, end_dates, coupons, recoveries, yc):
+ step_in_date = value_date + datetime.timedelta(days=1)
+ cash_settle_date = pd.Timestamp(value_date) + 3 * BDay()
+ start_date = previous_twentieth(value_date)
+ sc = SpreadCurve(value_date, yc, start_date,
+ step_in_date, cash_settle_date,
+ end_dates, coupons, quotes,
+ recoveries)
+ return sc
+
conn = serenitas_engine.raw_connection()
for index in ["IG", "HY", "EU", "XO"]:
+ if index in ["HY", "XO"]:
+ recoveries = np.full(len(tenors[index]), 0.3)
+ else:
+ recoveries = np.full(len(tenors[index]), 0.4)
for series in range(18, 31):
if index in ["EU", "XO"] and series == 30:
continue
- indices = {t: Index.from_name(index, series, t) for t in tenors[index]}
+ fee_legs, contingent_legs, df = \
+ get_legs(index, series, tenors[index])
+
index_quotes = pd.read_sql_query(
"SELECT id, date, tenor, close_price FROM index_quotes_pre "
"LEFT JOIN index_risk USING (id) "
@@ -27,13 +73,19 @@ for index in ["IG", "HY", "EU", "XO"]:
index_col='id')
if index_quotes.empty:
continue
+ index_quotes.tenor = index_quotes.tenor.astype(tenor_t)
+ index_quotes = index_quotes.sort_values('tenor')
+ index_quotes['close_price'] = 1. - index_quotes['close_price'] / 100
with conn.cursor() as c:
for k, v in index_quotes.groupby('date'):
- for id, tenor, close_price in v[['tenor', 'close_price']].itertuples():
- indices[tenor].value_date = k
- indices[tenor].price = close_price
- duration = indices[tenor].risky_annuity
- theta = - indices[tenor].theta / indices[tenor].notional
- c.execute(sql_str, (id, theta, duration))
+ yc = get_curve(k, "USD" if index in ["IG", "HY"] else "EUR")
+ v = v.merge(df, on='tenor')
+ sc = credit_curve(k, v.close_price.values, v.maturity.values,
+ v.coupon.values, recoveries, yc)
+ for t in v.tenor.values:
+ risky_annuity = fee_legs[t].(
+ k, step_in_date,
+ cash_settle_date, yc, sc,
+ False)
conn.commit()
conn.close()