aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics/index.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics/index.py')
-rw-r--r--python/analytics/index.py98
1 files changed, 49 insertions, 49 deletions
diff --git a/python/analytics/index.py b/python/analytics/index.py
index 58cada76..f27bef6d 100644
--- a/python/analytics/index.py
+++ b/python/analytics/index.py
@@ -53,11 +53,11 @@ class Index(object):
""" minimal class to represent a credit index """
__slots__ = ['fixed_rate', 'notional', '_start_date', '_end_date',
'recovery', '_version', '_fee_leg', '_default_leg',
- '_trade_date', '_yc', '_sc', '_risky_annuity', '_spread',
+ '_value_date', '_yc', '_sc', '_risky_annuity', '_spread',
'_price', 'name', 'issue_date', '_quote_is_price',
'_direction', 'currency', '_step_in_date', '_accrued',
- '_value_date', '_dl_pv', '_pv', '_clean_pv',
- '_original_clean_pv', '_original_trade_date',
+ '_cash_settle_date', '_dl_pv', '_pv', '_clean_pv',
+ '_original_clean_pv', '_trade_date',
'index_type', 'series', 'tenor', '_observed']
def __init__(self, start_date, end_date, recovery, fixed_rate,
notional=10e6, quote_is_price=False, issue_date=None):
@@ -80,7 +80,7 @@ class Index(object):
self._fee_leg = FeeLeg(self._start_date, end_date, True, 1., 1.)
self._default_leg = ContingentLeg(self._start_date, end_date, True)
- self._trade_date = None
+ self._value_date = None
self._yc, self._sc = None, None
self._risky_annuity = None
self._spread, self._price = None, None
@@ -88,9 +88,9 @@ class Index(object):
self.issue_date = issue_date
self._quote_is_price = quote_is_price
self._direction = -1.
- for attr in ['currency', '_step_in_date', '_value_date', '_accrued',
+ for attr in ['currency', '_step_in_date', '_cash_settle_date', '_accrued',
'_dl_pv', '_pv', '_clean_pv', '_original_clean_pv',
- '_original_trade_date', 'index_type', 'series', 'tenor']:
+ '_trade_date', 'index_type', 'series', 'tenor']:
setattr(self, attr, None)
self._observed = WeakSet()
@@ -148,16 +148,16 @@ class Index(object):
raise ValueError("Direction needs to be either 'Buyer' or 'Seller'")
def _update(self):
- self._sc = SpreadCurve(self.trade_date, self._yc, self.start_date,
- self._step_in_date, self._value_date,
+ self._sc = SpreadCurve(self.value_date, self._yc, self.start_date,
+ self._step_in_date, self._cash_settle_date,
[self.end_date], np.array([self._spread]), np.zeros(1),
np.array([self.recovery]))
- self._risky_annuity = self._fee_leg.pv(self.trade_date, self._step_in_date,
- self._value_date, self._yc,
+ self._risky_annuity = self._fee_leg.pv(self.value_date, self._step_in_date,
+ self._cash_settle_date, self._yc,
self._sc, False)
self._dl_pv = self._default_leg.pv(
- self.trade_date, self._step_in_date, self._value_date,
+ self.value_date, self._step_in_date, self._cash_settle_date,
self._yc, self._sc, self.recovery)
self._pv = self._dl_pv - self._risky_annuity * self.fixed_rate * 1e-4
self._clean_pv = self._pv + self._accrued * self.fixed_rate * 1e-4
@@ -209,16 +209,16 @@ class Index(object):
if self._price is None or math.fabs(val-self._price) > 1e-6:
self._clean_pv = (100 - val) / 100
self._sc = SpreadCurve(
- self.trade_date, self._yc, self.start_date,
- self._step_in_date, self._value_date,
+ self.value_date, self._yc, self.start_date,
+ self._step_in_date, self._cash_settle_date,
[self.end_date], array.array('d',[self.fixed_rate*1e-4]),
array.array('d', [self._clean_pv]),
array.array('d', [self.recovery]))
self._risky_annuity = self._fee_leg.pv(
- self.trade_date, self._step_in_date, self._value_date,
+ self.value_date, self._step_in_date, self._cash_settle_date,
self._yc, self._sc, False)
self._dl_pv = self._default_leg.pv(
- self.trade_date, self._step_in_date, self._value_date,
+ self.value_date, self._step_in_date, self._cash_settle_date,
self._yc, self._sc, self.recovery)
self._pv = self._clean_pv - self._accrued * self.fixed_rate * 1e-4
self._spread = self._clean_pv / (self._risky_annuity - self._accrued) \
@@ -250,13 +250,13 @@ class Index(object):
@property
def theta(self):
- old_pv, old_trade_date = self.clean_pv, self.trade_date
+ old_pv, old_value_date = self.clean_pv, self.value_date
with warnings.catch_warnings():
warnings.simplefilter("ignore")
- self.trade_date = self.trade_date + relativedelta(days=1)
+ self.value_date = self.value_date + relativedelta(days=1)
carry = self.notional * self._direction * self.fixed_rate * 1e-4/360
roll_down = self.clean_pv - old_pv
- self.trade_date = old_trade_date
+ self.value_date = old_value_date
return carry + roll_down
@property
@@ -265,7 +265,7 @@ class Index(object):
# for rh in self._helpers:
# rh.quote += 1e-4
# self._yc = ql_to_jp(self._ql_yc)
- helpers = rate_helpers(self.currency, evaluation_date=self.trade_date)
+ helpers = rate_helpers(self.currency, evaluation_date=self.value_date)
for rh in helpers:
rh.quote += 1e-4
ql_yc = YC(helpers)
@@ -301,32 +301,32 @@ class Index(object):
return self._risky_annuity - self._accrued
@property
- def trade_date(self):
- if self._trade_date is None:
- raise AttributeError('Please set trade_date first')
+ def value_date(self):
+ if self._value_date is None:
+ raise AttributeError('Please set value_date first')
else:
- return self._trade_date
+ return self._value_date
- @trade_date.setter
- def trade_date(self, d):
+ @value_date.setter
+ def value_date(self, d):
if isinstance(d, datetime.datetime):
d = d.date()
self.start_date = previous_twentieth(d)
self._yc = get_curve(d, self.currency)
# use the rolled forward curve if we price something in the future
- if self._yc.base_date < d:
- self._yc = self._yc.expected_forward_curve(d)
- self._trade_date = d
- self._step_in_date = self.trade_date + datetime.timedelta(days=1)
+ # if self._yc.base_date < d:
+ # self._yc = self._yc.expected_forward_curve(d)
+ self._value_date = d
+ self._step_in_date = d + datetime.timedelta(days=1)
self._accrued = self._fee_leg.accrued(self._step_in_date)
- self._value_date = pd.Timestamp(self._trade_date) + 3* BDay()
+ self._cash_settle_date = pd.Timestamp(self._value_date) + 3* BDay()
if self._spread is not None:
self._update()
self.notify()
def reset_pv(self):
self._original_clean_pv = self._clean_pv
- self._original_trade_date = self._trade_date
+ self._trade_date = self._value_date
@property
def pnl(self):
@@ -334,7 +334,7 @@ class Index(object):
raise ValueError("original pv not set")
else:
## TODO: handle factor change
- days_accrued = (self.trade_date - self._original_trade_date).days / 360
+ days_accrued = (self.value_date - self._trade_date).days / 360
return - self._direction * self.notional * self.factor * \
(self._clean_pv - self._original_clean_pv -
days_accrued * self.fixed_rate * 1e-4)
@@ -347,7 +347,7 @@ class Index(object):
self._observed.add(obj)
def mark(self):
- if self.trade_date == datetime.date.today():
+ if self.value_date == datetime.date.today():
with init_bbg_session(BBG_IP) as session:
security = self.name + " Corp"
field = "PX_LAST"
@@ -356,14 +356,14 @@ class Index(object):
else:
run = _engine.execute("""SELECT * FROM index_quotes
WHERE index=%s AND series=%s AND tenor=%s AND date=%s""",
- (self.index_type, self.series, self.tenor, self.trade_date))
+ (self.index_type, self.series, self.tenor, self.value_date))
rec = run.fetchone()
self.spread = rec.closespread
@property
def factor(self):
for lastdate, factor, _ in self._version:
- if lastdate >= self.trade_date:
+ if lastdate >= self.value_date:
return factor
else:
return 1
@@ -371,13 +371,13 @@ class Index(object):
@property
def version(self):
for lastdate, _, version in self._version:
- if lastdate >= self.trade_date:
+ if lastdate >= self.value_date:
return version
else:
return None
@classmethod
- def from_name(cls, index=None, series=None, tenor=None, trade_date=datetime.date.today(),
+ def from_name(cls, index=None, series=None, tenor=None, value_date=datetime.date.today(),
notional=10_000_000, redcode=None, maturity=None):
if all([index, series, tenor]):
sql_str = "SELECT indexfactor, lastdate, maturity, coupon, " \
@@ -409,7 +409,7 @@ class Index(object):
return None
else:
recovery = 0.4 if index_type in ['IG', 'EU'] else 0.3
- instance = cls(trade_date, maturity, recovery, coupon, notional,
+ instance = cls(value_date, maturity, recovery, coupon, notional,
index_type == "HY", df.issue_date[0])
instance._version = tuple((ld.date(), factor / 100, version) for ld, factor, version in \
df[['lastdate', 'indexfactor', 'version']].itertuples(index=False))
@@ -428,7 +428,7 @@ class Index(object):
instance.currency = "USD"
else:
instance.currency = "EUR"
- instance.trade_date = trade_date
+ instance.value_date = value_date
return instance
@classmethod
@@ -452,10 +452,10 @@ class Index(object):
instance.name = rec.security_desc
instance.currency = rec.currency
instance.direction = rec.protection
- instance.trade_date = rec.trade_date
+ instance.value_date = rec.trade_date
instance.pv = rec.upfront
instance._original_clean_pv = instance._clean_pv
- instance._original_trade_date = rec.trade_date
+ instance._trade_date = rec.trade_date
instance.index_type = index_type
instance.series = rec.series
instance.tenor = rec.tenor
@@ -488,8 +488,8 @@ class Index(object):
s += build_table(rows, format_strings, "{:<20}{:>19}\t\t{:<20}{:>15}")
s += ["",
colored("Calculator", attrs = ['bold'])]
- rows = [["Valuation Date", self.trade_date],
- ["Cash Settled On", self._value_date]]
+ rows = [["Valuation Date", self.value_date],
+ ["Cash Settled On", self._cash_settle_date]]
format_strings = [[None, '{:%m/%d/%y}'],
[None, '{:%m/%d/%y}']]
s += build_table(rows, format_strings, "{:<20}\t{:>15}")
@@ -524,8 +524,8 @@ class ForwardIndex(object):
@classmethod
def from_name(cls, index_type, series, tenor, forward_date,
- trade_date=datetime.date.today(), notional=10e6):
- index = Index.from_name(index_type, series, tenor, trade_date, notional)
+ value_date=datetime.date.today(), notional=10e6):
+ index = Index.from_name(index_type, series, tenor, value_date, notional)
return cls(index, forward_date)
@property
@@ -552,12 +552,12 @@ class ForwardIndex(object):
return hash(tuple(getattr(self, k) for k in ForwardIndex.__slots__ if k != '__weakref__'))
def _update(self, *args):
- if self.index.trade_date > self.forward_date:
- return
+ if self.index.value_date > self.forward_date:
+ raise ValueError("Option expired")
if self.index._sc is not None:
step_in_date = self.forward_date + datetime.timedelta(days=1)
- a = self.index._fee_leg.pv(self.index.trade_date, step_in_date,
- self.index.trade_date, self.index._yc, self.index._sc, False)
+ a = self.index._fee_leg.pv(self.index.value_date, step_in_date,
+ self.index.value_date, self.index._yc, self.index._sc, False)
Delta = self.index._fee_leg.accrued(step_in_date)
q = self.index._sc.survival_probability(self.forward_date)
self._forward_annuity = a - Delta * self.df * q