summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2017-02-17 18:03:24 -0500
committerGuillaume Horel <guillaume.horel@gmail.com>2017-02-17 18:03:24 -0500
commit467072ec6b92d86b220a96d595390b0615bd8b8b (patch)
treeeb8cb323b1cddf6a68e3d8885a7d6d4888d75f21
parent98d5545a5474194f3f6cf16cdf9ccd39dc060513 (diff)
downloadpyisda-467072ec6b92d86b220a96d595390b0615bd8b8b.tar.gz
rework CreditIndexCurve
-rw-r--r--pyisda/curve.pxd13
-rw-r--r--pyisda/curve.pyx201
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