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, fcm): r = dawn_engine.execute( "SELECT security_id, notional, folder, nextredindexcode, currency, " "maturity, indexfactor " "FROM list_cds_positions_by_strat_fcm(%s, %s) a " "JOIN index_version_markit " "ON a.security_id=index_version_markit.redindexcode " "WHERE nextredindexcode IS NOT NULL", (trade_date, fcm), ) return r def default_adjustment(company_id, seniority, end_date): r = serenitas_engine.execute( "SELECT recovery, event_date, auction_date FROM defaulted WHERE id=%s " "AND seniority=%s", (company_id, seniority), ) 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", "HYINX": "TRANCHE", "SER_IGCURVE": "CURVE", } def rebook(trade_date, company_id, seniority, fcm): upfront_settle_date = trade_date + 3 * BDay() effective_date = trade_date + datetime.timedelta(days=1) for r in get_outstanding_positions(trade_date, fcm): accrual_days, fee = default_adjustment(company_id, seniority, 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": "CONTRA", "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", "account_code": fcm, } 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) # WFT # rebook(datetime.date(2019, 7, 26), 103633, "WF") # rebook(datetime.date(2019, 7, 26), 103633, "BAML") # DF rebook(datetime.date(2019, 12, 11), 154954, "Senior", "BAML")