from utils.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, indexfactor " "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.0, 1.0 ) return accrual_days, fee PORTFOLIO = {"HYOPTDEL": "OPTIONS", "HEDGE_MBS": "MORTGAGES"} 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"], ) adj = ( (fee - accrual_days * index_new.fixed_rate * 1e-4 / 360) * r["notional"] * (r["indexfactor"] - index_new.factor) ) index_new.mark() trade_new = { "action": "NEW", "portfolio": PORTFOLIO[r["folder"]], "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"] = adj - index_new.pv 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_prev.values(), trade_new.values()]) if __name__ == "__main__": # PKD # rebook(datetime.date(2019, 1, 24), 101148) # WINDSSE rebook(datetime.date(2019, 4, 8), 36806879)