aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/reallocate_iam.py199
-rw-r--r--python/report_ops/cash.py18
2 files changed, 87 insertions, 130 deletions
diff --git a/python/reallocate_iam.py b/python/reallocate_iam.py
index cbbc5c43..07f827db 100644
--- a/python/reallocate_iam.py
+++ b/python/reallocate_iam.py
@@ -1,11 +1,11 @@
from serenitas.utils.misc import rename_keys
import datetime
from collections import defaultdict
-from psycopg2.errors import UniqueViolation
-from serenitas.analytics.dates import bus_day
from serenitas.ops.funds import Service
+from report_ops.cash import IAMDeal
+from serenitas.analytics.dates import prev_business_day
-_iam_brokers = {
+_bowdst_iam_cp = {
"BAML_ISDA": "BOANNY",
"CS": "CSITLN",
"GS": "GOLINY",
@@ -14,138 +14,92 @@ _iam_brokers = {
"JPM": "JPCBNY",
"GS_FCM": "GOLDNY",
}
-_custodian = {"GOLDNY": "GS"}
-_cash_account = {"GOLDNY": "057363418ICE-CDS"}
+_serenitas_iam_cp = {
+ "BAML_ISDA": "BAMSNY",
+ "CS": "CSFBBO",
+ "GS": "GOLDNY",
+ "BNP": "BNPBNY",
+ "MS": "MSCSNY",
+ "JPM": "JPCBNY",
+ "GS_FCM": "GOLDNY",
+}
-def iam_serialize(obj, action, trade_date):
- rename_keys(
- obj,
- {
- "dealid": "Deal Id",
- "counterparty": "Counterparty",
- "currency": "Currency",
- "start_money": "StartMoney",
- "trade_date": "Trade Date",
- },
- )
- deal_fields = {
- "Deal Type": "IamDeal",
- "Client": "HEDGEMARK",
- "Fund": "BOS_PAT_BOWDOIN",
- "Custodian": _custodian.get(obj["Counterparty"], "BNY"),
- "Cash Account": _cash_account.get(obj["Counterparty"], 751254),
- "State": "Valid",
- "SettlementDate": obj["Trade Date"],
- "Basis": "ACT/360",
- "MarginType": "Variation",
- "DealFunction": "OTC",
- "Folder": "M_CSH_CASH" if obj["strategy"] == "CSH_CASH" else obj["strategy"],
- "Action": action,
- "TransactionIndicator": "DEPOSIT" if obj["StartMoney"] > 0 else "LOAN",
- "ExpirationDate": trade_date
- if action == "UPDATE"
- else None, # We are updating old IAMDeals to expire
- "CallNoticeIndicator": "24H" if action == "NEW" else None, # This is a new IAM
- }
- obj["StartMoney"] = abs(obj["StartMoney"])
- obj.update(deal_fields)
- return obj
+def get_counterparty(fund, iam_broker):
+ match fund:
+ case "SERCGMAST":
+ return _serenitas_iam_cp[iam_broker]
+ case "BOWDST":
+ return _bowdst_iam_cp[iam_broker]
-def gen_offset(totals, trade_date):
- offsets = [
- (trade_date, "NEW", "CSH_CASH", broker, None, -amount, "USD", True)
- for broker, amount in totals.items()
- ]
- return offsets
+def get_custodian_account(fund, iam_broker):
+ match fund, iam_broker:
+ case ("SERCGMAST", "WF_FCM"):
+ return ("WELLSFCM", "WFNSCLMFCM")
+ case ("SERCGMAST", "BAML_FCM"):
+ return ("BOMLCM", "V0NSCLMFCM")
+ case ("BOWDST", "GS_FCM"):
+ return ("GS", "057363418ICE-CDS")
+ case ("SERCGMAST", _):
+ return ("UMB", "159260.1")
+ case ("BOWDST", _):
+ return ("BNY", "751254")
-def gen_strat_alloc(conn, trade_date):
- new_iam = []
- totals = defaultdict(int) # Need to figure out how much to offset
+def globeop_mapping(fund, iam_broker):
+ (custodian, cash_account) = get_custodian_account(fund, iam_broker)
+ return {
+ "custodian": custodian,
+ "cash_account": cash_account,
+ "counterparty": get_counterparty(fund, iam_broker),
+ }
+
+
+def gen_new_iam_deals(fund, cob, conn):
with conn.cursor() as c:
- strategy_allocation = (
- "SELECT broker, amount, currency, strategy FROM (SELECT *, rank() "
- "OVER(PARTITION BY broker,fund ORDER BY date desc) FROM strategy_im si "
- "WHERE fund = 'BOWDST' AND date<=%s ORDER BY date DESC) test WHERE RANK=1 and abs(amount) >= .01;"
+ c.execute(
+ "SELECT * FROM list_iam(%s, %s)",
+ (
+ cob,
+ fund,
+ ),
)
- c.execute(strategy_allocation, (trade_date,))
for row in c:
- new_iam.append(
- (
- trade_date,
- "NEW",
- row.strategy,
- _iam_brokers[row.broker],
- None,
- row.amount,
- row.currency,
- False,
- )
- )
- if row.broker != "GS_FCM": # HM doesn't book FCM, no need to offset
- totals[_iam_brokers[row.broker]] += row.amount
- new_iam += gen_offset(totals, trade_date)
- return new_iam
+ d = row._asdict() | globeop_mapping(fund, row.broker)
+ yield IAMDeal.from_dict(**d)
-def process_trades(conn, trade_date):
- # We will be grabbing the IAM deals from the DB for the new trades and for the updated trades
- deals = []
- actions = [
- (
- "NEW",
- "UPDATE iam_tickets set uploaded=True where maturity is null and trade_date =%s "
- "and action='NEW' and not uploaded returning *",
- (trade_date,),
- ),
- (
- "UPDATE",
- "UPDATE iam_tickets set maturity=%s where trade_date != %s and maturity is null and action='NEW' returning *",
- (trade_date, trade_date),
- ),
- ]
- for action, query, params in actions:
- with conn.cursor() as c:
- c.execute(query, params)
- for row in c:
- deals.append(iam_serialize(row._asdict(), action, trade_date))
- return deals
-
-
-def gen_iam_deals(conn, trade_date):
- new_iam = gen_strat_alloc(conn, trade_date)
- iam_deals = []
+def gen_new_iam_offsets(fund, cob, conn):
with conn.cursor() as c:
- insert_query = (
- "INSERT INTO iam_tickets(trade_date, action, strategy, counterparty, maturity, start_money, currency, booked_offset) "
- "VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"
+ c.execute(
+ "SELECT trade_date, broker, currency, fund, sum(start_money) AS start_money "
+ "FROM list_iam(%s, %s) GROUP BY (trade_date, broker, currency, fund);",
+ (
+ cob,
+ fund,
+ ),
)
- try:
- c.executemany(insert_query, new_iam)
- except UniqueViolation:
- # We already uploaded the IAM tickets today in that case, we need to update and cancel the old uploads
- conn.rollback()
- c.execute(
- "DELETE FROM iam_tickets where trade_date=%s returning *", (trade_date,)
+ for row in c:
+ d = (
+ row._asdict()
+ | globeop_mapping(fund, row.broker)
+ | {"offset": True, "folder": "M_CSH_CASH"}
)
- cancel_iam_deals = [
- iam_serialize(row._asdict(), "CANCEL", trade_date) for row in c
- ]
- iam_deals += cancel_iam_deals
- c.executemany(insert_query, new_iam)
- iam_deals += process_trades(conn, trade_date)
- return iam_deals
+ return IAMDeal.from_dict(**d)
-def process_upload(conn, trade_date, iam_deals):
- bowdst = Service["BOWDST"]()
- bowdst.staging_queue.extend(iam_deals)
- if bowdst.staging_queue:
- buf, dest = bowdst.build_buffer("iam")
- bowdst.upload(buf, dest.name)
+def main(fund, cob, conn):
+ service = Service[fund]
+ for iam in gen_iam_deals(fund, cob, conn):
+ iam.stage()
+ if fund in ("BOWDST"):
+ for iam in gen_iam_offsets(fund, cob, conn):
+ iam.stage()
+ for iam in IamDeal.commit():
+ service.push(iam)
+ buf, dest = service.build_buffer()
if __name__ == "__main__":
@@ -155,12 +109,11 @@ if __name__ == "__main__":
conn = dbconn("dawndb")
parser = argparse.ArgumentParser(description="Generate IAM file for globeop")
parser.add_argument(
- "date",
+ "cob",
nargs="?",
type=datetime.date.fromisoformat,
- default=(datetime.date.today() - bus_day).date(),
+ default=prev_business_day(datetime.date.today()),
)
args = parser.parse_args()
- iam_deals = gen_iam_deals(conn, args.date)
- process_upload(conn, args.date, iam_deals)
- conn.commit()
+ for fund in ("BOWDST",):
+ main(fund, args.cob, conn)
diff --git a/python/report_ops/cash.py b/python/report_ops/cash.py
index eabe5805..027cb350 100644
--- a/python/report_ops/cash.py
+++ b/python/report_ops/cash.py
@@ -13,17 +13,21 @@ from functools import partial
@dataclass
class IAMDeal(Deal, deal_type=None, table_name="iam_tickets"):
trade_date: datetime.date = field(metadata={"globeop": "SettlementDate"})
- action: str = field(metadata={"globeop": "Action"})
- strategy: str = field(metadata={"globeop": "Folder"})
+ folder: str = field(metadata={"globeop": "Folder"})
counterparty: str = field(metadata={"globeop": "Counterparty"})
- maturity: datetime.date
start_money: float = field(metadata={"globeop": "StartMoney"})
currency: str = field(metadata={"globeop": "Currency"})
- booked_offset: bool
- uploaded: bool
fund: Fund
- dealid: str = field(metadata={"insert": False})
- id: int = field(metadata={"insert": False})
+ maturity: datetime.date = None
+ uploaded: bool = False
+ booked_offset: bool = False
+ dealid: str = None
+ id: int = None
+ cash_account: str = field(
+ default=None,
+ metadata={"insert": False, "select": False, "globeop": "Cash Account"},
+ )
+ custodian: str = field(default=None, metadata={"insert": False, "select": False})
def to_globeop(self, action):
obj = super().to_globeop(action)