summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2018-03-23 13:49:50 -0400
committerGuillaume Horel <guillaume.horel@gmail.com>2018-03-23 14:08:58 -0400
commit4bf3ba9e209310bf0f20ebbef15a14c89c7d5688 (patch)
tree72d24858f2adf98c09c843a73fb7523a56944688
parentf749f287b8f73b66ee34d9101049fc0f3f94aa59 (diff)
downloadpyisda-4bf3ba9e209310bf0f20ebbef15a14c89c7d5688.tar.gz
fix memory leak
-rw-r--r--pyisda/credit_index.pyx178
1 files changed, 98 insertions, 80 deletions
diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx
index 5c5102d..dabed20 100644
--- a/pyisda/credit_index.pyx
+++ b/pyisda/credit_index.pyx
@@ -3,6 +3,7 @@ from libc.stdlib cimport malloc, free
from libc.math cimport nan
from libc.string cimport memcpy, memset
from libcpp.pair cimport pair
+from libcpp.memory cimport unique_ptr
from cython.operator cimport dereference as deref
from cpython cimport PyObject, Py_INCREF
@@ -24,6 +25,9 @@ import warnings
cdef inline shared_ptr[TCurve] make_shared(TCurve* ptr) nogil:
return shared_ptr[TCurve](ptr, JpmcdsFreeTCurve)
+ctypedef TFeeLeg* TFeeLeg_ptr
+ctypedef TContingentLeg* TContingentLeg_ptr
+
cdef TFeeLeg* copyFeeLeg(TFeeLeg* leg) nogil:
cdef TFeeLeg* new_leg = <TFeeLeg*>malloc(sizeof(TFeeLeg))
cdef size_t size = leg.nbDates * sizeof(TDate)
@@ -210,27 +214,12 @@ cdef class CreditIndex(CurveList):
sizeof(TContingentLeg))
self.fee_legs = <TFeeLeg**> malloc(self._maturities.size() *
sizeof(TFeeLeg))
- cdef TStubMethod stub_type
- if JpmcdsStringToStubMethod(b"f/s", &stub_type) != 0:
- raise ValueError("can't convert stub")
cdef size_t i
+ cdef pair[TContingentLeg_ptr, TFeeLeg_ptr] r
for i in range(self._maturities.size()):
- self.contingent_legs[i] = JpmcdsCdsContingentLegMake(self.start_date,
- self._maturities[i],
- 1.,
- True)
-
- self.fee_legs[i] = JpmcdsCdsFeeLegMake(self.start_date,
- self._maturities[i],
- True,
- NULL,
- &stub_type,
- 1.,
- 1.0,
- 3, #ACT_360
- <long>'M', # MODIFIED
- b'NONE',
- True)
+ r = get_legs(self._maturities[i], self.start_date)
+ self.contingent_legs[i] = r.first
+ self.fee_legs[i] = r.second
def __dealloc__(self):
if self.contingent_legs is not NULL:
@@ -369,11 +358,13 @@ cdef class CreditIndex(CurveList):
TDate maturity_c = pydate_to_TDate(maturity)
unsigned long mask = 0
vector[double] h
- pair[TContingentLeg,TFeeLeg] legs = get_legs(maturity_c,
- self.start_date,
- self.contingent_legs,
- self.fee_legs,
- self._maturities)
+ pair[TContingentLeg_ptr,TFeeLeg_ptr] legs
+ int i = get_maturity_index(maturity_c, self._maturities)
+ if i == -1:
+ legs = get_legs(maturity_c, self.start_date)
+ else:
+ legs.first = self.contingent_legs[i]
+ legs.second = self.fee_legs[i]
if epsilon != 0.:
mask = fill_mask(maturity_c, self._maturities, self._curves[0])
@@ -384,7 +375,9 @@ cdef class CreditIndex(CurveList):
r = pv(self._curves, self.base_date, step_in_date_c, value_date_c,
yc._thisptr.get(), legs, recovery_rate, fixed_rate,
self._weights, epsilon, h, self.T, mask)
-
+ if i == -1:
+ free(legs.first)
+ JpmcdsFeeLegFree(legs.second)
return r
def theta(self, step_in_date, value_date, maturity, YieldCurve yc not None,
@@ -393,32 +386,47 @@ cdef class CreditIndex(CurveList):
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)
+ TDate temp
vector[double] h
- pair[TContingentLeg,TFeeLeg] legs
+ pair[TContingentLeg_ptr,TFeeLeg_ptr] legs
TDateInterval ivl
+ int i
+ JpmcdsMakeDateInterval(-1, "Y", &ivl)
+ JpmcdsDtFwdAny(maturity_c, &ivl, &temp)
+ if temp < step_in_date_c:
+ return nan("")
if old_pv != old_pv:
- legs = get_legs(maturity_c,
- self.start_date,
- self.contingent_legs,
- self.fee_legs,
- self._maturities)
+ i = get_maturity_index(maturity_c, self._maturities)
+ if i == -1:
+ legs = get_legs(maturity_c,
+ self.start_date)
+ else:
+ legs.first = self.contingent_legs[i]
+ legs.second = self.fee_legs[i]
old_pv = pv(self._curves, self.base_date, step_in_date_c,
value_date_c, yc._thisptr.get(), legs,
recovery_rate, fixed_rate, self._weights,
0., h, self.T, 0)
+ if i == -1:
+ free(legs.first)
+ JpmcdsFeeLegFree(legs.second)
+ maturity_c = temp
+ i = get_maturity_index(maturity_c, self._maturities)
+ if i == -1:
+ legs = get_legs(maturity_c,
+ self.start_date)
+ else:
+ legs.first = self.contingent_legs[i]
+ legs.second = self.fee_legs[i]
- maturity_c = pydate_to_TDate(maturity)
- JpmcdsMakeDateInterval(-1, "Y", &ivl)
- JpmcdsDtFwdAny(maturity_c, &ivl, &maturity_c)
- legs = get_legs(maturity_c,
- self.start_date,
- self.contingent_legs,
- self.fee_legs,
- self._maturities)
- return old_pv - pv(self._curves, self.base_date, step_in_date_c, value_date_c,
- yc._thisptr.get(), legs, recovery_rate, fixed_rate,
- self._weights, 0., h, self.T, 0) + fixed_rate
+ cdef r = old_pv - pv(self._curves, self.base_date, step_in_date_c, value_date_c,
+ yc._thisptr.get(), legs, recovery_rate, fixed_rate,
+ self._weights, 0., h, self.T, 0) + fixed_rate
+ if i == -1:
+ free(legs.first)
+ JpmcdsFeeLegFree(legs.second)
+ return r
def duration(self, step_in_date, value_date, maturity, YieldCurve yc not None):
@@ -427,14 +435,26 @@ cdef class CreditIndex(CurveList):
TDate value_date_c = pydate_to_TDate(value_date)
TDate maturity_c = pydate_to_TDate(maturity)
TFeeLeg* fl
+ TStubMethod stub_type
size_t i
+ int found
- for i in range(self._maturities.size()):
- if self._maturities[i] == maturity_c:
- fl = self.fee_legs[i]
- break
+ found = get_maturity_index(maturity_c, self._maturities)
+ if found == -1:
+ JpmcdsStringToStubMethod(b"f/s", &stub_type)
+ fl = JpmcdsCdsFeeLegMake(self.start_date,
+ maturity_c,
+ True,
+ NULL,
+ &stub_type,
+ 1.,
+ 1.0,
+ 3, #ACT_360
+ <long>'M', # MODIFIED
+ b'NONE',
+ True)
else:
- raise ValueError("maturity is not correct")
+ fl = self.fee_legs[found]
cdef:
double fl_pv, r = 0
@@ -452,6 +472,8 @@ cdef class CreditIndex(CurveList):
&fl_pv)
r += self._weights[i] * fl_pv
i += 1
+ if found == -1:
+ JpmcdsFeeLegFree(fl)
return r
@property
@@ -521,38 +543,36 @@ cdef unsigned long fill_mask(const TDate maturity, const vector[TDate]& maturiti
mask |= 1 << i
return mask
-cdef pair[TContingentLeg,TFeeLeg] get_legs(TDate maturity,
- TDate start_date,
- TContingentLeg** contingent_legs,
- TFeeLeg** fee_legs,
- vector[TDate]& maturities) nogil:
- cdef:
- pair[TContingentLeg,TFeeLeg] r
- TStubMethod stub_type
-
+cdef inline int get_maturity_index(TDate maturity, const vector[TDate]& maturities):
+ cdef size_t i
for i in range(maturities.size()):
if maturities[i] == maturity:
break
else:
- JpmcdsStringToStubMethod(b"f/s", &stub_type)
- r.first = deref(JpmcdsCdsContingentLegMake(start_date,
- maturity,
- 1.,
- True))
- r.second = deref(JpmcdsCdsFeeLegMake(start_date,
- maturity,
- True,
- NULL,
- &stub_type,
- 1.,
- 1.0,
- 3, #ACT_360
- <long>'M', # MODIFIED
- b'NONE',
- True))
- return r
- r.first = deref(contingent_legs[i])
- r.second = deref(fee_legs[i])
+ return -1
+ return i
+
+cdef pair[TContingentLeg_ptr,TFeeLeg_ptr] get_legs(TDate maturity,
+ TDate start_date) nogil:
+ cdef:
+ pair[TContingentLeg_ptr,TFeeLeg_ptr] r
+ TStubMethod stub_type
+ JpmcdsStringToStubMethod(b"f/s", &stub_type)
+ r.first = JpmcdsCdsContingentLegMake(start_date,
+ maturity,
+ 1.,
+ True)
+ r.second = JpmcdsCdsFeeLegMake(start_date,
+ maturity,
+ True,
+ NULL,
+ &stub_type,
+ 1.,
+ 1.0,
+ 3, #ACT_360
+ <long>'M', # MODIFIED
+ b'NONE',
+ True)
return r
cdef double pv(vector[shared_ptr[TCurve]]& curves,
@@ -560,7 +580,7 @@ cdef double pv(vector[shared_ptr[TCurve]]& curves,
TDate step_in_date,
TDate value_date,
TCurve* yc,
- pair[TContingentLeg,TFeeLeg]& legs,
+ pair[TContingentLeg_ptr,TFeeLeg_ptr]& legs,
double recovery_rate,
double fixed_rate,
vector[double]& weights,
@@ -573,8 +593,6 @@ cdef double pv(vector[shared_ptr[TCurve]]& curves,
TCurve* tweaked_curve
shared_ptr[TCurve] c
size_t i = 0
- TFeeLeg* fl
- TContingentLeg* cl
if epsilon != 0.:
tweaked_curve = JpmcdsCopyCurve(curves[0].get())
@@ -584,7 +602,7 @@ cdef double pv(vector[shared_ptr[TCurve]]& curves,
tweak_curve(c.get(), tweaked_curve, epsilon, h, T, mask)
else:
tweaked_curve = c.get()
- JpmcdsContingentLegPV(&legs.first,
+ JpmcdsContingentLegPV(legs.first,
base_date,
value_date,
step_in_date,
@@ -593,7 +611,7 @@ cdef double pv(vector[shared_ptr[TCurve]]& curves,
recovery_rate,
&cl_pv)
- JpmcdsFeeLegPV(&legs.second,
+ JpmcdsFeeLegPV(legs.second,
base_date,
step_in_date,
value_date,