diff options
| author | Guillaume Horel <guillaume.horel@gmail.com> | 2019-03-05 14:05:44 -0500 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@gmail.com> | 2019-03-05 14:10:47 -0500 |
| commit | 110f23e4936178cc2595c0ea2c5fe957b13aeaa1 (patch) | |
| tree | 72bd6417c3012e4795817d61d0f06cca5d57b739 | |
| parent | a8af544372950e71c8dcccb7e5034e8f42e6f3af (diff) | |
| download | pyisda-110f23e4936178cc2595c0ea2c5fe957b13aeaa1.tar.gz | |
constify
| -rw-r--r-- | pyisda/credit_index.pyx | 5 | ||||
| -rw-r--r-- | pyisda/curve.pxd | 17 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 126 |
3 files changed, 72 insertions, 76 deletions
diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx index 74bd409..a7a05d0 100644 --- a/pyisda/credit_index.pyx +++ b/pyisda/credit_index.pyx @@ -206,7 +206,7 @@ cdef class CurveList: @cython.auto_pickle(False) cdef class CreditIndex(CurveList): def __init__(self, start_date, maturities, list curves, value_date=None): - CurveList.__init__(self, curves, value_date) + super().__init__(curves, value_date) self.start_date = pydate_to_TDate(start_date) for d in maturities: self._maturities.push_back(pydate_to_TDate(d)) @@ -545,7 +545,8 @@ cdef class CreditIndex(CurveList): if inplace: for i in range(self._curves.size()): sc_orig = self._curves[i].get() - tweak_curve(sc_orig, sc_orig, epsilon, mask) + sc_copy = sc_orig + tweak_curve(sc_orig, sc_copy, epsilon, mask) else: for i in range(self._curves.size()): sc_orig = self._curves[i].get() diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index de79d38..d3ee92e 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -43,9 +43,9 @@ cdef extern from "farmhash.h" namespace 'util' nogil: uint64_t Hash64(const char *buff, size_t len) uint64_t Hash64WithSeed(const char *buff, size_t len, uint64_t len) -cdef inline size_t TCurve_size(int num_items) nogil: +cdef inline size_t TCurve_size(const TCurve* curve) nogil: return sizeof(int) + sizeof(TDate) + sizeof(double) + \ - sizeof(long) + sizeof(TRatePt) * num_items + sizeof(long) + sizeof(TRatePt) * curve.fNumItems cdef inline unsigned char* serialize(const TCurve* curve, unsigned char* buf) nogil: memcpy(buf, &(curve.fNumItems), sizeof(curve.fNumItems)) @@ -66,7 +66,7 @@ cdef inline void serialize_vector(const vector[TDate]& v, unsigned char* cursor) memcpy(cursor, v.data(), sizeof(TDate) * v.size()) -cdef inline unsigned char* deserialize(unsigned char* buf, TCurve* curve) nogil: +cdef inline const unsigned char* deserialize(const unsigned char* buf, TCurve* curve) nogil: memcpy(&curve.fNumItems, buf, sizeof(curve.fNumItems)) buf += sizeof(curve.fNumItems) cdef size_t array_size = sizeof(TRatePt) * curve.fNumItems @@ -168,7 +168,7 @@ cdef extern from "isda/tcurve.h" nogil: int numPts, double basis, long dayCountConv) - TCurve* JpmcdsCopyCurve(TCurve* curve) + TCurve* JpmcdsCopyCurve(const TCurve* curve) TDate* JpmcdsDatesFromCurve(TCurve* curve) TCurve* JpmcdsNewTCurve(TDate baseDate, # (I) Base date int numPts, # (I) Length of dates & rates @@ -181,14 +181,15 @@ cdef extern from "isda/cxzerocurve.h" nogil: double JpmcdsLogForwardZeroPrice(const TCurve*, TDate startDate, TDate maturityDate) double JpmcdsZeroRate(TCurve* curve, TDate date) -cdef double survival_prob(TCurve* curve, TDate start_date, TDate maturity_date, double eps) nogil +cdef double survival_prob(const TCurve* curve, TDate start_date, + TDate maturity_date, double eps) nogil -cdef extern from "isda/cfinanci.h": +cdef extern from "isda/cfinanci.h" nogil: int JpmcdsDiscountToRateYearFrac(double discount, # (I) Discount factor double yearFraction, # (I) See JpmcdsDayCountFraction double basis, # (I) Basis for the rate - double *rate) nogil -cdef extern from "isda/macros.h": + double *rate) +cdef extern from "isda/macros.h" nogil: cdef double JPMCDS_MAX_RATE cdef enum Basis: diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index cb472e2..c08140a 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -60,7 +60,7 @@ cdef class Curve(object): cdef: size_t curve_size = self.size() unsigned char* buf = <unsigned char*>malloc(curve_size * sizeof(unsigned char)) - serialize(self.curve(), buf) + serialize(get_TCurve(self), buf) cdef bytes r = buf[:curve_size] free(buf) return r @@ -70,10 +70,10 @@ cdef class Curve(object): TCurve* curve = <TCurve*>malloc(sizeof(TCurve)) unsigned char* cursor = state deserialize(cursor, curve) - self._thisptr = make_shared(curve) + self._thisptr.reset(curve, JpmcdsFreeTCurve) - cdef size_t size(self): - return TCurve_size(self._thisptr.get().fNumItems) + cdef size_t size(self) nogil: + return TCurve_size(get_TCurve(self)) @classmethod def from_bytes(cls, object state): @@ -88,12 +88,12 @@ cdef class Curve(object): else: cursor = <bytes?>state deserialize(cursor, curve) - instance._thisptr = make_shared(curve) + instance._thisptr.reset(curve, JpmcdsFreeTCurve) return instance def __hash__(self): cdef: - const TCurve* curve = self.curve() + const TCurve* curve = get_TCurve(self) size_t curve_size = self.size() unsigned char* buf = <unsigned char*>malloc(curve_size * sizeof(unsigned char)) serialize(curve, buf) @@ -109,22 +109,16 @@ cdef class Curve(object): dict contains `base_date`, `basis`, `day_count_counvention` and `data` """ - cdef const TCurve* curve = self.curve() + cdef const TCurve* curve = get_TCurve(self) return {'base_date': self.base_date, 'basis': curve.fBasis, 'day_count_convention': dcc_tostring(curve.fDayCountConv), 'data': fArray_to_list(curve.fArray, curve.fNumItems)} - cdef const TCurve* curve(self): - if not self._thisptr: - raise ValueError("Curve is not initialized") - else: - return self._thisptr.get() - @cython.boundscheck(False) @cython.cdivision(True) def to_series(self, bint forward=True): - cdef const TCurve* curve = self.curve() + cdef const TCurve* curve = get_TCurve(self) cdef np.npy_intp n = curve.fNumItems cdef np.ndarray[np.float64_t,ndim=1] h = np.PyArray_EMPTY(1, &n, np.NPY_DOUBLE, 0) cdef np.ndarray[np.int64_t,ndim=1] d = np.PyArray_EMPTY(1, &n, np.NPY_INT64, 0) @@ -157,16 +151,17 @@ cdef class Curve(object): def __iter__(self): cdef: size_t i = 0 - TRatePt* it = self.curve().fArray - for i in range(self.curve().fNumItems): + TRatePt* it = get_TCurve(self).fArray + for i in range(get_TCurve(self).fNumItems): yield (TDate_to_pydate(it[i].fDate), it[i].fRate) def __len__(self): - return self.curve().fNumItems + return get_TCurve(self).fNumItems def __deepcopy__(self, dict memo): cdef Curve sc = Curve.__new__(Curve) - sc._thisptr = make_shared(JpmcdsCopyCurve(<TCurve*>self.curve())) + sc._thisptr.reset(JpmcdsCopyCurve(get_TCurve(self)), + JpmcdsFreeTCurve) memo[id(self)] = sc return sc @@ -174,7 +169,7 @@ cdef class Curve(object): @cython.cdivision(True) def forward_hazard_rates(self): cdef double t1, h1, t2, h2 - cdef const TCurve* curve = self.curve() + cdef const TCurve* curve = get_TCurve(self) cdef np.npy_intp shape = curve.fNumItems t1 = 0 h1 = 0 @@ -205,7 +200,7 @@ cdef class Curve(object): @property def base_date(self): - return TDate_to_pydate(self.curve().fBaseDate) + return TDate_to_pydate(get_TCurve(self).fBaseDate) def __forward_zero_price(self, d2, d1=None): """ computes the forward zero price at a given date. @@ -218,7 +213,7 @@ cdef class Curve(object): ------- float """ - cdef TCurve* curve = <TCurve*>self.curve() + cdef const TCurve* curve = get_TCurve(self) if d1 is None: return JpmcdsForwardZeroPrice(curve, curve.fBaseDate, pydate_to_TDate(d2)) @@ -312,19 +307,19 @@ cdef class YieldCurve(Curve): if JpmcdsDateIntervalToFreq(&ivl, &float_freq) != SUCCESS: raise ValueError - self._thisptr = make_shared(JpmcdsBuildIRZeroCurve( + self._thisptr.reset(JpmcdsBuildIRZeroCurve( value_date, types_bytes, self.dates.data(), &rates[0], self.dates.size(), dcc(mm_dcc), <long> fixed_freq, <long> float_freq, dcc(fixed_swap_dcc), dcc(float_swap_dcc), bad_day_conv, b"None" - )) + ), JpmcdsFreeTCurve) - cdef size_t size(self): + cdef size_t size(self) nogil: return Curve.size(self) + sizeof(size_t) + sizeof(TDate) * self.dates.size() def __getstate__(self): cdef: - const TCurve* curve = self.curve() + const TCurve* curve = get_TCurve(self) size_t buf_size = self.size() unsigned char* buf = <unsigned char*>malloc(buf_size) unsigned char* cursor = serialize(curve, buf) @@ -337,11 +332,11 @@ cdef class YieldCurve(Curve): def __setstate__(self, bytes state): cdef: TCurve* curve = <TCurve*>malloc(sizeof(TCurve)) - unsigned char* cursor = state + const unsigned char* cursor = state size_t num_instr cursor = deserialize(cursor, curve) - self._thisptr = make_shared(curve) + self._thisptr.reset(curve, JpmcdsFreeTCurve) memcpy(&num_instr, cursor, sizeof(size_t)) cursor += sizeof(size_t) self.dates = vector[TDate](num_instr) @@ -349,7 +344,7 @@ cdef class YieldCurve(Curve): def __deepcopy__(self, dict memo): cdef YieldCurve yc = YieldCurve.__new__(YieldCurve) - yc._thisptr = make_shared(JpmcdsCopyCurve(self._thisptr.get())) + yc._thisptr.reset(JpmcdsCopyCurve(get_TCurve(self)), JpmcdsFreeTCurve) yc.dates = vector[TDate](self.dates) memo[id(self)] = yc return yc @@ -361,7 +356,7 @@ cdef class YieldCurve(Curve): TCurve* curve = <TCurve*>malloc(sizeof(TCurve)) size_t num_instr Py_buffer* py_buf - unsigned char* cursor + const unsigned char* cursor if PyMemoryView_Check(state): py_buf = PyMemoryView_GET_BUFFER(state) @@ -371,7 +366,7 @@ cdef class YieldCurve(Curve): cursor = deserialize(cursor, curve) - instance._thisptr = make_shared(curve) + instance._thisptr.reset(curve, JpmcdsFreeTCurve) memcpy(&num_instr, cursor, sizeof(size_t)) cursor += sizeof(size_t) instance.dates = vector[TDate](num_instr) @@ -380,7 +375,7 @@ cdef class YieldCurve(Curve): def __hash__(self): cdef: - const TCurve* curve = self.curve() + const TCurve* curve = get_TCurve(self) size_t buf_size = self.size() size_t size unsigned char* buf = <unsigned char*>malloc(buf_size) @@ -407,9 +402,9 @@ cdef class YieldCurve(Curve): JpmcdsDiscountToRateYearFrac(dfs[i], <double>(yc.dates[i]-base_date_c)/365., <double>1, &rates[i]) - yc._thisptr = make_shared( + yc._thisptr.reset( JpmcdsMakeTCurve(base_date_c, yc.dates.data(), rates, dfs.shape[0], - <double>1, dcc(day_count_conv))) + <double>1, dcc(day_count_conv)), JpmcdsFreeTCurve) return yc discount_factor = Curve.__forward_zero_price @@ -439,9 +434,9 @@ cdef class YieldCurve(Curve): df, <double>(self.dates[i] - forward_date_c)/365., <double>1, &rates[k]) i += 1 - yc._thisptr = make_shared(JpmcdsMakeTCurve( + yc._thisptr.reset(JpmcdsMakeTCurve( forward_date_c, yc.dates.data(), rates, yc.dates.size(), - <double>1, self._thisptr.get().fDayCountConv)) + <double>1, self._thisptr.get().fDayCountConv), JpmcdsFreeTCurve) return yc @cython.cdivision(True) @@ -525,7 +520,7 @@ cdef class SpreadCurve(Curve): cdef size_t i cdef bint freeup = False - if cash_settle_date_c < yc._thisptr.get().fBaseDate: + if cash_settle_date_c < get_TCurve(yc).fBaseDate: raise ValueError("cash_settle_date: {0} is anterior to yc's base_date: {1}". format(cash_settle_date, yc.base_date)) if defaulted is None: @@ -569,7 +564,7 @@ cdef class SpreadCurve(Curve): with nogil: if self.defaulted == -1: curve = JpmcdsCleanSpreadCurve(today_c, - yc._thisptr.get(), + <TCurve*>get_TCurve(yc), start_date_c, step_in_date_c, cash_settle_date_c, @@ -619,52 +614,54 @@ cdef class SpreadCurve(Curve): survival_probability = Curve.__forward_zero_price - cdef size_t size(self): - cdef TCurve* curve = self._thisptr.get() + cdef size_t size(self) nogil: + cdef const TCurve* curve = get_TCurve(self) return Curve.size(self) + curve.fNumItems * sizeof(double) + \ - sizeof(size_t) + sizeof(TDate) + 16 + sizeof(TDate) + self.name.get().size() def __getstate__(self): cdef: - const TCurve* curve = self.curve() + const TCurve* curve = get_TCurve(self) size_t buf_size = self.size() size_t size_recovery = curve.fNumItems * sizeof(double) unsigned char* buf = <unsigned char*>malloc(buf_size) unsigned char* cursor = serialize(curve, buf) + memcpy(cursor, self.recovery_rates.get(), size_recovery) cursor += size_recovery memcpy(cursor, &self.defaulted, sizeof(TDate)) - strcpy(<char*>cursor, self.ticker.c_str()) + cursor += sizeof(TDate) + self.name.get().serialize(cursor) + cdef bytes r = buf[:buf_size] free(buf) - return buf[:buf_size] + return r def __setstate__(self, bytes state): cdef: TCurve* curve = <TCurve*>malloc(sizeof(TCurve)) - unsigned char* cursor = state - size_t ticker_length, recovery_size + const unsigned char* cursor = state + size_t recovery_size double* recovery_rates cursor = deserialize(cursor, curve) - self._thisptr = make_shared(curve) + self._thisptr.reset(curve, JpmcdsFreeTCurve) recovery_size = curve.fNumItems * sizeof(double) recovery_rates = <double*>malloc(recovery_size) memcpy(recovery_rates, cursor, recovery_size) cursor += recovery_size self.recovery_rates.reset(recovery_rates, double_free) - cursor += recovery_size memcpy(&self.defaulted, cursor, sizeof(TDate)) cursor += sizeof(TDate) - self.ticker = string(<const char*>cursor) + self.name = make_shared[CurveName](cursor) def __deepcopy__(self, dict memo): cdef SpreadCurve sc = SpreadCurve.__new__(SpreadCurve) - cdef TCurve* curve = self._thisptr.get() - cdef size_t size = curve.fNumItems * sizeof(double) - sc._thisptr = make_shared(JpmcdsCopyCurve(<TCurve*>curve)) - sc.ticker = self.ticker - sc.recovery_rates = shared_ptr[double](<double*>malloc(size), double_free) - memcpy(sc.recovery_rates.get(), self.recovery_rates.get(), size) + cdef const TCurve* curve = get_TCurve(self) + cdef size_t recovery_size = curve.fNumItems * sizeof(double) + sc._thisptr.reset(JpmcdsCopyCurve(curve), JpmcdsFreeTCurve) + sc.name = make_shared[CurveName](deref(self.name)) + sc.recovery_rates = shared_ptr[double](<double*>malloc(recovery_size), double_free) + memcpy(sc.recovery_rates.get(), self.recovery_rates.get(), recovery_size) sc.defaulted = self.defaulted memo[id(self)] = sc return sc @@ -682,7 +679,7 @@ cdef class SpreadCurve(Curve): def from_bytes(cls, bytes state): cdef: SpreadCurve instance = SpreadCurve.__new__(SpreadCurve) - unsigned char* cursor + const unsigned char* cursor TCurve* curve = <TCurve*>malloc(sizeof(TCurve)) size_t recovery_size Py_buffer* py_buf @@ -694,7 +691,7 @@ cdef class SpreadCurve(Curve): cursor = <bytes?>state cursor = deserialize(cursor, curve) - instance._thisptr = make_shared(curve) + instance._thisptr.reset(curve, JpmcdsFreeTCurve) recovery_size = curve.fNumItems * sizeof(double) instance.recovery_rates = shared_ptr[double](<double*>malloc(recovery_size), double_free) @@ -775,27 +772,24 @@ cdef class SpreadCurve(Curve): in the mask. """ cdef: + const TCurve* curve_orig = get_TCurve(self) TCurve* curve_tweaked SpreadCurve sc - int num_items = self._thisptr.get().fNumItems - vector[double] h - vector[double] T - size_t i + int num_items = curve_orig.fNumItems if not inplace: sc = SpreadCurve.__new__(SpreadCurve) - curve_tweaked = JpmcdsCopyCurve(self._thisptr.get()) - sc._thisptr = make_shared(curve_tweaked) - sc.ticker = self.ticker + curve_tweaked = JpmcdsCopyCurve(curve_orig) + sc._thisptr.reset(curve_tweaked, JpmcdsFreeTCurve) + sc.name = make_shared[CurveName](deref(self.name)) memcpy(sc.recovery_rates.get(), self.recovery_rates.get(), num_items * sizeof(double)) - #sc.recovery_rates = self.recovery_rates else: sc = self - curve_tweaked = self._thisptr.get() + curve_tweaked = <TCurve*>curve_orig if mask != 0: - tweak_curve(self._thisptr.get(), curve_tweaked, epsilon, mask) + tweak_curve(curve_orig, curve_tweaked, epsilon, mask) return sc @cython.boundscheck(False) |
