From 4a7f3a3977dcac815dcfbd9dc068ba6f791f8a7e Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Mon, 27 Feb 2017 16:53:54 -0500 Subject: add duration --- pyisda/credit_index.pyx | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx index f65bedb..2fa88bf 100644 --- a/pyisda/credit_index.pyx +++ b/pyisda/credit_index.pyx @@ -234,11 +234,48 @@ cdef class CreditIndex(CurveList): tweaked_curve, True, &fl_pv) - r += cl_pv - fl_pv * fixed_rate + r += self._weights[i] * (cl_pv - (fl_pv - accrued) * fixed_rate) if epsilon != 0: JpmcdsFreeTCurve(tweaked_curve) free(mask) - return r / self._curves.size() + return r + + @cython.boundscheck(False) + @cython.cdivision(True) + def duration(self, step_in_date, value_date, maturity, YieldCurve yc not None): + + cdef: + TDate step_in_date_c = pydate_to_TDate(step_in_date) + TDate value_date_c = pydate_to_TDate(value_date) + TDate maturity_c = pydate_to_TDate(maturity) + + cdef double accrued + FeeLegAI(self._fee_legs[0], self._base_date, &accrued) + cdef: + TFeeLeg* fl + + for i in range(self._maturities.size()): + if self._maturities[i] == maturity_c: + fl = self._fee_legs[i] + break + else: + raise ValueError("maturity is not correct") + + + cdef: + double fl_pv, r = 0 + + for i in range(self._curves.size()): + JpmcdsFeeLegPV(fl, + self._base_date, + step_in_date_c, + value_date_c, + yc._thisptr.get(), + self._curves[i].get(), + True, + &fl_pv) + r += self._weights[i] * fl_pv + return r @property def maturities(self): @@ -247,7 +284,7 @@ cdef class CreditIndex(CurveList): r.append(TDate_to_pydate(self._maturities[i])) return r - def tweak_portfolio(self, double epsilon, maturity, bint inplace=True): + def tweak_portfolio(self, double epsilon, maturity): cdef TDate maturity_c = pydate_to_TDate(maturity) cdef bint* mask = fill_mask(maturity_c, self._maturities, self._curves[0]) cdef vector[double] h = vector[double](self._T.size()) -- cgit v1.2.3-70-g09d2