aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/intex/__init__.py1
-rw-r--r--python/intex/__main__.py5
-rw-r--r--python/intex/common.py5
-rw-r--r--python/intex/intex_scenarios.py148
-rw-r--r--python/intex/load_indicative.py205
-rw-r--r--python/intex/load_intex_collateral.py186
6 files changed, 373 insertions, 177 deletions
diff --git a/python/intex/__init__.py b/python/intex/__init__.py
index 889702f8..168432ea 100644
--- a/python/intex/__init__.py
+++ b/python/intex/__init__.py
@@ -1,3 +1,4 @@
import sys
+
sys.path.append("..")
from utils.db import dbconn
diff --git a/python/intex/__main__.py b/python/intex/__main__.py
index ffbaee36..ddc677d7 100644
--- a/python/intex/__main__.py
+++ b/python/intex/__main__.py
@@ -2,13 +2,14 @@ import sys
import datetime
from .load_intex_collateral import intex_data
import logging
-logger = logging.getLogger('intex')
+
+logger = logging.getLogger("intex")
logger.addHandler(logging.StreamHandler())
if len(sys.argv) > 1:
workdate = sys.argv[1]
else:
workdate = str(datetime.date.today())
-with dbconn('etdb') as etdb:
+with dbconn("etdb") as etdb:
intex_data(etdb, workdate)
print("done")
diff --git a/python/intex/common.py b/python/intex/common.py
index d93f9c18..65bae4a0 100644
--- a/python/intex/common.py
+++ b/python/intex/common.py
@@ -1,12 +1,13 @@
import os
+
def sanitize_float(intex_float):
try:
intex_float = intex_float.replace(",", "")
- if " " in intex_float: #case of combo notes
+ if " " in intex_float: # case of combo notes
return float(intex_float.split(" ")[0])
if "(" in intex_float:
- return - float(intex_float[1:-1])
+ return -float(intex_float[1:-1])
else:
return float(intex_float)
except (AttributeError, ValueError):
diff --git a/python/intex/intex_scenarios.py b/python/intex/intex_scenarios.py
index 75da23a6..79b50639 100644
--- a/python/intex/intex_scenarios.py
+++ b/python/intex/intex_scenarios.py
@@ -27,8 +27,9 @@ pattern9 = re.compile("(?P<a>SEVERITY\[\w+,\d+\]=)mkt\(70\)")
global_reinvfloatpercentage = 84
global_reinvfixedpercentage = 16
+
def get_reinv_assets(conn, dealname, workdate):
- sqlstr = 'SELECT * FROM et_historicaldealinfo(%s, %s) WHERE ReinvFlag IS TRUE'
+ sqlstr = "SELECT * FROM et_historicaldealinfo(%s, %s) WHERE ReinvFlag IS TRUE"
d = {}
with conn.cursor() as c:
c.execute(sqlstr, (dealname, workdate))
@@ -37,10 +38,13 @@ def get_reinv_assets(conn, dealname, workdate):
conn.commit()
return d
+
def get_recovery(conn, dealname, workdate, defaultrecovery=50):
""" compute average price of defaulted assets """
- sqlstr = ("select sum(coalesce(price, %s) * currentbalance)/sum(currentbalance) AS recov "
- "from et_aggdealinfo_historical(%s, %s) where defaultedflag is True")
+ sqlstr = (
+ "select sum(coalesce(price, %s) * currentbalance)/sum(currentbalance) AS recov "
+ "from et_aggdealinfo_historical(%s, %s) where defaultedflag is True"
+ )
with conn.cursor() as c:
try:
c.execute(sqlstr, (defaultrecovery, dealname, workdate))
@@ -53,8 +57,9 @@ def get_recovery(conn, dealname, workdate, defaultrecovery=50):
conn.commit()
return float(recovery)
+
def get_reinvenddate(conn, dealname, workdate):
- sqlstr = 'SELECT reinv_end_date FROM historical_clo_universe(%s, %s)'
+ sqlstr = "SELECT reinv_end_date FROM historical_clo_universe(%s, %s)"
with conn.cursor() as c:
c.execute(sqlstr, (dealname, workdate))
reinvenddate, = c.fetchone()
@@ -64,10 +69,13 @@ def get_reinvenddate(conn, dealname, workdate):
else:
raise Exception("missing reinvestment end date")
+
def generate_scenarios(workdate, dealname, conn):
- prometheus = os.path.join(os.environ['BASE_DIR'], "Scenarios", "prometheus.sss")
+ prometheus = os.path.join(os.environ["BASE_DIR"], "Scenarios", "prometheus.sss")
n_scenarios = 100
- basedir = os.path.join(os.environ['BASE_DIR'], "Scenarios", "Intex curves_" + workdate)
+ basedir = os.path.join(
+ os.environ["BASE_DIR"], "Scenarios", "Intex curves_" + workdate
+ )
defaultedprice = get_recovery(conn, dealname, workdate)
replace = "\g<a>{0:.3f}".format(defaultedprice)
try:
@@ -76,22 +84,26 @@ def generate_scenarios(workdate, dealname, conn):
except IOError:
logger.error("{0}: config file doesn't exist".format(dealname))
return
- reinvflag = config['reinvflag']
+ reinvflag = config["reinvflag"]
if reinvflag:
reinvenddate = get_reinvenddate(conn, dealname, workdate)
reinv_assets = get_reinv_assets(conn, dealname, workdate)
- n_float_assets = len([v for v in reinv_assets.values() if v[0] == 'FLOAT'])
- n_fixed_assets = len([v for v in reinv_assets.values() if v[0] == 'FIXED'])
- rollingmat = config['rollingmat']
+ n_float_assets = len([v for v in reinv_assets.values() if v[0] == "FLOAT"])
+ n_fixed_assets = len([v for v in reinv_assets.values() if v[0] == "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
+ reinvfloatpercentage = (
+ 100 - n_fixed_assets * reinvfixedpercentage
+ ) / n_float_assets
try:
- with open(os.path.join(basedir, "csv", dealname + "-reinvprices.csv"), "r") as fh:
+ 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:
@@ -99,7 +111,9 @@ def generate_scenarios(workdate, dealname, conn):
try:
val = float(line[f])
except ValueError:
- logger.error("Incorrect value in reinvprices for {}".format(dealname))
+ logger.error(
+ "Incorrect value in reinvprices for {}".format(dealname)
+ )
else:
reinvprices[f].append("{0:.3f}".format(val))
@@ -119,15 +133,17 @@ def generate_scenarios(workdate, dealname, conn):
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])
+ recoveryline = "\t".join(
+ ["{0:.3f}".format(float(recovery)) for recovery in recoveryline]
+ )
- i=1
+ 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"
+ newline = "DEAL_NAME=" + dealname.upper() + "\r\n"
fhsss.write(newline)
continue
if not reinvflag and pattern8.match(line):
@@ -147,33 +163,39 @@ def generate_scenarios(workdate, dealname, conn):
coupon = 4
elif fixedorfloat == "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)
+ 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
+ )
if liborfloor is not None:
line += "|ARM_LIFE_FLOOR={}".format(liborfloor)
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)
+ 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"]))
+ 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]))
+ 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)
@@ -182,24 +204,32 @@ def generate_scenarios(workdate, dealname, conn):
reinv_name = "REINV_TBA" + reinv_number
if reinv_number == "1":
if dealname == "litpt3":
- line = "STANDARD_VAR[LITPT3::#LOANREINVPCT,{0}]=100".format(scen_number)
+ 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)
+ 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][0] == 'FIXED':
- line = "STANDARD_VAR[{0}::#REINVPCT_TBA{1},{2}]={3}".format(dealname.upper(),
- reinv_number,
- scen_number,
- reinvfixedpercentage)
- elif reinv_assets[reinv_name][0] == 'FLOAT':
- line = "STANDARD_VAR[{0}::#REINVPCT_TBA{1},{2}]={3}".format(dealname.upper(),
- reinv_number,
- scen_number,
- reinvfloatpercentage)
+ if reinv_assets[reinv_name][0] == "FIXED":
+ line = "STANDARD_VAR[{0}::#REINVPCT_TBA{1},{2}]={3}".format(
+ dealname.upper(),
+ reinv_number,
+ scen_number,
+ reinvfixedpercentage,
+ )
+ elif reinv_assets[reinv_name][0] == "FLOAT":
+ line = "STANDARD_VAR[{0}::#REINVPCT_TBA{1},{2}]={3}".format(
+ dealname.upper(),
+ reinv_number,
+ scen_number,
+ reinvfloatpercentage,
+ )
fhsss.write(line + "\r\n")
continue
@@ -217,10 +247,20 @@ def generate_scenarios(workdate, dealname, conn):
i = i + 1
if i <= n_scenarios:
cdrline = next(csvcdr)
- cdrline = "\t".join(["{0:.3f}".format(float(cdr)) for cdr in cdrline]) + "\r\n"
+ 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"
+ 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)
@@ -230,9 +270,11 @@ def generate_scenarios(workdate, dealname, conn):
fhcdr.close()
logger.info("generated scenarios for: {0}".format(dealname))
+
if __name__ == "__main__":
sys.path.append(".")
from utils.db import dbconn
+
if len(sys.argv) > 1:
workdate = sys.argv[1]
else:
@@ -240,11 +282,19 @@ if __name__ == "__main__":
if len(sys.argv) > 2:
dealnames = sys.argv[2:]
else:
- dealnames = [d.split(".")[0] for d in
- os.listdir(os.path.join(os.environ['BASE_DIR'], "Scenarios",
- "Intex curves_" + workdate, "csv"))
- if "RData" in d]
- ET = dbconn('etdb')
+ dealnames = [
+ d.split(".")[0]
+ for d in os.listdir(
+ os.path.join(
+ os.environ["BASE_DIR"],
+ "Scenarios",
+ "Intex curves_" + workdate,
+ "csv",
+ )
+ )
+ if "RData" in d
+ ]
+ ET = dbconn("etdb")
for dealname in dealnames:
generate_scenarios(workdate, dealname, ET)
ET.close()
diff --git a/python/intex/load_indicative.py b/python/intex/load_indicative.py
index 4e6c05c5..53124801 100644
--- a/python/intex/load_indicative.py
+++ b/python/intex/load_indicative.py
@@ -12,28 +12,46 @@ import sys
logger = logging.getLogger(__name__)
+
def convertToNone(s):
return None if s in ["", "-", "NR"] else s
def insert_new_cusip(conn, line):
- if line['Pari-Passu Tranches']:
- line['Pari-Passu Tranches'] = line['Pari-Passu Tranches'].split(",")
- to_insert = (line['CUSIP'], line['ISIN'], line['Bloomberg Ticker'],
- line['dealname'], line['tranche'], line['Pari-Passu Tranches'])
- for key in ['Orig Balance', 'Orig Attachment Point', 'Orig Detachment Point',
- 'Floater Spread/Margin']:
+ if line["Pari-Passu Tranches"]:
+ line["Pari-Passu Tranches"] = line["Pari-Passu Tranches"].split(",")
+ to_insert = (
+ line["CUSIP"],
+ line["ISIN"],
+ line["Bloomberg Ticker"],
+ line["dealname"],
+ line["tranche"],
+ line["Pari-Passu Tranches"],
+ )
+ for key in [
+ "Orig Balance",
+ "Orig Attachment Point",
+ "Orig Detachment Point",
+ "Floater Spread/Margin",
+ ]:
if line[key]:
line[key] = sanitize_float(line[key])
line[key] = convertToNone(line[key])
- to_insert += (line['Orig Balance'], line.get('Orig Moody'),
- line['Orig Attachment Point'], line['Orig Detachment Point'],
- line['Floater Index'], line['Floater Spread/Margin'],
- line['Type'])
- sqlstr = ("INSERT INTO cusip_ref(Cusip, ISIN, bloomberg_ticker, dealname, "
- "tranche, paripassu_tranches, Orig_Balance, Orig_Moody, Orig_Attach, "
- "Orig_Detach, Floater_Index, Spread, type) VALUES({0}) "
- "RETURNING cusip_id".format(",".join(["%s"] * 13)))
+ to_insert += (
+ line["Orig Balance"],
+ line.get("Orig Moody"),
+ line["Orig Attachment Point"],
+ line["Orig Detachment Point"],
+ line["Floater Index"],
+ line["Floater Spread/Margin"],
+ line["Type"],
+ )
+ sqlstr = (
+ "INSERT INTO cusip_ref(Cusip, ISIN, bloomberg_ticker, dealname, "
+ "tranche, paripassu_tranches, Orig_Balance, Orig_Moody, Orig_Attach, "
+ "Orig_Detach, Floater_Index, Spread, type) VALUES({0}) "
+ "RETURNING cusip_id".format(",".join(["%s"] * 13))
+ )
with conn.cursor() as c:
try:
c.execute(sqlstr, to_insert)
@@ -46,34 +64,37 @@ def insert_new_cusip(conn, line):
def upload_cusip_data(conn, filename):
dealupdate = {}
- with open( filename, "r") as fh:
- dr = csv.DictReader(fh, dialect='excel-tab')
+ 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
+ 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']
+ 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 max(\"Latest Update\") FROM clo_universe "
- "WHERE dealname = %s", (dealname,))
+ c.execute(
+ 'SELECT max("Latest Update") FROM clo_universe '
+ "WHERE dealname = %s",
+ (dealname,),
+ )
try:
dealupdate[dealname], = c.fetchone()
except TypeError:
- logging.error(f'deal:{dealname} not in database')
+ logging.error(f"deal:{dealname} not in database")
continue
sqlstring = "SELECT cusip_id FROM cusip_ref WHERE cusip=%s and dealname=%s"
with conn.cursor() as c:
- c.execute(sqlstring, (line['CUSIP'], dealname))
+ c.execute(sqlstring, (line["CUSIP"], dealname))
r = c.fetchone()
if r is None:
try:
@@ -88,26 +109,41 @@ def upload_cusip_data(conn, filename):
curr_date, = c.fetchone()
if curr_date is None or curr_date < dealupdate[dealname]:
try:
- for key in ['Curr Balance', 'Curr Attachment Point (def at MV)',
- 'Curr Detachment Point (def at MV)', 'Factor', 'Coupon']:
+ for key in [
+ "Curr Balance",
+ "Curr Attachment Point (def at MV)",
+ "Curr Detachment Point (def at MV)",
+ "Factor",
+ "Coupon",
+ ]:
if line[key]:
line[key] = sanitize_float(line[key])
line[key] = convertToNone(line[key])
except ValueError:
continue
- line['Curr Moody'] = line.get('Curr Moody') or line.get('Orig Moody')
- sqlstring = "INSERT INTO cusip_update VALUES({0})".format(",".join(["%s"] * 8))
- to_insert = (cusip_id, line['Curr Balance'], line['Factor'], line['Coupon'],
- line['Curr Moody'], line['Curr Attachment Point (def at MV)'],
- line['Curr Detachment Point (def at MV)'], dealupdate[dealname])
+ line["Curr Moody"] = line.get("Curr Moody") or line.get("Orig Moody")
+ sqlstring = "INSERT INTO cusip_update VALUES({0})".format(
+ ",".join(["%s"] * 8)
+ )
+ to_insert = (
+ cusip_id,
+ line["Curr Balance"],
+ line["Factor"],
+ line["Coupon"],
+ line["Curr Moody"],
+ line["Curr Attachment Point (def at MV)"],
+ line["Curr Detachment Point (def at MV)"],
+ dealupdate[dealname],
+ )
with conn.cursor() as c:
try:
c.execute(sqlstring, to_insert)
except (psycopg2.DataError, psycopg2.IntegrityError) as e:
logger.error(e)
- logger.debug("uploaded: {0}".format(line['CUSIP']))
+ logger.debug("uploaded: {0}".format(line["CUSIP"]))
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:
@@ -119,52 +155,76 @@ def upload_deal_data(conn, filename):
deallist2 = set([d for d, in c])
conn.commit()
with open(filename, "r") as fh:
- dr = csv.DictReader(fh, dialect='excel-tab')
+ 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'):
+ if not line["Deal Name, Tranche Name"] or (
+ line["Deal Name, Tranche Name"] == "Unknown Security"
+ ):
continue
- if not line['Latest Update']:
+ if not line["Latest Update"]:
continue
for key in line.keys():
line[key] = convertToNone(line[key])
##simpler names
- line["CDOpercent"] = line["CDO Pct of Assets that are Structured Finance Obligations"]
- line['defaultedbal'] = line["CDO Defaulted Security Balance (Reported)"]
+ line["CDOpercent"] = line[
+ "CDO Pct of Assets that are Structured Finance Obligations"
+ ]
+ line["defaultedbal"] = line["CDO Defaulted Security Balance (Reported)"]
line["Paid Down"] = None
if "Paid Down" in line["Latest Update"]:
- line["Paid Down"] = re.sub("Paid Down: ","", line["Latest Update"])
+ line["Paid Down"] = re.sub("Paid Down: ", "", line["Latest Update"])
line["Latest Update"] = line["Paid Down"]
- for field in ["Deal Closing Date", "Deal Termination Date", "Reinv End Date", \
- "Latest Update", "Pay Day", "Deal First Pay Date", "Paid Down",
- "Deal Last Refi Date"]:
+ for field in [
+ "Deal Closing Date",
+ "Deal Termination Date",
+ "Reinv End Date",
+ "Latest Update",
+ "Pay Day",
+ "Deal First Pay Date",
+ "Paid Down",
+ "Deal Last Refi Date",
+ ]:
if line[field]:
try:
- line[field] = datetime.datetime.strptime(line[field], '%b %d, %Y').date()
+ line[field] = datetime.datetime.strptime(
+ line[field], "%b %d, %Y"
+ ).date()
except ValueError:
logger.error("Can't parse date {}".format(line[field]))
pdb.set_trace()
if line["Pay Day"]:
line["Pay Day"] = line["Pay Day"].day
- for key in ["Principal Collection Account", "Interest Collection Account",
- "Curr Deal Bal", "Tranche Curr Bal", "CDOpercent", "defaultedbal",
- "Orig Deal Bal", "Tranche Orig Bal"]:
+ for key in [
+ "Principal Collection Account",
+ "Interest Collection Account",
+ "Curr Deal Bal",
+ "Tranche Curr Bal",
+ "CDOpercent",
+ "defaultedbal",
+ "Orig Deal Bal",
+ "Tranche Orig Bal",
+ ]:
if line[key]:
line[key] = sanitize_float(line[key])
- line['Deal/Tranche ID'] = line['Deal/Tranche ID'].lower()
- dealname = line['Deal/Tranche ID']
+ line["Deal/Tranche ID"] = line["Deal/Tranche ID"].lower()
+ dealname = line["Deal/Tranche ID"]
if dealname not in deallist2:
- sqlstr = "INSERT INTO deal_indicative VALUES( %(Deal/Tranche ID)s, " \
- "%(Deal Name)s, %(Collateral Manager)s, " \
- "%(Deal Closing Date)s, %(Pay Day)s, " \
- "%(Deal First Pay Date)s, %(Paid Down)s)"
+ sqlstr = (
+ "INSERT INTO deal_indicative VALUES( %(Deal/Tranche ID)s, "
+ "%(Deal Name)s, %(Collateral Manager)s, "
+ "%(Deal Closing Date)s, %(Pay Day)s, "
+ "%(Deal First Pay Date)s, %(Paid Down)s)"
+ )
else:
- #we always update paid_down
- sqlstr = 'UPDATE deal_indicative SET paid_down=%(Paid Down)s ' \
- 'WHERE dealname=%(Deal/Tranche ID)s'
+ # we always update paid_down
+ sqlstr = (
+ "UPDATE deal_indicative SET paid_down=%(Paid Down)s "
+ "WHERE dealname=%(Deal/Tranche ID)s"
+ )
- if line['Deal CUSIP List']:
- line['Deal CUSIP List'] = line['Deal CUSIP List'].split(",")
+ if line["Deal CUSIP List"]:
+ line["Deal CUSIP List"] = line["Deal CUSIP List"].split(",")
try:
with conn.cursor() as c:
c.execute(sqlstr, line)
@@ -175,38 +235,47 @@ def upload_deal_data(conn, filename):
# update deallist2
if dealname not in deallist2:
deallist2.add(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, %(Principal Collection Account)s, " \
- "%(Interest Collection Account)s, %(CDOpercent)s, %(defaultedbal)s, " \
- "%(Coupon)s, %(Latest Update)s, %(Deal Last Refi Date)s, " \
- "%(Deal CUSIP List)s, %(Deal Termination Date)s, %(Reinv End Date)s, " \
+ 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, %(Principal Collection Account)s, "
+ "%(Interest Collection Account)s, %(CDOpercent)s, %(defaultedbal)s, "
+ "%(Coupon)s, %(Latest Update)s, %(Deal Last Refi Date)s, "
+ "%(Deal CUSIP List)s, %(Deal Termination Date)s, %(Reinv End Date)s, "
"%(Orig Deal Bal)s, %(Tranche Orig Bal)s)"
+ )
try:
with conn.cursor() as c:
c.execute(sqlstring, line)
- deallist1[dealname] = [line['Latest Update']]
+ deallist1[dealname] = [line["Latest Update"]]
except (psycopg2.DataError, KeyError) as detail:
logger.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(os.environ['DATA_DIR'], "Indicative_" + workdate, f) for f in
- os.listdir(os.path.join(os.environ['DATA_DIR'], "Indicative_" + workdate))]
+ files = [
+ os.path.join(os.environ["DATA_DIR"], "Indicative_" + workdate, f)
+ for f in os.listdir(
+ os.path.join(os.environ["DATA_DIR"], "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]
- with closing(dbconn('etdb')) as etdb:
- #first load deal data
+ with closing(dbconn("etdb")) as etdb:
+ # first load deal data
for deal in deal_files:
upload_deal_data(etdb, deal)
- #then load tranche data
+ # then load tranche data
for cusip in cusip_files:
upload_cusip_data(etdb, cusip)
diff --git a/python/intex/load_intex_collateral.py b/python/intex/load_intex_collateral.py
index d848887b..9fdfa9d6 100644
--- a/python/intex/load_intex_collateral.py
+++ b/python/intex/load_intex_collateral.py
@@ -11,30 +11,77 @@ import logging
logger = logging.getLogger(__name__)
-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", "Amortization Schedule"]
+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",
+ "Amortization Schedule",
+]
+
def upload_data(conn, workdate):
- 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",
- "amort_schedule_dates", "amort_schedule_amounts"]
- sqlstr = "INSERT INTO ET_COLLATERAL({0}) VALUES({1})".format(",".join(sql_fields),
- ",".join(["%s"] * len(sql_fields)))
- basedir = Path(os.environ['DATA_DIR']) / ("Collaterals_" + workdate)
+ 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",
+ "amort_schedule_dates",
+ "amort_schedule_amounts",
+ ]
+ sqlstr = "INSERT INTO ET_COLLATERAL({0}) VALUES({1})".format(
+ ",".join(sql_fields), ",".join(["%s"] * len(sql_fields))
+ )
+ basedir = Path(os.environ["DATA_DIR"]) / ("Collaterals_" + workdate)
for fname in basedir.iterdir():
fh = open(fname, encoding="windows-1252")
dealname = fname.name.rsplit("_", 1)[0].lower()
- dr = csv.DictReader(fh, dialect='excel-tab')
- missingfields = set(fields).union({'Gross Margin'}) - set(dr.fieldnames)
+ 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"
logger.warning(msg.format(dealname))
@@ -42,70 +89,85 @@ def upload_data(conn, workdate):
for line in dr:
for f in missingfields:
line[f] = None
- for key in ['LoanX ID', 'CUSIP', 'Fixed or Float']:
+ 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 ","")
- if line['Second Lien']:
- line['Second Lien'] = line['Second Lien'].replace("Second Lien", "Y")
- for key, l in [('LoanX ID', 8), ('CUSIP', 9), ('Asset Subtype', 10)]:
+ if line["Asset Subtype"]:
+ line["Asset Subtype"] = (
+ line["Asset Subtype"].replace("Reinvest ", "").replace("Reinv ", "")
+ )
+ if line["Second Lien"]:
+ line["Second Lien"] = line["Second Lien"].replace("Second Lien", "Y")
+ for key, l in [("LoanX ID", 8), ("CUSIP", 9), ("Asset Subtype", 10)]:
if line[key]:
if len(line[key]) > l:
logger.warning("dubious {0} found: {1}".format(key, line[key]))
line[key] = line[key][:l]
- if 'Reinvest Collat' not in missingfields and line['Reinvest Collat'].upper() == 'Y':
+ if (
+ "Reinvest Collat" not in missingfields
+ 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']
+ 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']:
+ 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']:
+ 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'])
+ line["Life Floor"] = float(line["Life Floor"]) - float(
+ line["Spread"]
+ )
except ValueError:
- line['Life Floor'] = float('Nan')
+ line["Life Floor"] = float("Nan")
# we take care of reinvestment asset lines
- if not line['Asset Name']:
- line['Asset Name'] = 'Reinv'
+ if not line["Asset Name"]:
+ line["Asset Name"] = "Reinv"
try:
- line['Asset Maturity Date'] = datetime.datetime.strptime(line['Asset Maturity Date'],
- '%b %d, %Y').date()
+ line["Asset Maturity Date"] = datetime.datetime.strptime(
+ line["Asset Maturity Date"], "%b %d, %Y"
+ ).date()
except (ValueError, TypeError):
- line['Asset Maturity Date'] = None
+ line["Asset Maturity Date"] = None
r = [line[field] or None for field in fields]
if line["Amortization Schedule"]:
temp = line["Amortization Schedule"].split("; ")
temp = [e.split(" @ ") for e in temp]
amounts, dates = zip(*temp)
- if '%' in amounts[0]: #for reinvestment assets amort is in percentage.
+ if "%" in amounts[0]: # for reinvestment assets amort is in percentage.
amounts = [float(e.replace("%", "")) / 100 for e in amounts]
else:
amounts = [float(e.replace(",", "")) for e in amounts]
- dates = [datetime.datetime.strptime(e, "%b %d, %Y").date() for e in dates]
+ dates = [
+ datetime.datetime.strptime(e, "%b %d, %Y").date() for e in dates
+ ]
r[-1] = dates
r.append(amounts)
else:
r.append(None)
- #sometimes the Asset Name is not unique (we add random tag in this case)
+ # 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"
+ 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]
@@ -120,9 +182,13 @@ def upload_data(conn, workdate):
c.execute(sql_str, (dealname, updatedate))
currlen = c.fetchone()[0]
conn.commit()
- if currlen != len(data): #then we delete and just reupload
- logger.warning("{0} has {1} rows in the database " \
- "and current collateral file has {2}".format(dealname, currlen, len(data)))
+ if currlen != len(data): # then we delete and just reupload
+ logger.warning(
+ "{0} has {1} rows in the database "
+ "and current collateral file has {2}".format(
+ dealname, currlen, len(data)
+ )
+ )
with conn.cursor() as c:
sql_str = "DELETE FROM et_collateral where dealname = %s and updatedate = %s"
c.execute(sql_str, (dealname, updatedate))
@@ -132,21 +198,29 @@ def upload_data(conn, workdate):
if reinsert or not old_update_dates or updatedate not in old_update_dates:
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:
+ c.executemany(
+ sqlstr,
+ [(dealname, updatedate, k) + tuple(v) for k, v in data.items()],
+ )
+ except (
+ psycopg2.DataError,
+ psycopg2.IntegrityError,
+ TypeError,
+ ) as detail:
logger.error(detail)
conn.rollback()
else:
conn.commit()
+
def intex_data(conn, workdate):
- basedir = Path(os.environ['DATA_DIR']) / ("Indicative_" + workdate)
+ basedir = Path(os.environ["DATA_DIR"]) / ("Indicative_" + workdate)
cusip_files = [f for f in basedir.iterdir() if "TrInfo" in f.name]
deal_files = [f for f in basedir.iterdir() if "TrInfo" not in f.name]
- #first load deal data
+ # first load deal data
for deal_file in deal_files:
upload_deal_data(conn, deal_file)
- #then load tranche data
+ # then load tranche data
for cusip_file in cusip_files:
upload_cusip_data(conn, cusip_file)