summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyisda/curve.pxd7
-rw-r--r--pyisda/curve.pyx98
2 files changed, 62 insertions, 43 deletions
diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd
index 2e5e999..503727d 100644
--- a/pyisda/curve.pxd
+++ b/pyisda/curve.pxd
@@ -117,11 +117,12 @@ cdef class YieldCurve(Curve):
cdef class SpreadCurve(Curve):
pass
-cdef class BasketIndex:
- cdef TCurve* _sc
+cdef class CreditIndex:
+ cdef TCurve** _curves
cdef TContingentLeg* _contingent_leg
cdef TFeeLeg* _fee_leg
cdef double* _T
- cdef double[:,::1] _hazard_rates
+ cdef int _ncurves
+ cdef int _ndates
cdef fArray_to_list(TRatePt* fArray, int fNumItems)
diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx
index cd38398..eb3d40e 100644
--- a/pyisda/curve.pyx
+++ b/pyisda/curve.pyx
@@ -1,6 +1,6 @@
from libc.stdlib cimport malloc, free
from libc.string cimport memcpy
-from libc.math cimport log1p, expm1
+from libc.math cimport log1p
from date cimport (JpmcdsStringToDateInterval, pydate_to_TDate, dcc,
JpmcdsDateIntervalToFreq, JpmcdsDateFwdThenAdjust, TDate_to_pydate,
JpmcdsDateFromBusDaysOffset, JpmcdsStringToDayCountConv)
@@ -45,14 +45,16 @@ cdef class Curve(object):
TDate base_date
double basis
long dcc
+ TCurve* new_curve
num_items, rates, base_date, basis, dcc = state
- self._thisptr = <TCurve*>malloc(sizeof(TCurve))
- self._thisptr.fNumItems = num_items
- self._thisptr.fArray = <TRatePt*>malloc(sizeof(TRatePt) * num_items)
- memcpy(self._thisptr.fArray, rates, sizeof(TRatePt) * num_items)
- self._thisptr.fBaseDate = base_date
- self._thisptr.fBasis = basis
- self._thisptr.fDayCountConv = dcc
+ new_curve = <TCurve*>malloc(sizeof(TCurve))
+ new_curve.fNumItems = num_items
+ new_curve.fArray = <TRatePt*>malloc(sizeof(TRatePt) * num_items)
+ memcpy(new_curve.fArray, rates, sizeof(TRatePt) * num_items)
+ new_curve.fBaseDate = base_date
+ new_curve.fBasis = basis
+ new_curve.fDayCountConv = dcc
+ self._thisptr = new_curve
def inspect(self):
""" method to inspect the content of the C struct
@@ -402,23 +404,23 @@ cdef class SpreadCurve(Curve):
## We want to tweak in the forward space, so we convert the hazard rates
## into forward rates and then back
cdef double t1, h1, t2, h2
- cdef TCurve* newcurve = NULL
+ cdef TCurve* curve = self._thisptr
cdef SpreadCurve sc
- cdef int num_items = self._thisptr.fNumItems
+ cdef int num_items = curve.fNumItems
if not inplace:
sc = SpreadCurve.__new__(SpreadCurve)
- sc._thisptr = JpmcdsCopyCurve(self._thisptr)
+ sc._thisptr = JpmcdsCopyCurve(curve)
t1 = 0
h1 = 0
cdef double* h = <double*>malloc(num_items * sizeof(double))
cdef double* T = <double*>malloc(num_items * sizeof(double))
if mask is not None:
- if mask.size != self._thisptr.fNumItems:
+ if mask.size != curve.fNumItems:
raise ValueError("mask size need to be the same as the number of Items")
for i in range(num_items):
- h2 = self._thisptr.fArray[i].fRate
- t2 = T[i] = (self._thisptr.fArray[i].fDate - self._thisptr.fBaseDate)/365.
+ h2 = curve.fArray[i].fRate
+ t2 = T[i] = (curve.fArray[i].fDate - curve.fBaseDate)/365.
h[i] = (h2 * t2 - h1 * t1) / (t2 - t1)
if mask is None or mask[i]:
h[i] *= (1+epsilon)
@@ -428,11 +430,11 @@ cdef class SpreadCurve(Curve):
cdef double c = 0
cdef TRatePt* update
if inplace:
- update = self._thisptr.fArray
+ update = curve.fArray
else:
- update = sc._thisptr.fArray
+ update = curve.fArray
- for i in range(self._thisptr.fNumItems):
+ for i in range(curve.fNumItems):
c += (T[i] - t1) * h[i]
update[i].fRate = c/T[i]
t1 = T[i]
@@ -443,24 +445,25 @@ cdef class SpreadCurve(Curve):
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 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* 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
- self._T = <double*>malloc(sizeof(double)*n_dates)
+ self._T = <double*>malloc(sizeof(double) * self._ndates)
+ self._ncurves = len(curves)
+ self._curves = <TCurve**>malloc(sizeof(TCurve*) * self._ncurves)
+ cdef size_t i
+
for i, d in enumerate(end_dates):
date = pydate_to_TDate(d)
self._T[i] = (date - base_date_c) / 365.
- self._sc.fArray[i].fDate = date
- self._hazard_rates = hazard_rates
+
+ for i, c in enumerate(curves):
+ self._curves[i] = JpmcdsCopyCurve((<SpreadCurve?>c)._thisptr)
+
self._contingent_leg = JpmcdsCdsContingentLegMake(start_date_c,
end_date_c,
1.,
@@ -483,39 +486,54 @@ cdef class BasketIndex:
def __dealloc__(self):
if self._T is not NULL:
free(self._T)
- JpmcdsFreeTCurve(self._sc)
if self._contingent_leg is not NULL:
free(self._contingent_leg)
JpmcdsFeeLegFree(self._fee_leg)
+ for i in range(self._ncurves):
+ JpmcdsFreeTCurve(self._curves[i])
+ free(self._curves)
- @cython.initializedcheck(False)
+ #@cython.initializedcheck(False)
@cython.boundscheck(False)
def pv(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._hazard_rates.shape[0]
+ cdef np.npy_intp n = self._ncurves
cdef double accrued
- FeeLegAI(self._fee_leg, self._sc.fBaseDate, &accrued)
- cdef size_t i, j
+ 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)
- for i in range(n):
- for j in range(self._sc.fNumItems):
- self._sc.fArray[j].fRate = self._hazard_rates[i,j]
+ cdef TCurve* sc
+ for i in range(self._ncurves):
+ sc = self._curves[i]
JpmcdsContingentLegPV(self._contingent_leg,
- self._sc.fBaseDate,
+ sc.fBaseDate,
value_date_c,
step_in_date_c,
yc._thisptr,
- self._sc,
+ sc,
recovery_rate,
&cl_pv[i])
JpmcdsFeeLegPV(self._fee_leg,
- self._sc.fBaseDate,
+ sc.fBaseDate,
step_in_date_c,
value_date_c,
yc._thisptr,
- self._sc,
+ sc,
True,
&fl_pv[i])
return (fl_pv-accrued, cl_pv)
+
+ @property
+ def curves(self):
+ """returns the list of curves inside the porfolio.
+
+ 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]
+ sc = SpreadCurve.__new__(SpreadCurve)
+ sc._thisptr = c
+ r.append(sc)