aboutsummaryrefslogtreecommitdiffstats
path: root/python/thetas-durations.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/thetas-durations.py')
-rw-r--r--python/thetas-durations.py64
1 files changed, 40 insertions, 24 deletions
diff --git a/python/thetas-durations.py b/python/thetas-durations.py
index 286a77b5..e7ee6cbb 100644
--- a/python/thetas-durations.py
+++ b/python/thetas-durations.py
@@ -3,6 +3,7 @@ import numpy as np
import pandas as pd
from analytics.utils import tenor_t
from pandas.tseries.offsets import BDay
+from dateutil.relativedelta import relativedelta
from yieldcurve import get_curve
from db import dbengine
from pyisda.legs import FeeLeg, ContingentLeg
@@ -20,8 +21,6 @@ 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 "
@@ -31,24 +30,22 @@ def get_legs(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)
+ maturity_short = maturity - relativedelta(years=1)
+ fee_legs[tenor] = (FeeLeg(issue_date, maturity, True, 1., 1.),
+ FeeLeg(issue_date, maturity_short,
+ True, 1., coupon))
+ contingent_legs[tenor] = (ContingentLeg(issue_date, maturity, True),
+ ContingentLeg(issue_date, maturity_short, True))
# 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
+def index_pv(fl, cl, value_date, step_in_date, cash_settle_date, yc, sc, recovery):
+ dl_pv = cl.pv(value_date, step_in_date, cash_settle_date, yc, sc, recovery)
+ cl_pv = fl.pv(value_date, step_in_date, cash_settle_date, yc, sc, True)
+ return dl_pv - cl_pv
conn = serenitas_engine.raw_connection()
for index in ["IG", "HY", "EU", "XO"]:
@@ -77,15 +74,34 @@ for index in ["IG", "HY", "EU", "XO"]:
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'):
- 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)
+ for value_date, data in index_quotes.groupby('date'):
+ yc = get_curve(value_date, "USD" if index in ["IG", "HY"] else "EUR")
+ # right_index?? is it a bug?
+ data = data.merge(df, on='tenor', right_index=True)
+ step_in_date = value_date + datetime.timedelta(days=1)
+ cash_settle_date = value_date + 3 * BDay()
+ start_date = previous_twentieth(value_date)
+ sc = SpreadCurve(value_date, yc, start_date,
+ step_in_date, cash_settle_date,
+ data.maturity.values, data.coupon.values,
+ data.close_price.values,
+ recoveries)
+ for r in data[['coupon', 'tenor', 'close_price']].itertuples():
+ fl, fl_short = fee_legs[r.tenor]
+ cl, cl_short = contingent_legs[r.tenor]
+
+ duration = fl.pv(value_date, step_in_date,
+ cash_settle_date, yc, sc,
+ True)
+ if cl_short.end_date <= value_date.date():
+ theta = None
+ else:
+ pv = index_pv(fl_short, cl_short,
+ value_date, step_in_date, cash_settle_date, yc, sc,
+ recoveries[0])
+ theta = r.close_price - pv + r.coupon
+
+ c.execute("INSERT INTO index_risk VALUES(%s, %s, %s)",
+ (r.Index, theta, duration))
conn.commit()
conn.close()