diff options
| author | Guillaume Horel <guillaume.horel@gmail.com> | 2023-06-09 16:54:50 -0400 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@gmail.com> | 2023-06-09 16:54:50 -0400 |
| commit | 86c120cf8ca9a7dbff88d1084a0faee19ee6e339 (patch) | |
| tree | b26a8c5b24c24826e437af8287495d2112106fee | |
| parent | be2496b941a9af64dcdccb80f553c1694da89eb6 (diff) | |
| download | pyisda-86c120cf8ca9a7dbff88d1084a0faee19ee6e339.tar.gz | |
log of default prob instead of log of surv prob
| -rw-r--r-- | pyisda/credit_index.pyx | 4 | ||||
| -rw-r--r-- | pyisda/curve.pxd | 2 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 12 |
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: |
