diff options
Diffstat (limited to 'python/thetas-durations.py')
| -rw-r--r-- | python/thetas-durations.py | 64 |
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() |
