diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/cds_curve.py | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/python/cds_curve.py b/python/cds_curve.py index 7b9e5713..2b5285f0 100644 --- a/python/cds_curve.py +++ b/python/cds_curve.py @@ -93,59 +93,61 @@ def forward_hazard_rates(sc): serenitas_engine = dbengine('serenitasdb') -def calibrate_portfolio(index_type, series): +def calibrate_portfolio(index_type, series, tenors=['3yr', '5yr', '7yr', '10yr']): if index_type == 'IG': recovery = 0.4 else: recovery = 0.3 - tenors = ['3yr', '5yr', '7yr', '10yr'] index_quotes = get_index_quotes(index_type, series, tenors)['closeprice'].unstack() - index_desc = pd.read_sql_query("SELECT tenor, maturity, coupon FROM index_maturity " \ - "WHERE index=%s AND series=%s", serenitas_engine, - index_col='tenor', params=(index_type, series)) + index_desc = pd.read_sql_query("SELECT tenor, maturity, coupon * 1e-4 AS coupon, " \ + "issue_date "\ + "FROM index_maturity " \ + "WHERE index=%s AND series=%s", serenitas_engine, + index_col='tenor', params=(index_type, series), + parse_dates=['maturity', 'issue_date']) index_quotes.columns = index_desc.loc[index_quotes.columns, "maturity"] - index_quotes = index_quotes.sort_index(1) - end_dates = [datetime.date(2017, 12, 20), - datetime.date(2018, 12, 20), - datetime.date(2019, 12, 20), - datetime.date(2020, 12, 20), - datetime.date(2021, 12, 20), - datetime.date(2023, 12, 20), - datetime.date(2026, 12, 20)] - maturities = index_desc.maturity.tolist() - start_date = datetime.date(2016, 9, 20) + index_quotes = 1 - index_quotes / 100 + issue_date = index_desc.issue_date[0] + end_dates = [issue_date + relativedelta(years=i, months=3) for i \ + in [1, 2, 3, 4, 5, 7, 10]] + index_desc = index_desc.set_index('maturity') + maturities = index_quotes.columns.sort_values().to_pydatetime() r = {} for k, s in index_quotes.iterrows(): - trade_date = k[0].date() + trade_date = k[0] + print(trade_date) sn_quotes = get_singlenames_quotes("{}{}".format(index_type.lower(), series), - trade_date) + trade_date.date()) Settings().evaluation_date = Date.from_datetime(trade_date) yc = YC() jp_yc = ql_to_jp(yc) step_in_date = trade_date + datetime.timedelta(days=1) - value_date = (pd.Timestamp(trade_date) + 3* BDay()).date() - args = (trade_date, jp_yc, start_date, step_in_date, value_date, end_dates) + value_date = pd.Timestamp(trade_date) + 3* BDay() + args = (trade_date, jp_yc, issue_date, step_in_date, value_date, end_dates) curves = build_curves_dist(sn_quotes, args) - index = CreditIndex(start_date, maturities, curves) + index = CreditIndex(issue_date, maturities, curves) d = {'tweak':[], 'duration':[], 'theta':[]} - for i, m in enumerate(maturities): - index_quote = 1 - s.iat[i]/100 - eps = brentq(lambda epsilon: index.pv(step_in_date, - value_date, m, jp_yc, 0.4, 0.01, epsilon) - - index_quote, -0.3, 0.3) + s.name = 'index_quote' + quotes = pd.concat([index_desc, s], axis=1) + for m, coupon, index_quote in quotes[['coupon', 'index_quote']].itertuples(): + eps = brentq(lambda epsilon: index.pv(step_in_date, value_date, + m, jp_yc, recovery, + coupon, epsilon) - + index_quote, -0.35, 0.3) #tweak the curves in place index.tweak_portfolio(eps, m) d['duration'].append(index.duration(step_in_date, value_date, m, jp_yc)) d['theta'].append(index_quote - index.theta(step_in_date, value_date, - m - relativedelta(years=1), jp_yc, 0.4, 0.01) + - 0.01) + m - relativedelta(years=1), + jp_yc, recovery, coupon) + + coupon) d['tweak'].append(eps) r[trade_date] = pd.DataFrame(d, index=tenors) - return pd.concat(d) + return pd.concat(r) if __name__=="__main__": df = calibrate_portfolio("IG", 27) |
