diff options
| author | Guillaume Horel <guillaume.horel@gmail.com> | 2017-02-17 18:03:24 -0500 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@gmail.com> | 2017-02-17 18:03:24 -0500 |
| commit | 467072ec6b92d86b220a96d595390b0615bd8b8b (patch) | |
| tree | eb8cb323b1cddf6a68e3d8885a7d6d4888d75f21 | |
| parent | 98d5545a5474194f3f6cf16cdf9ccd39dc060513 (diff) | |
| download | pyisda-467072ec6b92d86b220a96d595390b0615bd8b8b.tar.gz | |
rework CreditIndexCurve
| -rw-r--r-- | pyisda/curve.pxd | 13 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 201 |
2 files changed, 150 insertions, 64 deletions
diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index 503727d..e42e8de 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -117,12 +117,15 @@ cdef class YieldCurve(Curve): cdef class SpreadCurve(Curve): pass -cdef class CreditIndex: +cdef class CreditIndexCurve: + cdef TDate _base_date cdef TCurve** _curves - cdef TContingentLeg* _contingent_leg - cdef TFeeLeg* _fee_leg + cdef int _len_curves + cdef TDate* _maturities + cdef TContingentLeg** _contingent_legs + cdef TFeeLeg** _fee_legs + cdef int _len_maturities cdef double* _T - cdef int _ncurves - cdef int _ndates + cdef int _len_T cdef fArray_to_list(TRatePt* fArray, int fNumItems) diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index 49e2522..9662961 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -483,86 +483,116 @@ cdef class SpreadCurve(Curve): free(T) return sc -cdef class CreditIndex: - def __init__(self, base_date, start_date, end_date, end_dates, curves): - self._ndates = len(end_dates) - cdef TDate base_date_c = pydate_to_TDate(base_date) - cdef TDate start_date_c = pydate_to_TDate(start_date) - cdef TDate end_date_c = pydate_to_TDate(end_date) - cdef TDate date - self._T = <double*>malloc(sizeof(double) * self._ndates) - self._ncurves = len(curves) - self._curves = <TCurve**>malloc(sizeof(TCurve*) * self._ncurves) +cdef class CreditIndexCurve: + def __init__(self, start_date, maturities, curves): + cdef SpreadCurve sc = <SpreadCurve?>curves[0] + self._len_T = sc._thisptr.fNumItems + self._base_date = sc._thisptr.fBaseDate + self._T = <double*>malloc(sizeof(double) * self._len_T) cdef size_t i - - for i, d in enumerate(end_dates): - date = pydate_to_TDate(d) - self._T[i] = (date - base_date_c) / 365. + for i in range(self._len_T): + self._T[i] = (sc._thisptr.fArray[i].fDate - self._base_date) / 365. + cdef TDate start_date_c = pydate_to_TDate(start_date) + self._len_maturities = len(maturities) + self._maturities = <TDate*>malloc(sizeof(TDate) * self._len_maturities) + for i, d in enumerate(maturities): + self._maturities[i] = pydate_to_TDate(d) + self._len_curves = len(curves) + self._curves = <TCurve**>malloc(sizeof(TCurve*) * self._len_curves) for i, c in enumerate(curves): self._curves[i] = JpmcdsCopyCurve((<SpreadCurve?>c)._thisptr) - self._contingent_leg = JpmcdsCdsContingentLegMake(start_date_c, - end_date_c, - 1., - True) + self._contingent_legs = <TContingentLeg**> malloc(self._len_maturities * + sizeof(TContingentLeg)) + self._fee_legs = <TFeeLeg**> malloc(self._len_maturities * + sizeof(TFeeLeg)) cdef TStubMethod stub_type if JpmcdsStringToStubMethod(b"f/s", &stub_type) != 0: raise ValueError("can't convert stub") + for i in range(self._len_maturities): + self._contingent_legs[i] = JpmcdsCdsContingentLegMake(start_date_c, + self._maturities[i], + 1., + True) - self._fee_leg = JpmcdsCdsFeeLegMake(start_date_c, - end_date_c, - True, - NULL, - &stub_type, - 1., - 1.0, - 3, #ACT_360 - MODIFIED, - b'NONE', - True) + self._fee_legs[i] = JpmcdsCdsFeeLegMake(start_date_c, + self._maturities[i], + True, + NULL, + &stub_type, + 1., + 1.0, + 3, #ACT_360 + MODIFIED, + b'NONE', + True) def __dealloc__(self): if self._T is not NULL: free(self._T) - if self._contingent_leg is not NULL: - free(self._contingent_leg) - JpmcdsFeeLegFree(self._fee_leg) - for i in range(self._ncurves): + if self._maturities is not NULL: + free(self._maturities) + if self._contingent_legs is not NULL: + for i in range(self._len_maturities): + free(self._contingent_legs[i]) + if self._fee_legs is not NULL: + for i in range(self._len_maturities): + JpmcdsFeeLegFree(self._fee_legs[i]) + for i in range(self._len_curves): JpmcdsFreeTCurve(self._curves[i]) free(self._curves) #@cython.initializedcheck(False) @cython.boundscheck(False) - def pv(self, step_in_date, value_date, YieldCurve yc, double recovery_rate): + def pv_vec(self, step_in_date, value_date, YieldCurve yc, double recovery_rate): cdef TDate step_in_date_c = pydate_to_TDate(step_in_date) cdef TDate value_date_c = pydate_to_TDate(value_date) - cdef np.npy_intp n = self._ncurves + cdef np.npy_intp[2] n = [self._len_curves, self._len_maturities] cdef double accrued - FeeLegAI(self._fee_leg, yc._thisptr.fBaseDate, &accrued) - cdef size_t i - cdef np.ndarray[np.float64_t,ndim=1] cl_pv = np.PyArray_EMPTY(1, &n, np.NPY_DOUBLE, 0) - cdef np.ndarray[np.float64_t,ndim=1] fl_pv = np.PyArray_EMPTY(1, &n, np.NPY_DOUBLE, 0) + FeeLegAI(self._fee_legs[0], self._base_date, &accrued) + cdef size_t i, j + + cdef np.ndarray[np.float64_t,ndim=2] cl_pv = np.PyArray_EMPTY(2, n, np.NPY_DOUBLE, 0) + cdef np.ndarray[np.float64_t,ndim=2] fl_pv = np.PyArray_EMPTY(2, n, np.NPY_DOUBLE, 0) cdef TCurve* sc - for i in range(self._ncurves): + for i in range(self._len_curves): sc = self._curves[i] - JpmcdsContingentLegPV(self._contingent_leg, - sc.fBaseDate, - value_date_c, - step_in_date_c, - yc._thisptr, - sc, - recovery_rate, - &cl_pv[i]) - JpmcdsFeeLegPV(self._fee_leg, - sc.fBaseDate, - step_in_date_c, - value_date_c, - yc._thisptr, - sc, - True, - &fl_pv[i]) + for j in range(self._len_maturities): + JpmcdsContingentLegPV(self._contingent_legs[j], + sc.fBaseDate, + value_date_c, + step_in_date_c, + yc._thisptr, + sc, + recovery_rate, + &cl_pv[i,j]) + JpmcdsFeeLegPV(self._fee_legs[j], + sc.fBaseDate, + step_in_date_c, + value_date_c, + yc._thisptr, + sc, + True, + &fl_pv[i,j]) return (fl_pv-accrued, cl_pv) + def pv(self, step_in_date, value_date, YieldCurve yc not None, + double recovery_rate): + + cdef TDate step_in_date_c = pydate_to_TDate(step_in_date) + cdef TDate value_date_c = pydate_to_TDate(value_date) + + r = [] + for j in range(self._len_maturities): + r.append(pv(self._base_date, step_in_date_c, value_date_c, + yc._thisptr, recovery_rate, 0.01, + self._contingent_legs[j], + self._fee_legs[j], self._curves, self._len_curves)) + + cdef double accrued + FeeLegAI(self._fee_legs[0], self._base_date, &accrued) + return r + @property def curves(self): """returns the list of curves inside the porfolio. @@ -570,8 +600,61 @@ cdef class CreditIndex: This is returning the curves by reference so don't delete them.""" cdef list r = [] cdef SpreadCurve sc - for i in range(self._ncurves): - c = self._curves[i] + for i in range(self._len_curves): sc = SpreadCurve.__new__(SpreadCurve) - sc._thisptr = c + sc._thisptr = self._curves[i] r.append(sc) + + @property + def maturities(self): + cdef list r = [] + for i in range(self._len_maturities): + r.append(TDate_to_pydate(self._maturities[i])) + + def tweak_portfolio(self, quotes): + if len(quotes) != self._len_maturities: + raise ValueError("length of quotes must equal length of maturities") + cdef bint* mask = <bint*>malloc(sizeof(bint) * self._len_T) + cdef double* basis = <double*>malloc(sizeof(double) * self._len_T) + cdef TCurve* sc = self._curves[0] + cdef TDate maturity, prev_maturity + prev_maturity = 0 + cdef size_t i + for i in range(self._len_maturities): + maturity = self._maturities[i] + for j in range(self._len_T): + mask[j] = (sc.fArray[i].fDate <= maturity ) and \ + (sc.fArray[i].fDate > prev_maturity) + + free(mask) + free(basis) + +@cython.boundscheck(False) +cdef double pv(TDate base_date, TDate step_in_date, TDate value_date, TCurve* yc, + double recovery_rate, double coupon, + TContingentLeg* cl, TFeeLeg* fl, TCurve** curves, int n_curves): + + cdef size_t i + cdef TCurve* sc + cdef double r = 0 + cdef double cl_pv, fl_pv + for i in range(n_curves): + sc = curves[i] + JpmcdsContingentLegPV(cl, + base_date, + value_date, + step_in_date, + yc, + sc, + recovery_rate, + &cl_pv) + JpmcdsFeeLegPV(fl, + base_date, + step_in_date, + value_date, + yc, + sc, + True, + &fl_pv) + r += cl_pv - fl_pv*coupon + return r / <double>n_curves |
