diff options
| -rw-r--r-- | pyisda/curve.pxd | 12 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 65 |
2 files changed, 77 insertions, 0 deletions
diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index 61d55de..b30ffe1 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -1,4 +1,5 @@ from cdsone cimport TStubMethod +from legs cimport TContingentLeg, TFeeLeg cdef extern from "isda/zerocurve.h" nogil: ctypedef int TBoolean @@ -85,6 +86,10 @@ cdef extern from "isda/tcurve.h" nogil: long dayCountConv) TCurve* JpmcdsCopyCurve(TCurve* curve) TDate* JpmcdsDatesFromCurve(TCurve* curve) + TCurve* JpmcdsNewTCurve(TDate baseDate, # (I) Base date + int numPts, # (I) Length of dates & rates + double basis, # (I) Compounding periods/year + long dayCountConv) cdef extern from "isda/cxzerocurve.h" nogil: double JpmcdsZeroPrice(TCurve* curve, TDate date) @@ -112,4 +117,11 @@ cdef class YieldCurve(Curve): cdef class SpreadCurve(Curve): pass +cdef class BasketIndex: + cdef TCurve* _sc + cdef TContingentLeg* _contingent_leg + cdef TFeeLeg* _fee_leg + cdef double* _T + cdef double[:,::1] _rate + cdef fArray_to_list(TRatePt* fArray, int fNumItems) diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index 15f48a5..e481c22 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -6,6 +6,9 @@ from date cimport (JpmcdsStringToDateInterval, pydate_to_TDate, dcc, JpmcdsDateFromBusDaysOffset, JpmcdsStringToDayCountConv) from date import dcc_tostring from cdsone cimport JpmcdsStringToStubMethod, TStubMethod +from legs cimport (JpmcdsCdsContingentLegMake, JpmcdsCdsFeeLegMake, + JpmcdsContingentLegPV, JpmcdsFeeLegPV) + cimport cython cimport numpy as np np.import_array() @@ -431,3 +434,65 @@ cdef class SpreadCurve(Curve): return self else: return sc + +cdef class BasketIndex: + def __init__(self, base_date, start_date, end_date, + list end_dates, double[:,::1] hazard_rates): + cdef int n_dates = len(end_dates) + if n_dates != hazard_rates.shape[1]: + raise ValueError("Number of dates must equal the number of columns in rates") + cdef TDate base_date_c = pydate_to_TDate(base_date) + cdef TDate* end_dates_c = <TDate*>malloc(n_dates * sizeof(TDate)) + cdef TDate start_date_c = pydate_to_TDate(start_date) + cdef TDate end_date_c = pydate_to_TDate(end_date) + self._sc = JpmcdsNewTCurve(base_date_c, n_dates, 5000., 2L) + cdef TDate date + for i, d in enumerate(end_dates): + date = pydate_to_TDate(d) + self._T[i] = (date - base_date_c) / 365. + self._thisptr.fArray[i].fDate = date + self._hazard_rates[:] = hazard_rates + self._contingent_leg = JpmcdsCdsContingentLegMake(start_date_c, + end_date_c, + 1., + True) + cdef TStubMethod stub_type + if JpmcdsStringToStubMethod(b"f/s", &stub_type) != 0: + raise ValueError("can't convert stub") + + self._fee_leg = JpmcdsCdsFeeLegMake(start_date_c, + end_date_c, + True, + NULL, + &stub_type, + 1., + 0.01, + 3, #ACT_360 + MODIFIED, + b'NONE', + True) + + def pv(self, step_in_date, value_date, YieldCurve yc, double recovery_rate): + cdef step_in_date_c = pydate_to_TDate(step_in_date) + cdef value_date_c = pydate_to_TDate(value_date) + cdef size_t n = self._hazard_rates.shape[0] + cdef double cl_pv, fl_pv + for i in range(n): + for j in range(self._thisptr.fNumItems): + self._thisptr.fArray[j].fRate = self._rate[i][j] + JpmcdsContingentLegPV(self._contingent_leg, + self._sc.fBaseDate, + value_date_c, + step_in_date_c, + yc._thisptr, + self._sc, + recovery_rate, + &cl_pv) + JpmcdsFeeLegPV(self._fee_leg, + self._sc.fBaseDate, + step_in_date_c, + value_date_c, + yc._thisptr, + self._sc, + True, + &fl_pv) |
