summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2019-03-05 14:05:44 -0500
committerGuillaume Horel <guillaume.horel@gmail.com>2019-03-05 14:10:47 -0500
commit110f23e4936178cc2595c0ea2c5fe957b13aeaa1 (patch)
tree72bd6417c3012e4795817d61d0f06cca5d57b739
parenta8af544372950e71c8dcccb7e5034e8f42e6f3af (diff)
downloadpyisda-110f23e4936178cc2595c0ea2c5fe957b13aeaa1.tar.gz
constify
-rw-r--r--pyisda/credit_index.pyx5
-rw-r--r--pyisda/curve.pxd17
-rw-r--r--pyisda/curve.pyx126
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)