import logging import argparse import datetime from serenitas.analytics.dates import prev_business_day from serenitas.utils.db import dbconn from serenitas.utils.exchange import ExchangeMessage from serenitas.analytics.exceptions import MissingDataError from .sma import SMA from .cash import CashReport from .admin import CitcoReport from .wires import WireReport from .custodians import upload_to_custodian, get_custodian_download_fun from .utils import notify_payment_settlements, notify_fx_hedge from .misc import _fund_custodians logging.basicConfig( format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO ) logger = logging.getLogger(__name__) logging.getLogger("exchangelib.fields").setLevel(logging.WARNING) parser = argparse.ArgumentParser() parser.add_argument( "-s", "--sma_positions", action="store_true", help="upload sma positions to hedgemark", ) parser.add_argument( "-c", "--cash_reports", action="store_true", help="process cash reports to database" ) parser.add_argument( "-i", "--isosel_reports", action="store_true", help="download isosel reports to database", ) parser.add_argument( "-w", "--wire_reports", action="store_true", help="download wires to db" ) parser.add_argument( "-sc", "--send_to_custodians", action="store_true", help="upload trade files to notify custodians", ) parser.add_argument( "-ps", "--payment_settlements", action="store_true", help="notify payment settlements by email", ) parser.add_argument( "-fh", "--fx_hedge", action="store_true", help="return fx trades", ) parser.add_argument( "-n", "--no-upload", action="store_true", help="do not upload, just create files" ) parser.add_argument( "date", nargs="?", type=datetime.date.fromisoformat, default=datetime.date.today(), ) args = parser.parse_args() cob = prev_business_day(args.date) if args.sma_positions: for fund in ("BOWDST", "ISOSEL", "BRINKER"): sma = SMA[fund](cob) try: sma.email_positions() except ValueError as e: logger.warning(e) if args.cash_reports or args.wire_reports: em = ExchangeMessage() for fund, custodians in _fund_custodians.items(): for custodian in custodians: get_custodian_download_fun(custodian)(args.date, fund, em=em) if args.cash_reports: cash_report = CashReport[custodian] try: for row in cash_report.yield_rows(args.date, fund): cash = cash_report.from_report_line( row | {"fund": fund, "knowledge_date": args.date} ) cash.stage() cash_report.commit() cash_report.clear() except (MissingDataError, RuntimeError) as e: logger.warning(e) if args.wire_reports: wire_report = WireReport[custodian] try: for row in wire_report.yield_rows(args.date, fund): wire = wire_report.from_report_line(row | {"fund": fund}) wire.stage() wire_report.commit() wire_report.clear() except (MissingDataError, RuntimeError) as e: logger.warning(e) if args.isosel_reports: for fund in ("ISOSEL",): for report in ("isosel_accrued", "citco_reports"): report = CitcoReport[report](cob, fund) try: report.to_db() except MissingDataError as e: logger.warning(e) if args.send_to_custodians: for account in ( "BBH", "UMB", ): upload_to_custodian(account, args.date, not args.no_upload) if args.payment_settlements: conn = dbconn("dawndb") for fund in ("SERCGMAST", "BRINKER", "BOWDST", "ISOSEL"): notify_payment_settlements(args.date, fund, conn) if args.fx_hedge: conn = dbconn("dawndb") for fund in ("SERCGMAST", "BOWDST", "ISOSEL"): notify_fx_hedge(cob, fund, conn)