summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyisda/credit_index.pyx6
-rw-r--r--pyisda/curve.pxd3
-rw-r--r--pyisda/curve.pyx22
3 files changed, 27 insertions, 4 deletions
diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx
index 1d7ae43..1f0bca5 100644
--- a/pyisda/credit_index.pyx
+++ b/pyisda/credit_index.pyx
@@ -12,7 +12,7 @@ cimport cython
from legs cimport (JpmcdsCdsContingentLegMake, JpmcdsCdsFeeLegMake,
JpmcdsContingentLegPV, JpmcdsFeeLegPV, FeeLegAI, JpmcdsFeeLegFree)
from curve cimport (SpreadCurve, JpmcdsCopyCurve, tweak_curve, YieldCurve,
- JpmcdsFreeTCurve, JpmcdsForwardZeroPrice, Hash64WithSeed,
+ JpmcdsFreeTCurve, survival_prob, Hash64WithSeed,
Hash64, uint64_t, TCurve_size, serialize)
from date cimport (pydate_to_TDate, TDate_to_pydate, ACT_365F, JpmcdsDtFwdAny,
TDateInterval, JpmcdsMakeDateInterval)
@@ -523,7 +523,7 @@ cdef class CreditIndex(CurveList):
- def survival_matrix(self, TDate[:] schedule):
+ def survival_matrix(self, TDate[:] schedule, double epsilon=0.):
cdef:
shared_ptr[TCurve] sc
pair[string, size_t] p
@@ -539,7 +539,7 @@ cdef class CreditIndex(CurveList):
sc = self._curves[p.second]
tickers[p.second] = p.first
for i in range(n[1]):
- sp[p.second, i] = JpmcdsForwardZeroPrice(sc.get(), self.base_date, schedule[i])
+ sp[p.second, i] = survival_prob(sc.get(), self.base_date, schedule[i], epsilon)
return sp, tickers
cdef unsigned long fill_mask(const TDate maturity, const vector[TDate]& maturities,
diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd
index c30f502..f89d892 100644
--- a/pyisda/curve.pxd
+++ b/pyisda/curve.pxd
@@ -183,6 +183,9 @@ cdef extern from "isda/tcurve.h" nogil:
cdef extern from "isda/cxzerocurve.h" nogil:
double JpmcdsZeroPrice(TCurve* curve, TDate date)
double JpmcdsForwardZeroPrice(TCurve* curve, TDate startDate, TDate maturityDate)
+ double JpmcdsZeroRate(TCurve* curve, TDate date)
+
+cdef double survival_prob(TCurve* curve, TDate start_date, TDate maturity_date, double eps) nogil
cdef extern from "isda/cfinanci.h":
int JpmcdsDiscountToRateYearFrac(double discount, # (I) Discount factor
diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx
index e6c64c7..65c37b5 100644
--- a/pyisda/curve.pyx
+++ b/pyisda/curve.pyx
@@ -1,4 +1,4 @@
-from libc.math cimport log1p, log
+from libc.math cimport log1p, log, exp
from date cimport (JpmcdsStringToDateInterval, pydate_to_TDate, dcc, TMonthDayYear,
JpmcdsDateIntervalToFreq, JpmcdsDateFwdThenAdjust, TDate_to_pydate,
JpmcdsDateFromBusDaysOffset, JpmcdsStringToDayCountConv, ACT_360,
@@ -36,6 +36,26 @@ cdef inline void double_free(double* ptr) nogil:
free(ptr)
+cdef double survival_prob(TCurve* curve, TDate start_date, TDate maturity_date, double eps) nogil:
+ cdef:
+ double lambda1, lambda2
+ double t1, t2, u
+ if start_date == curve.fBaseDate:
+ lambda2 = JpmcdsZeroRate(curve, maturity_date)
+ t2 = (maturity_date - curve.fBaseDate) / 365.
+ if eps != 0.:
+ lambda2 *= (1 + eps)
+ return exp(-lambda2 * t2)
+ else:
+ lambda1 = JpmcdsZeroRate(curve, start_date)
+ lambda2 = JpmcdsZeroRate(curve, maturity_date)
+ t1 = (start_date - curve.fBaseDate) / 365.
+ t2 = (maturity_date - curve.fBaseDate) / 365.
+ u = lambda1 * t1 - lambda2 * t2
+ if eps != 0.:
+ u *= (1 + eps)
+ return exp(u)
+
cdef class Curve(object):
def __getstate__(self):