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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
import csv
import datetime
import pathlib
from serenitas.utils.remote import FtpClient, SftpClient
from serenitas.utils.exchange import ExchangeMessage, FileAttachment
from io import StringIO
from typing import Tuple, Union
from serenitas.utils.env import DAILY_DIR
from .file_gen import get_headers, build_line
class Fund:
staged_queue = []
_registry = {}
filepath_pattern = None
def __class_getitem__(cls, fund_name: str):
return cls._registry[fund_name]
def __init_subclass_(cls, fund_name: str):
cls.name = fund_name
cls._registry[fund_name] = cls
@classmethod
def build_buffer(cls, trade_type):
buf = StringIO()
csvwriter = csv.writer(buf)
headers = get_headers(trade_type, cls.name)
csvwriter.writerow(headers)
csvwriter.writerows(
[[obj.get(h) for h in headers] for obj in cls.stating_queue]
)
buf = buf.getvalue().encode()
dest = cls.get_filepath(DAILY_DIR, trade_type)
dest.parent.mkdir(exist_ok=True)
dest.write_bytes(buf)
return buf, dest
@classmethod
def set_headers(cls, trade_type):
cls.headers = get_headers(trade_type, cls.name)
@classmethod
def stage(cls, trade, *, trade_type, **kwargs):
cls.stating_queue.append(build_line(trade, trade_type, cls.name))
@classmethod
def get_filepath(
cls,
base_dir: pathlib.Path,
trade_type: Union[str, Tuple[str, str]],
) -> pathlib.Path:
d = {
"bond": "Mortgages",
"cds": "CreditDefaultSwapDeal",
"swaption": "SwaptionDeal",
"future": "Future",
"wire": "CashFlowDeal",
"spot": "SpotDeal",
"fx_swap": "FxSwapDeal",
"capfloor": "CapFloor",
"repo": "RepoDeal",
}
trade_tag: str
if isinstance(trade_type, tuple):
trade_tag = d[trade_type[0]] + trade_type[1]
else:
trade_tag = d[trade_type]
timestamp = datetime.datetime.now()
return (
base_dir
/ str(timestamp.date())
/ cls.filepath_pattern.format(timestamp, trade_tag)
)
class Serenitas(Fund, fund_name="SERCGMAST"):
filepath_pattern = "Serenitas.ALL.{timestamp:%Y%m%d.%H%M%S}.{trade_tag}.csv"
@staticmethod
def upload(buf, dest):
ftp = FtpClient.from_creds("serenitas")
ftp.client.cwd("incoming")
ftp.client.put(buf, dest)
class Brinker(Fund, fund_name="BRINKER"):
filepath_pattern = "LMCG_BBH_SWAP_TRADES_P.{timestamp:%Y%m%d%H%M%S}.csv"
@staticmethod
def upload(buf, dest):
sftp = SftpClient.from_creds("bbh")
sftp.put(buf, dest)
class Bowdst(Fund, fund_name="BOWDST"):
filepath_pattern = "Bowdst.ALL.{timestamp:%Y%m%d.%H%M%S}.{trade_tag}.csv"
@staticmethod
def upload(buf, dest):
sftp = SftpClient.from_creds("hm_globeop")
sftp.client.chdir("incoming")
sftp.put(buf, dest)
em = ExchangeMessage()
recipients = ("hm-operations@bnymellon.com",)
em.send_email(
"Trade file",
"",
to_recipients=recipients,
cc_recipients=("bowdoin-ops@lmcg.com",),
attach=(FileAttachment(name=dest, content=buf),),
)
class Selene(Fund, fund_name="ISOSEL"):
@classmethod
def stage(cls, trade, *, action="NEW", **kwargs):
cls.stating_queue.append(trade.to_citco(action))
|