aboutsummaryrefslogtreecommitdiffstats
path: root/python/mtm_upload.py
blob: 8ac6a6bd9c2af5df738d850868938dd0024ba08d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
from serenitas.utils.db import dbconn
from io import StringIO
import csv
from serenitas.utils.env import DAILY_DIR
from serenitas.utils.remote import SftpClient
from serenitas.analytics.dates import next_business_day
import datetime
from trade_dataclasses import CDSDeal, SwaptionDeal
from headers import MTM_HEADERS


def rename_keys(d, mapping):
    """rename keys in dictionary according to mapping dict inplace"""
    for k, v in mapping.items():
        if k in d:
            d[v] = d.pop(k)


def tranche_trades(tradeids, conn):
    trades = []
    for tradeid in tradeids:
        obj = CDSDeal.from_tradeid(tradeid).to_markit()
        trades.append(obj)
    return trades


def swaption_trades(tradeids, conn):
    trades = []
    for tradeid in tradeids:
        obj = SwaptionDeal.from_tradeid(tradeid).to_markit()
        trades.append(obj)
    return trades


def tranche_term_trades(conn):
    with conn.cursor() as c:
        trades = []
        c.execute(
            "SELECT terminations.*, cds.fund, cds.cp_code FROM terminations left join cds using (dealid) where termination_date >= %s and dealid LIKE %s",
            (datetime.date(2022, 3, 1), "SCCDS%"),
        )
        for row in c:
            obj = row._asdict()
            rename_keys(
                obj,
                {
                    "dealid": "Swap ID",
                    "termination_cp": "Broker Id",
                    "termination_amount": "1st Leg Notional",
                    "termination_fee": "Initial Payment",
                    "termination_date": "Trade Date",
                    "fee_payment_date": "Settle Date",
                    "fund": "Account Abbreviation",
                    "termination_cp": "Broker Id",
                    "cp_code": "Remaining Party",
                },
            )
            if obj["Initial Payment"] >= 0:
                obj["Transaction Code"] = "Receive"
            else:
                obj["Initial Payment"] = abs(obj["Initial Payment"])
                obj["Transaction Code"] = "Pay"
            obj["Currency Code"] = "USD"
            obj["Product Type"] = "TRN"
            obj["Entity Matrix"] = "Publisher"
            obj["Definitions Type"] = "ISDA2003Credit"
            obj["Trade ID"] = obj["Swap ID"] + "-" + str(obj["id"])
            obj["Transaction Type"] = "Partial Assignment"
            obj["Effective Date"] = obj["Trade Date"] + datetime.timedelta(days=1)
            trades.append(obj)
    return trades


def terminations(tradeid, conn):
    with conn.cursor() as c:
        termination_query = (
            """SELECT terminations.*, coalesce(cds.cp_code, swaptions.cp_code) AS orig_cp, COALESCE (cds."currency", swaptions."currency") AS currency, """
            """COALESCE (cds."swap_type", 'SWAPTION') as swap_type FROM terminations LEFT JOIN cds USING (dealid) LEFT JOIN swaptions USING (dealid) where terminations.id = %s ORDER BY id desc;"""
        )
        c.execute(termination_query, (tradeid,))
        for row in c:
            obj = row._asdict()
            rename_keys(
                obj,
                {
                    "dealid": "Swap ID",
                    "termination_cp": "Broker Id",
                    "termination_amount": "1st Leg Notional",
                    "termination_fee": "Initial Payment",
                    "termination_date": "Trade Date",
                    "fee_payment_date": "Settle Date",
                    "fund": "Account Abbreviation",
                    "termination_cp": "Broker Id",
                    "orig_cp": "Remaining Party",
                    "currency": "Currency Code",
                },
            )
            if obj["Initial Payment"] >= 0:
                obj["Transaction Code"] = "Receive"
            else:
                obj["Initial Payment"] = abs(obj["Initial Payment"])
                obj["Transaction Code"] = "Pay"
            match obj["swap_type"]:
                case "CD_INDEX_TRANCHE":
                    obj["Product Type"] = "TRN"
                case "SWAPTION":
                    obj["Product Type"] = "CDISW"
                case _:
                    print("Not a valid termination")
            obj["Trade ID"] = obj["Swap ID"] + "-" + str(obj["id"])
            obj["Transaction Type"] = (
                "Termination"
                if obj["Remaining Party"] == obj["Broker Id"]
                else "Assignment"
            )
            obj["Effective Date"] = obj["Trade Date"] + datetime.timedelta(days=1)
            trades.append(obj)


def build_line(obj, asset_type):
    return [obj.get(h, None) for h in MTM_HEADERS[asset_type]]


def process_upload(trades, asset_type, upload):
    buf = StringIO()
    csvwriter = csv.writer(buf)
    csvwriter.writerow(MTM_HEADERS[asset_type])
    csvwriter.writerows(build_line(trade, asset_type) for trade in trades)
    buf = buf.getvalue().encode()
    fname = f"MTM.{datetime.datetime.now():%Y%m%d.%H%M%S}.{asset_type.capitalize()}.csv"
    sftp = SftpClient.from_creds("mtm")
    sftp.put(buf, fname)
    dest = DAILY_DIR / str(datetime.date.today()) / fname
    dest.write_bytes(buf)


def upload_mtm_trades(trade_type, tradeid, conn=None):
    match trade_type:
        case "swaption":
            process_upload(
                SwaptionDeal.from_tradeid(tradeid).to_markit(), trade_type, True
            )
        case "cds":
            process_upload(CDSDeal.from_tradeid(tradeid).to_markit(), trade_type, True)
        case "termination":
            process_upload(terminations(tradeid, conn), trade_type, True)


if __name__ == "__main__":
    conn = dbconn("dawndb")
    upload_trades(conn)