import datetime import logging from dataclasses import replace from serenitas.analytics.dates import prev_business_day from serenitas.utils.db import dbconn from serenitas.ops.trade_dataclasses import WireDeal from serenitas.ops.funds import Service from report_ops.utils import ( GFSMonitor, StratMonitor, check_cleared_cds, BondMarkMonitor, ) from collateral.common import CASH_STRATEGY_MAPPING, STRATEGY_CASH_MAPPING def check_gfs(date, fund, conn): with conn.cursor() as c: c.execute( "SELECT endqty as amount, invccy as currency, periodenddate as date, port as portfolio FROM valuation_reports vr WHERE fund=%s AND abs(endqty) > 50000 AND port ='GFS_HELPER_BUSINESS_UNIT' AND periodenddate =%s;", ( fund, date, ), ) for row in c: GFSMonitor.stage(row._asdict()) GFSMonitor.email(fund) GFSMonitor._staging_queue.clear() def check_random_strat(date, fund, conn): with conn.cursor() as c: c.execute( "SELECT gfstranid1, invdesc, knowledgedate, periodenddate, port, strat FROM valuation_reports vr WHERE fund=%s AND periodenddate=%s AND port='SERCGMAST';", ( fund, date, ), ) for row in c: StratMonitor.stage(row._asdict()) StratMonitor.email(fund) StratMonitor._staging_queue.clear() def reallocate_strategy_cash(date, fund, conn): service = Service[fund] with conn.cursor() as c: c.execute( "SELECT 1 FROM wires WHERE trade_date=%s AND fund=%s AND author='auto'", ( date, fund, ), ) if c.fetchone(): return c.execute( "SELECT * FROM list_orphaned_cash(%s, %s) WHERE abs(amount) > 1", ( date, fund, ), ) for row in c: if row.folder not in CASH_STRATEGY_MAPPING: obj = WireDeal(**row._asdict()) offset = replace( obj, folder=STRATEGY_CASH_MAPPING[obj.folder], amount=-obj.amount ) obj.stage() offset.stage() if not WireDeal._insert_queue: return for wire in WireDeal.commit(returning=True): service.push_trade(wire, "NEW") buf, dest = service.build_buffer("wire") service.upload(buf, dest.name) service().clear() def check_manager_marks(date, fund, conn): with conn.cursor() as c: c.execute( """SELECT periodenddate, invid, gfstranid1 as geneva_identifier, pricelist, knowledgedate FROM valuation_reports vr WHERE periodenddate =%s AND fund=%s AND strat::text LIKE 'MTG_%%' AND pricelist != 'MANAGER';""", ( date, fund, ), ) for row in c: BondMarkMonitor.stage(row._asdict()) BondMarkMonitor.email(fund) BondMarkMonitor._staging_queue.clear() if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument( "cob", nargs="?", type=datetime.date.fromisoformat, default=prev_business_day(datetime.date.today()), help="working date", ) args = parser.parse_args() logger = logging.getLogger(__name__) conn = dbconn("dawndb") for fund in ( "SERCGMAST", "BOWDST", ): check_gfs(args.cob, fund, conn) check_cleared_cds(args.cob, fund, conn) match fund: case "SERCGMAST": check_manager_marks(args.cob, "SERCGMAST", conn) check_random_strat(args.cob, "SERCGMAST", conn) case "BOWDST": reallocate_strategy_cash(args.cob, "BOWDST", conn)