From 07d18d03d2f2eb8bd4bb4df844ce2e16e7e581d1 Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Tue, 28 Aug 2018 16:01:03 -0400 Subject: write our own survival_prob function --- pyisda/credit_index.pyx | 6 +++--- pyisda/curve.pxd | 3 +++ pyisda/curve.pyx | 22 +++++++++++++++++++++- 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): -- cgit v1.2.3-70-g09d2