summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyisda/credit_index.pyx36
-rw-r--r--pyisda/curve.pxd1
2 files changed, 35 insertions, 2 deletions
diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx
index 3238f2f..163f2f1 100644
--- a/pyisda/credit_index.pyx
+++ b/pyisda/credit_index.pyx
@@ -1,7 +1,7 @@
#cython: cdivision=True, boundscheck=False
from libc.stdlib cimport malloc, free
from libc.math cimport nan
-from libc.string cimport memcpy
+from libc.string cimport memcpy, memset
from libcpp.pair cimport pair
from cython.operator cimport dereference as deref
from cpython cimport PyObject, Py_INCREF
@@ -10,7 +10,8 @@ cimport cython
from legs cimport (JpmcdsCdsContingentLegMake, JpmcdsCdsFeeLegMake,
JpmcdsContingentLegPV, JpmcdsFeeLegPV, FeeLegAI, JpmcdsFeeLegFree)
from curve cimport (SpreadCurve, JpmcdsCopyCurve, tweak_curve, YieldCurve,
- JpmcdsFreeTCurve, JpmcdsForwardZeroPrice)
+ JpmcdsFreeTCurve, JpmcdsForwardZeroPrice, Hash64WithSeed,
+ Hash64, uint64_t, TCurve_size, serialize)
from date cimport (pydate_to_TDate, TDate_to_pydate, ACT_365F, JpmcdsDtFwdAny,
TDateInterval, JpmcdsMakeDateInterval)
from cdsone cimport JpmcdsStringToStubMethod, TStubMethod
@@ -279,6 +280,37 @@ cdef class CreditIndex(CurveList):
return (self.__class__,
(TDate_to_pydate(self.start_date), self.maturities, self.curves, self.weights))
+ def __hash__(self):
+ cdef:
+ TCurve* curve = self._curves[0].get()
+ size_t size = TCurve_size(curve.fNumItems)
+ size_t buf_size = size + sizeof(size_t) + curve.fNumItems * sizeof(double) + 8
+ unsigned char* buf = <unsigned char*>malloc(buf_size)
+ unsigned char* cursor
+ unsigned char* start = buf + size
+ size_t i
+ uint64_t h = 0
+ pair[string, size_t] p
+
+ for p in self.tickers:
+ cursor = start
+ curve = self._curves[p.second].get()
+ serialize(curve, buf)
+ p.first.copy(<char*>cursor, p.first.length(), 0)
+ #0 padding
+ if p.first.length() < 8:
+ memset(cursor + p.first.length(), 0, 8 - p.first.length())
+ cursor += 8
+ memcpy(cursor, self.recovery_rates[p.second].get(), curve.fNumItems * sizeof(double))
+ h ^= Hash64(<char*>buf, buf_size)
+
+ free(buf)
+ h = Hash64WithSeed(<char*>&self.start_date, sizeof(TDate), h)
+ h = Hash64WithSeed(<char*>self._maturities.data(), sizeof(TDate) * self._maturities.size(), h)
+ h = Hash64WithSeed(<char*>self._weights.data(), sizeof(double) * self._weights.size(), h)
+ return h
+
+
#@cython.initializedcheck(False)
def pv_vec(self, step_in_date, value_date, YieldCurve yc, double recovery_rate):
cdef:
diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd
index 269199c..8d62d65 100644
--- a/pyisda/curve.pxd
+++ b/pyisda/curve.pxd
@@ -41,6 +41,7 @@ cdef extern from "isda/bastypes.h":
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:
return sizeof(int) + sizeof(TDate) + sizeof(double) + \