summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyisda/credit_index.pyx4
-rw-r--r--pyisda/curve.pxd2
-rw-r--r--pyisda/curve.pyx12
3 files changed, 11 insertions, 7 deletions
diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx
index 509b0de..0264272 100644
--- a/pyisda/credit_index.pyx
+++ b/pyisda/credit_index.pyx
@@ -630,7 +630,7 @@ cdef class CreditIndex(CurveList):
self._curves[i].reset(new_buf, char_free)
self.names[CurveName(new_buf + offset)] = i
- def survival_matrix(self, const TDate[::1] schedule=None, double epsilon=0., bint log=False):
+ def survival_matrix(self, const TDate[::1] schedule=None, double epsilon=0., bint logsp=False):
cdef:
TCurve* sc
pair[CurveName, size_t] p
@@ -657,7 +657,7 @@ cdef class CreditIndex(CurveList):
tickers[j] = string(p.first.ticker.begin(), p.first.ticker.end())
for i in range(n[1]):
sp_view[j, i] = survival_prob(sc, self.base_date,
- schedule_ptr[i], epsilon, log)
+ schedule_ptr[i], epsilon, logsp)
j += 1
return sp, tickers
diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd
index ea01e08..54193a8 100644
--- a/pyisda/curve.pxd
+++ b/pyisda/curve.pxd
@@ -145,7 +145,7 @@ cdef extern from "isda/cxzerocurve.h" nogil:
double JpmcdsZeroRate(TCurve* curve, TDate date)
cdef double survival_prob(const TCurve* curve, TDate start_date,
- TDate maturity_date, double eps, bint log) noexcept nogil
+ TDate maturity_date, double eps, bint log_dp) noexcept nogil
cdef extern from "isda/cfinanci.h" nogil:
int JpmcdsDiscountToRateYearFrac(double discount, # (I) Discount factor
diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx
index a5d1261..813dbd7 100644
--- a/pyisda/curve.pyx
+++ b/pyisda/curve.pyx
@@ -1,7 +1,7 @@
from cython.operator import dereference as deref, preincrement as preinc
from cpython.bytes cimport PyBytes_FromStringAndSize, PyBytes_AS_STRING, PyBytes_GET_SIZE
-from libc.math cimport log1p, log, exp, isnan, NAN
+from libc.math cimport log1p, expm1, log, exp, isnan, NAN, M_LN2
from libc.string cimport strcpy, strncpy, strlen
from .date cimport (JpmcdsStringToDateInterval, pydate_to_TDate, dcc,
JpmcdsDateIntervalToFreq, JpmcdsDateFwdThenAdjust, TDate_to_pydate,
@@ -37,7 +37,7 @@ cdef inline void double_free(double* ptr) noexcept nogil:
cdef inline void char_free(char* ptr) noexcept nogil:
free(ptr)
-cdef double survival_prob(const TCurve* curve, TDate start_date, TDate maturity_date, double eps, bint log) noexcept nogil:
+cdef double survival_prob(const TCurve* curve, TDate start_date, TDate maturity_date, double eps, bint log_dp) noexcept nogil:
cdef:
double lambda1, lambda2
double t1, t2, u
@@ -46,7 +46,8 @@ cdef double survival_prob(const TCurve* curve, TDate start_date, TDate maturity_
t2 = (maturity_date - curve.fBaseDate) / 365.
if eps != 0.:
lambda2 *= (1 + eps)
- return -lambda2 * t2 if log else exp(-lambda2 * t2)
+ u = -lambda2 * t2
+
else:
lambda1 = JpmcdsZeroRate(curve, start_date)
lambda2 = JpmcdsZeroRate(curve, maturity_date)
@@ -55,7 +56,10 @@ cdef double survival_prob(const TCurve* curve, TDate start_date, TDate maturity_
u = (lambda1 * t1 - lambda2 * t2) / 365.
if eps != 0.:
u *= (1 + eps)
- return u if log else exp(u)
+ if log_dp:
+ return log(-expm1(u)) if u > - M_LN2 else log1p(-exp(u))
+ else:
+ return exp(u)
cdef void forward_rates(const TRatePt* arr, const TDate base_date, const int n, double* f, int *t) noexcept nogil:
cdef: