aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics/credit_default_swap.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics/credit_default_swap.py')
-rw-r--r--python/analytics/credit_default_swap.py46
1 files changed, 31 insertions, 15 deletions
diff --git a/python/analytics/credit_default_swap.py b/python/analytics/credit_default_swap.py
index 5bddbf73..a2464f94 100644
--- a/python/analytics/credit_default_swap.py
+++ b/python/analytics/credit_default_swap.py
@@ -13,6 +13,7 @@ from pyisda.date import previous_twentieth
from pyisda.legs import ContingentLeg, FeeLeg
from termcolor import colored
from .utils import build_table, get_fx
+from typing import Union
from weakref import WeakSet
from yieldcurve import get_curve, rate_helpers, YC, ql_to_jp
@@ -51,7 +52,13 @@ class CreditDefaultSwap:
)
def __init__(
- self, start_date, end_date, recovery, fixed_rate, notional=10e6, issue_date=None
+ self,
+ start_date: datetime.date,
+ end_date: datetime.date,
+ recovery: float,
+ fixed_rate: float,
+ notional: float = 10e6,
+ issue_date: Union[datetime.date, None] = None,
):
"""
start_date : :class:`datetime.date`
@@ -134,6 +141,15 @@ class CreditDefaultSwap:
def spread(self):
if self._spread is not None:
return self._spread * 1e4
+ elif self._sc is not None:
+ return self._sc.par_spread(
+ self.value_date,
+ self._step_in_date,
+ self.start_date,
+ [self.end_date],
+ np.array([self.recovery]),
+ self._yc,
+ )
else:
return None
@@ -154,17 +170,18 @@ class CreditDefaultSwap:
raise ValueError("Direction needs to be either 'Buyer' or 'Seller'")
def _update(self):
- self._sc = SpreadCurve(
- self._yc.base_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]),
- )
+ if self._spread is not None:
+ self._sc = SpreadCurve(
+ self._yc.base_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.value_date,
@@ -189,7 +206,7 @@ class CreditDefaultSwap:
@spread.setter
def spread(self, s):
""" s: spread in bps """
- if self.spread is None or s != self.spread:
+ if self._spread is None or s != self.spread:
self._spread = s * 1e-4
self._update()
self.notify()
@@ -361,8 +378,7 @@ class CreditDefaultSwap:
self._step_in_date = d + datetime.timedelta(days=1)
self._accrued = self._fee_leg.accrued(self._step_in_date)
self._cash_settle_date = pd.Timestamp(self._value_date) + 3 * BDay()
- if self._spread is not None:
- self._update()
+ self._update()
self.notify()
def reset_pv(self):