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
|
import datetime
import logging
import pandas as pd
from exchangelib import HTMLBody
from sqlalchemy.engine import Engine
logger = logging.getLogger(__name__)
CASH_STRATEGY_MAPPING = {
"COCSH": ["IGREC", "IGPAYER", "HYPAYER", "HYREC", "HYOPTDEL", "IGOPTDEL"],
"IRDEVCSH": ["STEEP", "FLAT"],
"TCSH": [
"IGMEZ",
"IGSNR",
"IGEQY",
"HYMEZ",
"HYEQY",
"BSPK",
"XOMEZ",
"IGINX",
"HYINX",
"XOINX",
],
"MBSCDSCSH": ["HEDGE_MBS", "MBSCDS"],
"MACCDSCSH": ["HEDGE_MAC"],
"SER_ITRXCVCSH": ["SER_ITRXCURVE"],
"SER_IGCVECSH": ["SER_IGCURVE"],
}
STRATEGY_CASH_MAPPING = {e: k for k, v in CASH_STRATEGY_MAPPING.items() for e in v}
def compare_notionals(df: pd.DataFrame, positions: pd.DataFrame, fcm: str) -> None:
check_notionals = (
positions.groupby(level=["security_id", "maturity"])[["notional"]]
.sum()
.join(df["NOTIONAL"], how="left")
)
diff_notionals = check_notionals[
check_notionals.notional != check_notionals.NOTIONAL
]
if not diff_notionals.empty:
logger.error(f"Database and {fcm} FCM know different notionals")
for t in diff_notionals.itertuples():
logger.error(
f"{t.Index[0]}\t{t.Index[1].date()}\t{t.notional}\t{t.NOTIONAL}"
)
def get_dawn_trades(d: datetime.date, engine: Engine) -> pd.DataFrame:
df_cds = pd.read_sql_query(
"SELECT cpty_id, folder, initial_margin_percentage * notional / 100 as IA "
"FROM list_cds(%s::date) "
"WHERE cpty_id IS NOT NULL",
engine,
params=(d,),
)
df_swaptions = pd.read_sql_query(
"SELECT cpty_id, folder, initial_margin_percentage * notional / 100 AS IA "
"FROM swaptions "
"WHERE cpty_id IS NOT NULL "
"AND trade_date <= %s",
engine,
params=(d,),
)
df_caps = pd.read_sql_query(
"SELECT cpty_id, folder, initial_margin_percentage * amount / 100 AS IA "
"FROM capfloors "
"WHERE cpty_id IS NOT NULL "
"AND trade_date <= %s",
engine,
params=(d,),
)
df = pd.concat([df_cds, df_swaptions, df_caps])
df = df.replace({"folder": STRATEGY_CASH_MAPPING})
return df
def send_email(d: datetime.date, df: pd.DataFrame) -> None:
from exchange import ExchangeMessage
pd.set_option("display.float_format", "{:.2f}".format)
df = df.drop("date", axis=1).set_index("broker")
cp_mapping = {
"CITI": "Citi",
"MS": "Morgan Stanley",
"GS": "Goldman Sachs",
"BAML_FCM": "Baml FCM",
"BAML_ISDA": "Baml OTC",
"WELLS": "Wells Fargo",
"BNP": "BNP Paribas",
"CS": "Credit Suisse",
}
html = "<html><body>"
for cp, name in cp_mapping.items():
html += f"<h3> At {name}:</h3>\n{df.loc[cp].to_html(index=False)}"
em = ExchangeMessage()
em.send_email(
f"IAM booking {d:%Y-%m-%d}",
HTMLBody(html),
["serenitas.otc@sscinc.com"],
["nyops@lmcg.com"],
)
|