aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/analytics/basket_index.py14
-rw-r--r--python/analytics/tranche_basket.py83
-rw-r--r--python/analytics/tranche_functions.py8
-rw-r--r--python/index_data.py2
4 files changed, 83 insertions, 24 deletions
diff --git a/python/analytics/basket_index.py b/python/analytics/basket_index.py
index 7b0fa8f8..0347a224 100644
--- a/python/analytics/basket_index.py
+++ b/python/analytics/basket_index.py
@@ -17,7 +17,7 @@ class BasketIndex(CreditIndex):
value_date: pd.Timestamp
tweaks: List[float]
- def __init__(self, index_type: str, series: int, tenors: List[str], *args,
+ def __init__(self, index_type: str, series: int, tenors: List[str], *,
trade_date: pd.Timestamp=pd.Timestamp.today().normalize() - BDay()):
self.index_type = index_type
self.series = series
@@ -33,7 +33,7 @@ class BasketIndex(CreditIndex):
index_col='tenor',
params=(index_type, series),
parse_dates=['maturity', 'issue_date'])
- r = _engine.execute("SELECT lastdate, indexfactor/100 AS factor, cumulativeloss, version " \
+ r = _engine.execute("SELECT lastdate, indexfactor/100 AS factor, cumulativeloss/100, version " \
"FROM index_version " \
"WHERE index = %s AND series = %s" \
"ORDER BY lastdate", (index_type, series))
@@ -57,15 +57,15 @@ class BasketIndex(CreditIndex):
@property
def factor(self):
- return self._query_version(1)
+ return self._query_version(0)
@property
def cumloss(self):
- return self._query_version(2)
+ return self._query_version(1)
@property
def version(self):
- return self._query_version(3)
+ return self._query_version(2)
def _get_quotes(self):
pass
@@ -125,9 +125,9 @@ class BasketIndex(CreditIndex):
self.tweak_portfolio(eps, m)
class MarkitBasketIndex(BasketIndex):
- def __init__(self, index_type: str, series: int, tenors: List[str], *args,
+ def __init__(self, index_type: str, series: int, tenors: List[str], *,
trade_date: pd.Timestamp=pd.Timestamp.today().normalize() - BDay()):
- super().__init__(index_type, series, tenors, *args, trade_date)
+ super().__init__(index_type, series, tenors, trade_date=trade_date)
self.index_quotes = (get_index_quotes(index_type, series,
tenors, years=None)['closeprice'].
unstack().
diff --git a/python/analytics/tranche_basket.py b/python/analytics/tranche_basket.py
index 67327e00..ad96cb59 100644
--- a/python/analytics/tranche_basket.py
+++ b/python/analytics/tranche_basket.py
@@ -1,22 +1,61 @@
from .basket_index import BasketIndex
from .db import _engine
-from .tranche_functions import credit_schedule
+from .tranche_functions import credit_schedule, adjust_attachments, cds_accrued
from index_data import get_singlenames_curves, get_tranche_quotes
from pyisda.cdsone import upfront_charge
from pandas.tseries.offsets import BDay
import pandas as pd
+import numpy as np
class TrancheBasket(BasketIndex):
- def __init__(self, index_type: str, series: int, tenor: str, *args,
- trade_date: pd.Timestamp=pd.Timestamp.today().normalize() - BDay()):
- super().__init__(index_type, series, [tenor], *args, trade_date)
+ def __init__(self, index_type: str, series: int, tenor: str, *,
+ trade_date: pd.Timestamp=pd.Timestamp.today().normalize()):
+ print(trade_date)
+ super().__init__(index_type, series, [tenor], trade_date=trade_date)
self.tranche_quotes = get_tranche_quotes(index_type, series, tenor, trade_date.date())
index_desc = self.index_desc.reset_index('maturity').set_index('tenor')
self.maturity = index_desc.loc[tenor].maturity
self.start_date, self.cs = credit_schedule(trade_date, tenor[:-1], 1, self.yc)
- self.K_orig = [0] + [q['detach'] for q in self.tranche_quotes]
- #self.K = adjust_attachments(self.K_orig, self
+ self.K_orig = np.hstack([0, self.tranche_quotes.detach])
+ self.K = adjust_attachments(self.K_orig, self.cumloss, self.factor)
+ if index_type == "HY":
+ self.tranche_quotes['quotes'] = 1 - self.tranche_quotes.trancheupfrontmid / 100
+ else:
+ self.tranche_quotes['quotes'] = self.tranche_quotes.trancheupfrontmid / 100
+ self.tranche_quotes['running'] = self.tranche_quotes.trancherunningmid * 1e-4
+
+ if index_type == "XO":
+ coupon = 500 * 1e-4
+ self.tranche_quotes.quotes.iat[3] = self._snacpv(self.tranche_quotes.running.iat[3],
+ coupon,
+ 0.4)
+ self.tranche_quotes.running = coupon
+
+ if index_type == "EU":
+ if series >= 21:
+ coupon = 100 * 1e-4
+ for i in [2, 3]:
+ self.tranche_quotes.quotes.iat[i] = self._snacpv(
+ self.tranche_quotes.running.iat[i],
+ coupon,
+ 0. if i == 2 else 0.4)
+ self.tranche_quotes.running.iat[i] = coupon
+ elif series == 9:
+ for i in [3, 4, 5]:
+ coupon = 25 * 1e-4 if i == 5 else 100 * 1e-4
+ recov = 0.4 if i == 5 else 0
+ self.tranche_quotes.quotes.iat[i] = self._snacpv(
+ self.tranche_quotes.running.iat[i],
+ coupon,
+ recov)
+ self.tranche_quotes.running.iat[i] = coupon
+ accrued = cds_accrued(self.trade_date, self.tranche_quotes.running)
+ self.tranche_quotes.quotes -= accrued
+
+ self._Ngh = 250
+ self._Ngrid = 201
+ self._Z, self._w = GHquad(self._Ngh)
def _get_quotes(self):
refprice = self.tranche_quotes[0]['indexrefprice']
@@ -25,12 +64,32 @@ class TrancheBasket(BasketIndex):
return {self.maturity: 1 - refprice / 100}
if refspread is not None:
return {self.maturity:
- upfront_charge(self.trade_date, self.value_date, self.start_date,
- self.step_in_date, self.start_date, self.maturity,
- self.coupon(self.maturity), self.yc,
- refspread * 1e-4, self.recovery)}
+ _scnacpv(refspread * 1e-4, self.coupon(maturity), self.recovery)}
raise ValueError("ref is missing")
+ def _snacpv(self, spread, coupon, recov):
+ return upfront_charge(self.trade_date, self.value_date, self.start_date,
+ self.step_in_date, self.start_date, self.maturity,
+ coupon, self.yc, spread, recov)
+
@property
- def survival_matrix(self):
- return super().survival_matrix(self.cs.index.values.astype('M8[D]').view('int') + 134774)
+ def default_prob(self):
+ return 1 - super().survival_matrix(self.cs.index.values.astype('M8[D]').view('int') + 134774)
+
+ def tranche_legs(self, K, rho, complement=False):
+ if ((K == 0 and not complement) or (K == 1 and complement)):
+ return {'cl': 0., 'pl': 0.}
+ elif ((K == 1 and not complement) or (K == 0 and complement)):
+ return BCindexpv(index)
+ else:
+ L, R = BCloss_recov_dist(self.default_prob,
+ self.weights,
+ self.recovery,
+ rho,
+ self._Z, self._w, self._Ngrid)
+ if complement:
+ return {'cl': tranche_cl(L, R, self.cs, K, 1),
+ 'pl': tranche_pl(L, self.cs, K, 1)}
+ else:
+ return {'cl': tranche_cl(L, R, self.cs, 0, K),
+ 'pl': tranche_pl(L, self.cs, 0, K)}
diff --git a/python/analytics/tranche_functions.py b/python/analytics/tranche_functions.py
index 25020cd6..499bbc7e 100644
--- a/python/analytics/tranche_functions.py
+++ b/python/analytics/tranche_functions.py
@@ -304,14 +304,14 @@ def credit_schedule(tradedate, tenor, coupon, yc, enddate=None):
return pydates[0], pd.DataFrame({"df": df, "coupons": coupons}, dates[1:])
-def cdsAccrued(tradedate, coupon):
+def cds_accrued(tradedate, coupon):
tradedate = pydate_to_qldate(tradedate)
- end = tradedate + Period('3Mo')
+ end = tradedate + Period('3M')
start_protection = tradedate + 1
DC = Actual360()
- cal = UnitedStates()
- sched = Schedule(start, end, Period('3Mo'), cal, date_generation_rule=CDS2015)
+ cal = WeekendsOnly()
+ sched = Schedule(tradedate, end, Period('3M'), cal, date_generation_rule=CDS2015)
prevpaydate = sched.previous_date(tradedate)
return DC.year_fraction(prevpaydate, start_protection) * coupon
diff --git a/python/index_data.py b/python/index_data.py
index a4f76113..730a4e8a 100644
--- a/python/index_data.py
+++ b/python/index_data.py
@@ -173,4 +173,4 @@ def get_tranche_quotes(index_type, series, tenor, date=datetime.date.today()):
conn = dbconn('serenitasdb')
with conn.cursor() as c:
c.callproc("get_tranche_quotes", (index_type, series, tenor, date))
- return c.fetchall()
+ return pd.DataFrame.from_records(dict(d) for d in c)