aboutsummaryrefslogtreecommitdiffstats
path: root/python/report_ops/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/report_ops/utils.py')
-rw-r--r--python/report_ops/utils.py100
1 files changed, 45 insertions, 55 deletions
diff --git a/python/report_ops/utils.py b/python/report_ops/utils.py
index 4a490881..e3ff060c 100644
--- a/python/report_ops/utils.py
+++ b/python/report_ops/utils.py
@@ -15,7 +15,7 @@ from decimal import Decimal
import math
import re
from zoneinfo import ZoneInfo
-from .misc import _recipients
+from .misc import _recipients, _cc_recipients
logger = logging.getLogger(__name__)
@@ -201,6 +201,7 @@ class Monitor:
header: ClassVar[str] = None
line_format: ClassVar[str] = None
_insert_queue: ClassVar[list] = []
+ _em: ClassVar = ExchangeMessage()
def __init_subclass__(cls, keys, header, line_format):
cls.keys = keys
@@ -209,79 +210,68 @@ class Monitor:
@classmethod
def stage(cls, d: dict):
- line = tuple(d[key] for key in cls.keys)
- cls.append(line)
+ cls.insert_queue.append(tuple(d[key] for key in cls.keys))
- def to_email_format(self):
- return f"\t* {self.settle_date}: {self.amount:,.2f} {self.currency}"
+ @classmethod
+ def to_email_format(cls):
+ return "\n".join([cls.line_format.format(line) for line in cls._insert_queue])
class GFSMonitor(
- Monitor, keys=(date, currency, amount), line_format="{0}: {2:,.2f} {1}"
+ Monitor, keys=("date", "currency", "amount"), line_format="* {0}: {2:,.2f} {1}"
):
- pass
+ @classmethod
+ def email(cls, fund):
+ if not cls._insert_queue:
+ return
+ cls._em.send_email(
+ f"GFS Helper Strategy Issue: {fund}",
+ "Good morning, \n\nWe noticed some cash in the GFS helper strategy that shouldn't be there:\n\n"
+ + cls.to_email_format(),
+ to_recipients=_recipients[fund],
+ cc_recipients=_cc_recipients[fund],
+ )
-class PaymentSettlement(Payment):
+class CDXQuoteMonitor(
+ Monitor,
+ keys=("date", "underlying", "globeop_quote", "serenitas_quote"),
+ line_format="* ({0}) {1}: Globeop:{3:,.2f} Ours:{4:,.2f}",
+):
@classmethod
- def email_innocap(cls, date, account_balance):
+ def email(cls, fund):
if not cls._insert_queue:
return
- cls.subtract_cash_balance(account_balance)
- move_cash = ""
- for currency in ("USD", "EUR"):
- biggest_deficit = min(
- list(
- map(
- lambda x: int(x.amount) if x.currency == currency else 0,
- cls._insert_queue,
- )
- )
- )
- if biggest_deficit < 0:
- move_cash += f"\n\n***Please move ${round_up(abs(biggest_deficit), -6):,.2f} {currency} to Northern Trust from Scotia and confirm when done.***"
- em = ExchangeMessage()
- em.send_email(
- f"{'*ACTION REQUESTED* ' if move_cash else ''}Payment Settlements Bond/FX NT: ISOSEL {date}",
- "Good morning, \n\nProjected Balances at Northern Trust: (Positive Amounts = Positive Balance, Negative Amounts = Negative Balance)\n\n"
- + "\n".join(
- settlement.to_email_format() for settlement in cls._insert_queue
- )
- + move_cash,
- to_recipients=_recipients["ISOSEL"],
- cc_recipients=("Selene-Ops@lmcg.com",),
+ cls._em.send_email(
+ f"Cleared CDX Quote Issue: {fund}",
+ "Good morning, \n\nWe've noticed some cleared CDX quotes outside of our tolerance:\n\n"
+ + cls.to_email_format(),
+ to_recipients=_recipients[fund],
+ cc_recipients=_cc_recipients[fund],
)
- cls._insert_queue.clear()
- @classmethod
- def stage_payment(cls, settlements, date):
- for row in settlements:
- cls._insert_queue.append(cls(date, row.currency, row.payment_amount))
+class CBMonitor(
+ Monitor, keys=("date", "currency", "amount"), line_format="* {0}: {2:,.2f} {1}"
+):
@classmethod
- def subtract_cash_balance(cls, account_balance):
- for settlement in cls._insert_queue:
- settlement.amount = Decimal(account_balance[settlement.currency]) - (
- -settlement.amount
- )
-
+ def project_cash_balances(cls, account_balances):
+ projected_balances = []
+ for (date, currency, amount) in cls._insert_queue:
+ projected_balance = Decimal(account_balance[currency]) + amount
+ projected_balances = (date, currency, projected_balance)
+ cls._insert_queue = projected_balances
-class GFSMonitor(Payment):
@classmethod
- def email_globeop(cls, fund):
+ def email(cls, fund):
if not cls._insert_queue:
return
- em = ExchangeMessage()
- em.send_email(
- f"GFS Helper Strategy Issue: {fund}",
- "Good morning, \n\nWe noticed some cash in the GFS helper strategy that shouldn't be there:\n\n"
- + "\n".join(
- settlement.to_email_format() for settlement in cls._insert_queue
- ),
+ cls._em.send_email(
+ f"*ACTION REQUESTED* Projected overdraft for {fund}",
+ "Good morning, \n\nWe are expecting an overdraft at NT: (Positive Amounts = Positive Balance, Negative Amounts = Negative Balance)\n\n"
+ + cls.to_email_format(),
to_recipients=_recipients[fund],
- cc_recipients=(
- "Bowdoin-Ops@LMCG.com" if fund == "BOWDST" else "NYOps@lmcg.com",
- ),
+ cc_recipients=_cc_recipients[fund],
)