from db import dawn_engine, serenitas_engine import datetime from pandas.tseries.offsets import BDay from pyisda.date import default_accrual, previous_twentieth from analytics.index import CreditIndex from copy import copy def get_outstanding_positions(trade_date): r = dawn_engine.execute( "SELECT security_id, notional, folder, nextredindexcode, currency, maturity " "FROM list_cds_positions_by_strat(%s) a " "JOIN index_version_markit " "ON a.security_id=index_version_markit.redindexcode " "WHERE nextredindexcode IS NOT NULL", (trade_date,)) return r def default_adjustment(company_id, end_date): r = serenitas_engine.execute("SELECT recovery, event_date, auction_date FROM defaulted " "WHERE id=%s", (company_id,)) recovery, event_date, auction_date = next(r) fee = 1 - recovery start_date = previous_twentieth(event_date) accrual_days, _ = default_accrual(auction_date, event_date, start_date, end_date, 1., 1.) return accrual_days, fee def rebook(trade_date, company_id): upfront_settle_date = trade_date + 3 * BDay() effective_date = trade_date + datetime.timedelta(days=1) for r in get_outstanding_positions(trade_date): accrual_days, fee = default_adjustment(company_id, r['maturity']) index_new = CreditIndex(redcode=r['nextredindexcode'], maturity=r['maturity'], value_date=trade_date, notional=-r['notional']) if index_new.index_type == "HY": n_constituents = 100 elif index_new.index_type in ["EU", "IG"]: n_constituents = 125 elif index_new.index_type == "XO": n_constituents = 75 adj = (fee - accrual_days * index_new.fixed_rate * 1e-4 /360) \ * r['notional'] * 1/n_constituents index_new.mark() trade_new = {'action': 'NEW', 'folder': r['folder'], 'cp_code': 'INTERCO', 'custodian': 'NONE', 'trade_date': trade_date, 'effective_date': effective_date, 'maturity': r['maturity'], 'currency': r['currency'], 'payment_rolldate': 'Following', 'notional': abs(r['notional']), 'fixed_rate': index_new.fixed_rate / 100, 'day_count': 'ACT/360', 'frequency': 4, 'protection': index_new.direction, 'security_id': r['nextredindexcode'], 'security_desc': f"CDX {index_new.index_type} CDSI S{index_new.series} 5Y", 'upfront': -index_new.pv, 'upfront_settle_date': upfront_settle_date, 'swap_type': 'CD_INDEX'} trade_prev = copy(trade_new) trade_prev['protection'] = "Seller" if trade_new['protection'] == "Buyer" else "Buyer" trade_prev['upfront'] = index_new.pv - adj trade_prev['security_id'] = r['security_id'] sql_str = (f"INSERT INTO cds({','.join(trade_new.keys())}) " f"VALUES({','.join(['%s'] * len(trade_new))})") dawn_engine.execute(sql_str, [trade_new.values(), trade_prev.values()]) if __name__ == "__main__": # PKD rebook(datetime.date(2019, 1, 24), 101148)