diff options
Diffstat (limited to 'python/intex')
| -rw-r--r-- | python/intex/__init__.py | 0 | ||||
| -rw-r--r-- | python/intex/common.py | 18 | ||||
| -rw-r--r-- | python/intex/intex_scenarios.py | 239 | ||||
| -rw-r--r-- | python/intex/load_indicative.py | 187 | ||||
| -rw-r--r-- | python/intex/load_intex_collateral.py | 149 |
5 files changed, 593 insertions, 0 deletions
diff --git a/python/intex/__init__.py b/python/intex/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/python/intex/__init__.py diff --git a/python/intex/common.py b/python/intex/common.py new file mode 100644 index 00000000..557189a4 --- /dev/null +++ b/python/intex/common.py @@ -0,0 +1,18 @@ +import os + +if os.name =='nt': + root = "//WDsentinel/share/CorpCDOs" +elif os.name == 'posix': + root = '/home/share/CorpCDOs' + +def sanitize_float(intex_float): + try: + intex_float = intex_float.replace(",", "") + if " " in intex_float: #case of combo notes + return float(intex_float.split(" ")[0]) + if "(" in intex_float: + return - float(intex_float[1:-1]) + else: + return float(intex_float) + except (AttributeError, ValueError): + return intex_float diff --git a/python/intex/intex_scenarios.py b/python/intex/intex_scenarios.py new file mode 100644 index 00000000..2650b25a --- /dev/null +++ b/python/intex/intex_scenarios.py @@ -0,0 +1,239 @@ +import os
+import os.path
+import datetime
+import csv
+from csv import reader
+import json
+import re
+import psycopg2
+from common import root
+from db import query_db, with_connection
+import sys
+import yaml
+
+pattern1 = re.compile("REINVEST\[\w+::REINV_TBA(\d)\]\[DEAL,(\d+)\]=.*$")
+# reinv end date
+pattern2 = re.compile("(STANDARD_VAR\[)\w+(::#REINV_END,\d+\]=)(\d.*$)")
+# reinvprices 1
+pattern3 = re.compile("STANDARD_VAR\[\w+::#PRICE100_TBA(\d),(\d+)\]=")
+pattern5 = re.compile("STANDARD_VAR\[\w+::#REINVPCT_TBA(\d),(\d+)\]=")
+pattern7 = re.compile("KINGS3")
+pattern8 = re.compile("(#COLLATREINV_REINV_PCT_EXT\[)\w+(::\*\]\[DEAL,\d+\])=100")
+pattern9 = re.compile("(?P<a>SEVERITY\[\w+,\d+\]=)mkt\(70\)")
+
+# we use 84 so that it's both dividable by 2 and 3
+global_reinvfloatpercentage = 84
+global_reinvfixedpercentage = 16
+
+@with_connection
+def dealname_from_cusip(conn, cusips):
+ with conn.cursor() as c:
+ c.callproc("dealname_from_cusip", params = cusip)
+ dealnames = [d[0] for d in c.fetchall()]
+ return dealnames
+
+def get_reinv_assets(dealname, workdate):
+ sqlstr = 'select * from et_historicaldealinfo(%s, %s) where ReinvFlag IS TRUE'
+ reinvassets = query_db(sqlstr, params = (dealname, workdate), one = False)
+ d = {}
+ for line in reinvassets:
+ d[line[3]] = line[22]
+ return d
+
+def get_recovery(dealname, workdate, defaultrecovery = 50):
+ """ compute average price of defaulted assets
+ """
+ sqlstr = "select sum(coalesce(price, %s) * currentbalance)/sum(currentbalance) " + \
+ "from et_aggdealinfo_historical(%s, %s) where defaultedflag is True"
+ recovery = query_db(sqlstr, params = (defaultrecovery, dealname, workdate))
+
+ try:
+ recovery = recovery[0]
+ except TypeError:
+ recovery = defaultrecovery
+
+ if not recovery:
+ recovery = defaultrecovery
+ return float(recovery)
+
+def get_reinvenddate(dealname):
+ sqlstr = 'SELECT reinv_end_date from deal_indicative where dealname=%s'
+ reinvenddate = query_db(sqlstr, params = (dealname,))[0]
+ if reinvenddate:
+ reinvenddate = reinvenddate.strftime("%Y%m%d")
+ return reinvenddate
+ else:
+ raise Exception("missing reinvestment end date")
+
+def generate_scenarios(workdate, dealname):
+ prometheus = os.path.join(root, "Scenarios", "prometheus.sss")
+ n_scenarios = 100
+ basedir = os.path.join(root, "Scenarios", "Intex curves_" + workdate)
+ defaultedprice = get_recovery(dealname, workdate)
+ replace = "\g<a>{0:.3f}".format(defaultedprice)
+ try:
+ with open(os.path.join(basedir, "csv", dealname + ".config")) as fh:
+ config = yaml.load(fh)
+ except IOError:
+ print("{0}: config file doesn't exist".format(dealname))
+ return
+ reinvflag = config['reinvflag']
+ if reinvflag:
+ reinvenddate = get_reinvenddate(dealname)
+ reinv_assets = get_reinv_assets(dealname, workdate)
+ n_float_assets = len([v for v in reinv_assets.values() if v == 'FLOAT'])
+ n_fixed_assets = len([v for v in reinv_assets.values() if v == 'FIXED'])
+ rollingmat = config['rollingmat']
+ if n_fixed_assets == 0:
+ reinvfixedpercentage = 0
+ else:
+ reinvfixedpercentage = global_reinvfixedpercentage / n_fixed_assets
+ if n_float_assets > 0:
+ reinvfloatpercentage = (100 - n_fixed_assets * reinvfixedpercentage)/n_float_assets
+
+ try:
+ with open(os.path.join(basedir, "csv", dealname + "-reinvprices.csv"), "r") as fh:
+ dr = csv.DictReader(fh)
+ reinvprices = {f: [] for f in dr.fieldnames}
+ for line in dr:
+ for f in dr.fieldnames:
+ reinvprices[f].append("{0:.3f}".format(float(line[f])))
+ except IOError:
+ reinvflag = False
+
+ sssfile = os.path.join(basedir, "sss", dealname + ".sss")
+ if not os.path.exists(os.path.join(basedir, "sss")):
+ os.makedirs(os.path.join(basedir, "sss"))
+ cdrscenarios = os.path.join(basedir, "csv", dealname + "-cdr.csv")
+ recoveryscenarios = os.path.join(basedir, "csv", dealname + "-recovery.csv")
+ fhsss = open(sssfile, "w")
+ fhcdr = open(cdrscenarios, "r")
+ fhrecovery = open(recoveryscenarios, "r")
+ csvcdr = reader(fhcdr)
+ csvrecovery = reader(fhrecovery)
+ cdrline = next(csvcdr)
+ cdrline = "\t".join(["{0:.3f}".format(float(cdr)) for cdr in cdrline])
+ recoveryline = next(csvrecovery)
+ recoveryline = "\t".join(["{0:.3f}".format(float(recovery)) for recovery in recoveryline])
+
+ i=1
+ with open(prometheus) as fh:
+ for line in fh:
+ line = line.rstrip()
+
+ if "DEAL_NAME" in line:
+ newline = "DEAL_NAME=" + dealname.upper() + "\r\n"
+ fhsss.write(newline)
+ continue
+ if not reinvflag and pattern8.match(line):
+ line = re.sub(pattern8, r"\1{0}\2=0".format(dealname.upper()), line)
+ fhsss.write(line + "\r\n")
+ continue
+ if not reinvflag and "DO_REINV" in line:
+ fhsss.write("DO_REINV=0" + "\r\n")
+ continue
+ m = pattern1.match(line)
+ if reinvflag and m:
+ reinv_number, scen_number = m.groups()
+ key = "REINV_TBA" + reinv_number
+ if key in reinv_assets:
+ if reinv_assets[key] == "FLOAT":
+ coupon = 4
+ elif reinv_assets[key] == "FIXED":
+ coupon = 7
+ line = "REINVEST[{0}::REINV_TBA{1}][DEAL,{2}]=".format(dealname.upper(),
+ reinv_number,
+ scen_number)
+ line += "COUP_SPR={0}|AMORT=Bullet|USE_REINVEST_PIP=1|MAT_DATE={1}|".format(coupon,
+ rollingmat)
+ fhsss.write(line + "\r\n")
+ continue
+ if reinvflag and pattern2.match(line):
+ line = re.sub(pattern2, r"\1{0}\2{1}", line).format(dealname.upper(), reinvenddate)
+ fhsss.write(line + "\r\n")
+ continue
+ m = pattern3.match(line)
+ if reinvflag and m:
+ reinv_number, scen_number = m.groups()
+ if dealname=="litpt3" and reinv_number=="1":
+ line = "STANDARD_VAR[LITPT3::#REINVLOANP100,{0}]".format(scen_number) + \
+ "={0}".format(" ".join(reinvprices["REINV_TBA1"]))
+ fhsss.write(line + "\r\n")
+ continue
+ reinv_name = "REINV_TBA" + reinv_number
+ if reinv_name in reinvprices:
+ line = \
+ "STANDARD_VAR[{0}::#PRICE100_TBA{1},{2}]={3}".format(dealname.upper(),
+ reinv_number,
+ scen_number,
+ " ".join(reinvprices[reinv_name]))
+ fhsss.write(line + "\r\n")
+ continue
+ m = pattern5.match(line)
+ if reinvflag and m:
+ reinv_number, scen_number = m.groups()
+ reinv_name = "REINV_TBA" + reinv_number
+ if reinv_number=="1":
+ if dealname=="litpt3":
+ line = "STANDARD_VAR[LITPT3::#LOANREINVPCT,{0}]=100".format(scen_number)
+ fhsss.write(line + "\r\n")
+ continue
+ if dealname=="flags4":
+ line = "STANDARD_VAR[FLAGS4::#PCT100_TBA1,{0}]=100".format(scen_number)
+ fhsss.write(line + "\r\n")
+ continue
+ if reinv_name in reinv_assets:
+ if reinv_assets[reinv_name] == 'FIXED':
+ line = "STANDARD_VAR[{0}::#REINVPCT_TBA{1},{2}]={3}".format(dealname.upper(),
+ reinv_number,
+ scen_number,
+ reinvfixedpercentage)
+ elif reinv_assets[reinv_name] == 'FLOAT':
+ line = "STANDARD_VAR[{0}::#REINVPCT_TBA{1},{2}]={3}".format(dealname.upper(),
+ reinv_number,
+ scen_number,
+ reinvfloatpercentage)
+
+ fhsss.write(line + "\r\n")
+ continue
+ if pattern7.search(line):
+ line = re.sub(pattern7, dealname.upper(), line)
+ fhsss.write(line + "\r\n")
+ continue
+ if "LOSS_RATE[DEAL,{0}]".format(i) in line:
+ newcdrline = "LOSS_RATE[DEAL,{0}]=".format(i) + cdrline
+ fhsss.write(newcdrline + "\r\n")
+ continue
+ if "LOSS_SEVERITY[DEAL,{0}]".format(i) in line:
+ newrecoveryline = "LOSS_SEVERITY[DEAL,{0}]=".format(i) + recoveryline
+ fhsss.write(newrecoveryline + "\r\n")
+ i = i + 1
+ if i <= n_scenarios:
+ cdrline = next(csvcdr)
+ cdrline = "\t".join(["{0:.3f}".format(float(cdr)) for cdr in cdrline]) + "\r\n"
+ recoveryline = next(csvrecovery)
+ recoveryline = "\t".join(["{0:.3f}".format(float(recovery)) \
+ for recovery in recoveryline]) + "\r\n"
+ continue
+ if "LOSS_NONPERF_SEVERITY" in line:
+ line = re.sub(pattern9, replace, line)
+ fhsss.write(line + "\r\n")
+ fhsss.close()
+ fhrecovery.close()
+ fhcdr.close()
+ print("generated scenarios for: {0}".format(dealname))
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1:
+ workdate = sys.argv[1]
+ else:
+ workdate = str(datetime.date.today())
+ if len(sys.argv) > 2:
+ dealnames = sys.argv[2:]
+ else:
+ dealnames = [d.split(".")[0] for d in
+ os.listdir(os.path.join(root, "Scenarios",
+ "Intex curves_" + workdate, "csv"))
+ if "RData" in d]
+ for dealname in dealnames:
+ generate_scenarios(workdate, dealname)
diff --git a/python/intex/load_indicative.py b/python/intex/load_indicative.py new file mode 100644 index 00000000..8fd75b6e --- /dev/null +++ b/python/intex/load_indicative.py @@ -0,0 +1,187 @@ +import psycopg2 +import os +import datetime +from datetime import date +import csv, sys, re +import pdb +from common import root, sanitize_float +from db import conn +import logging + +def convertToNone(s): + return None if s in ["", "-", "NR"] else s + +def upload_cusip_data(conn, filename): + dealupdate = {} + with open( filename, "r") as fh: + dr = csv.DictReader(fh, dialect='excel-tab') + data = [] + deals_to_update = [] + + for line in dr: + if "ISIN" not in line: + line['ISIN'] = None + sp = line["Tranche"].split(",") + if len(sp)==2: + line["dealname"], line["tranche"] = sp + else: + continue + line["dealname"] = line["dealname"].lower() + dealname = line['dealname'] + line = {k: convertToNone(v) for k, v in line.items()} + if dealname not in dealupdate: + with conn.cursor() as c: + c.execute("SELECT \"Latest Update\" FROM clo_universe " \ + "WHERE dealname = %s ORDER BY \"Latest Update\" DESC", (dealname,)) + dealupdate[dealname] = c.fetchone()[0] + + sqlstring = "SELECT updatedate FROM latest_cusip_universe WHERE cusip = %s" + with conn.cursor() as c: + c.execute(sqlstring, (line['CUSIP'],)) + curr_date = c.fetchone() + conn.commit() + if not curr_date or curr_date[0] < dealupdate[dealname]: + if dealname not in deals_to_update: + deals_to_update.append(dealname) + line['updatedate'] = dealupdate[dealname] + try: + for key in ['Curr Balance', 'Orig Balance', 'Orig Attachment Point', + 'Curr Attachment Point (def at MV)', 'Orig Detachment Point', + 'Curr Detachment Point (def at MV)', 'Factor', 'Coupon', + 'Floater Spread/Margin']: + if line[key]: + line[key] = sanitize_float(line[key]) + line[key] = convertToNone(line[key]) + except ValueError: + continue + line['Curr Attachment Point'] = line['Curr Attachment Point (def at MV)'] + line['Curr Detachment Point'] = line['Curr Detachment Point (def at MV)'] + if "Curr Moody" not in line: + if 'Orig Moody' in line: + line['Curr Moody'] = line['Orig Moody'] + else: + line['Curr Moody'] = None + line['Orig Moody'] = None + sqlstring = "INSERT INTO cusip_universe(Cusip, ISIN, \"Bloomberg Ticker\", dealname, tranche, " \ + "Coupon, Orig_Balance, Curr_Balance, Factor, Orig_Moody, Curr_Moody, " \ + "Orig_Attach, Orig_Detach, Curr_Attach, Curr_Detach, Floater_Index, " \ + "Spread, updatedate) " \ + "VALUES(%(CUSIP)s, %(ISIN)s, %(Bloomberg Ticker)s, %(dealname)s, %(tranche)s, %(Coupon)s, " \ + "%(Orig Balance)s, %(Curr Balance)s, %(Factor)s, %(Orig Moody)s, %(Curr Moody)s, " \ + "%(Orig Attachment Point)s, %(Orig Detachment Point)s, "\ + "%(Curr Attachment Point)s, %(Curr Detachment Point)s, " \ + "%(Floater Index)s, %(Floater Spread/Margin)s, %(updatedate)s)" + try: + with conn.cursor() as c: + c.execute(sqlstring, line) + except psycopg2.DataError as e: + logging.error(e) + logging.debug("uploaded: {0}".format(line['CUSIP'])) + conn.commit() + # for dealname in deals_to_update: + # with conn.cursor() as c: + # c.execute("SELECT p_cusip, p_curr_subordination, "\ + # "p_curr_thickness from et_deal_subordination(%s)", + # (dealname,)) + # data = [ (t[1], t[2], t[0], dealupdate[dealname]) for t in c] + # c.executemany("UPDATE cusip_universe SET subordination = %s, " + # "thickness = %s WHERE cusip = %s AND " + # "updatedate = %s", data) + # conn.commit() + +def upload_deal_data(conn, filename): + sqlstr = "select dealname, array_agg(\"Latest Update\") from clo_universe group by dealname" + with conn.cursor() as c: + c.execute(sqlstr) + deallist1 = dict(c) + sqlstr = "select dealname from deal_indicative" + with conn.cursor() as c: + c.execute(sqlstr) + deallist2 = [d[0] for d in c] + conn.commit() + with open( filename, "r") as fh: + dr = csv.DictReader(fh, dialect='excel-tab') + data = [] + for line in dr: + if not line['Deal Name, Tranche Name'] or (line['Deal Name, Tranche Name'] == 'Unknown Security'): + continue + if not line['Latest Update']: + continue + for key in line.keys(): + line[key] = convertToNone(line[key]) + line["CDOpercent"] = line["CDO Pct of Assets that are Structured Finance Obligations"] + line["Paid Down"] = None + if "Paid Down" in line["Latest Update"]: + line["Paid Down"] = re.sub("Paid Down: ","", line["Latest Update"]) + line["Latest Update"] = line["Paid Down"] + for field in ["Deal Issue Date", "Deal Termination Date", "Reinv End Date", \ + "Latest Update", "Pay Day", "Deal First Pay Date", "Paid Down"]: + if line[field]: + try: + line[field] = datetime.datetime.strptime(line[field], '%b %d, %Y').date() + except ValueError: + pdb.set_trace() + if line["Pay Day"]: + line["Pay Day"] = line["Pay Day"].day + for key in ["Collection Account Principal Balance", "Collection Account Interest Balance", + "Curr Deal Bal", "Tranche Curr Bal", + "CDO Pct of Assets that are Structured Finance Obligations", + "CDO Defaulted Security Balance (Reported)"]: + if line[key]: + line[key] = sanitize_float(line[key]) + line['Deal/Tranche ID'] = line['Deal/Tranche ID'].lower() + dealname = line['Deal/Tranche ID'] + line['defaultedbal'] = line["CDO Defaulted Security Balance (Reported)"] + if dealname not in deallist2: + for key in ["Orig Deal Bal", "Tranche Orig Bal"]: + if line[key]: + line[key] = sanitize_float(line[key]) + if line['Deal CUSIP List']: + line['Deal CUSIP List'] = line['Deal CUSIP List'].split(",") + sqlstr = "INSERT INTO deal_indicative VALUES( %(Deal/Tranche ID)s, %(Deal Name)s, " \ + "%(Collateral Manager)s, %(Deal Issue Date)s, %(Deal Termination Date)s, " \ + "%(Pay Day)s, %(Reinv End Date)s, %(Deal First Pay Date)s, %(Orig Deal Bal)s, " \ + "%(Tranche Orig Bal)s, %(Deal CUSIP List)s, %(Paid Down)s)" + try: + with conn.cursor() as c: + c.execute(sqlstr, line) + except (psycopg2.DataError, KeyError) as detail: + logging.error(detail) + pdb.set_trace() + with conn.cursor() as c: + if line['Paid Down']: + c.execute("UPDATE deal_indicative SET paid_down=%s WHERE dealname=%s", + (line['Paid Down'], dealname)) + if dealname not in deallist1 or line['Latest Update'] not in deallist1[dealname]: + sqlstring = \ + "INSERT INTO clo_universe " \ + "VALUES (%(Deal/Tranche ID)s, %(Curr Deal Bal)s, %(Tranche Curr Bal)s, " \ + "%(Tranche Factor)s, %(Collection Account Principal Balance)s, " \ + "%(Collection Account Interest Balance)s, %(CDOpercent)s, %(defaultedbal)s, " \ + "%(Coupon)s, %(Latest Update)s)" + try: + with conn.cursor() as c: + c.execute(sqlstring, line) + deallist1[dealname] = [line['Latest Update']] + except (psycopg2.DataError, KeyError) as detail: + logging.error(detail) + pdb.set_trace() + conn.commit() + +if __name__=="__main__": + if len(sys.argv) > 1: + workdate = sys.argv[1] + else: + workdate = str(datetime.date.today()) + files = [os.path.join(root, "data", "Indicative_" + workdate, f) for f in + os.listdir(os.path.join(root, "data", "Indicative_" + workdate))] + cusip_files = [f for f in files if "TrInfo" in f] + deal_files = [f for f in files if "TrInfo" not in f] + + #first load deal data + for deal in deal_files: + upload_deal_data(conn, deal) + #then load tranche data + for cusip in cusip_files: + upload_cusip_data(conn, cusip) + conn.close() diff --git a/python/intex/load_intex_collateral.py b/python/intex/load_intex_collateral.py new file mode 100644 index 00000000..1b0a7c45 --- /dev/null +++ b/python/intex/load_intex_collateral.py @@ -0,0 +1,149 @@ +import psycopg2 +import os, csv, datetime +import pdb +from common import root, sanitize_float +from db import conn +import sys +import uuid +from load_indicative import upload_cusip_data, upload_deal_data +import logging + +fields = ['Asset Name', 'Issuer', 'Contributed Balance', 'Asset Maturity Date', + 'Asset Subtype', 'Asset Type', 'Gross Coupon', 'Spread', \ + 'Frequency', 'Next Paydate', 'Second Lien', 'LoanX ID', 'CUSIP', + 'Market Price', 'Market Price Source', 'Market Price Date', 'Fixed or Float', \ + 'Defaulted Flag', 'Security Sub-Category', 'Structured Finance Security', \ + 'Life Floor', 'Reinvest Collat', 'Native Currency', "Moody's Industry Name", + "Country"] + +def convertToNone(s): + return None if s=='' else s + +def windows1252_encoder(fh): + for line in fh: + yield line.decode('windows-1252').encode('utf-8') + +def upload_data(conn, dealnames, workdate): + for dealname in dealnames: + basedir = os.path.join(root, "data", "Collaterals_" + workdate) + if sys.version_info[0]==2: + fh = open(os.path.join(basedir, dealname.upper() + "_AD.txt")) + fh = windows1252_encoder(fh) + else: + fh = open(os.path.join(basedir, dealname.upper() + "_AD.txt"), encoding="windows-1252") + + dr = csv.DictReader(fh, dialect = 'excel-tab') + missingfields = set(fields).union({'Gross Margin'}) - set(dr.fieldnames) + if "LoanX ID" in missingfields: + msg = "{0}: LoanX ID column is missing. Probably an error in exporting from intex" + logging.warning(msg.format(dealname)) + data = {} + for line in dr: + for f in missingfields: + line[f] = None + for key in ['LoanX ID', 'CUSIP', 'Fixed or Float']: + if line[key]: + line[key] = line[key].upper() + if line['Asset Subtype']: + line['Asset Subtype'] = line['Asset Subtype'].replace("Reinvest ", "").replace("Reinv ","") + for key, l in [('LoanX ID', 8), ('CUSIP', 9), ('Asset Subtype', 10)]: + if line[key]: + if len(line[key]) > l: + logging.warning("dubious {0} found: {1}".format(key, line[key])) + line[key] = line[key][:l] + + if 'Reinvest Collat' in line and line['Reinvest Collat'].upper() == 'Y': + # assume it's a reinvestment asset + line['Reinvest Collat'] = True + line['Issuer'] = line['ID Number'] + if not line['Spread']: + line['Spread'] = line['Gross Margin'] + + for field in ['Spread', 'Gross Coupon', 'Market Price', 'Contributed Balance']: + line[field] = sanitize_float(line[field]) + if line['Market Price'] == 0: + line['Market Price'] = None + #we store the Libor Floor in the database, so Life Floor is really Libor Floor + if line['Life Floor'] == "No limit": + line['Life Floor'] = 0 + elif line['Life Floor']: + try: + line['Life Floor'] = float(line['Life Floor']) - float(line['Spread']) + except ValueError: + line['Life Floor'] = float('Nan') + + # we take care of reinvestment asset lines + if not line['Asset Name']: + line['Asset Name'] = 'Reinv' + r = [convertToNone(line[field]) for field in fields] + #sometimes the Asset Name is not unique (we add random tag in this case) + if r[0] in data: + r[0] = r[0] + str(uuid.uuid4())[:3] + data[r[0]] = r[1:] + fh.close() + sqlstr1 = "select distinct(updatedate) from et_collateral where dealname= %s" + sqlstr2 = "select max(\"Latest Update\") from clo_universe where dealname= %s and \"Latest Update\"<=%s" + with conn.cursor() as c: + c.execute(sqlstr1, (dealname,)) + old_update_dates = [date[0] for date in c] + c.execute(sqlstr2, (dealname, workdate)) + updatedate = c.fetchone()[0] + conn.commit() + # sanity check if we already have the data + reinsert = False + if updatedate in old_update_dates: + sqlstr = "SELECT count(*) FROM et_collateral where dealname = %s and updatedate= %s" + with conn.cursor() as c: + c.execute(sqlstr, (dealname, updatedate)) + currlen = c.fetchone()[0] + conn.commit() + if currlen != len(data): #then we delete and just reupload + logging.warning("{0} has {1} rows in the database " \ + "and current collateral file has {2}".format(dealname, currlen, len(data))) + with conn.cursor() as c: + sqlstr = "DELETE FROM et_collateral where dealname = %s and updatedate = %s" + c.execute(sqlstr, (dealname, updatedate)) + conn.commit() + reinsert = True + + if reinsert or not old_update_dates or updatedate not in old_update_dates: + sql_fields = ["dealname", "updatedate", "name", "IssuerName", "CurrentBalance", + "Maturity", "AssetSubtype", "AssetType", "GrossCoupon", + "Spread", "Frequency", "NextPaydate", "SecondLien", "LoanXID", + "Cusip", "IntexPrice", "IntexPriceSource", "IntexPriceDate", + "FixedOrFloat", "DefaultedFlag", "CovLite", "isCDO", + "Liborfloor", "ReinvFlag", "Currency", "Industry", "Country"] + sqlstr = "INSERT INTO ET_COLLATERAL({0}) VALUES({1})".format(",".join(sql_fields), + ",".join(["%s"] * len(sql_fields))) + with conn.cursor() as c: + try: + c.executemany(sqlstr, [(dealname, updatedate, k) + tuple(v) for k, v in data.items()]) + except (psycopg2.DataError, psycopg2.IntegrityError, TypeError) as detail: + logging.error(detail) + pdb.set_trace() + conn.commit() + +def intex_data(conn, workdate): + dealnames = [d.replace("_AD.txt", "").lower() for d in + os.listdir(os.path.join(root, "data", "Collaterals_" + workdate))] + basedir = os.path.join(root, "data", "Indicative_" + workdate) + files = [os.path.join(basedir, f) for f in os.listdir(basedir)] + cusip_files = [f for f in files if "TrInfo" in f] + deal_files = [f for f in files if "TrInfo" not in f] + #first load deal data + for deal_file in deal_files: + upload_deal_data(conn, deal_file) + #then load tranche data + for cusip_file in cusip_files: + upload_cusip_data(conn, cusip_file) + + upload_data(conn, dealnames, workdate) + +if __name__ == "__main__": + if len(sys.argv) > 1: + workdate = sys.argv[1] + else: + workdate = str(datetime.date.today()) + intex_data(conn, workdate) + conn.close() + print("done") |
