diff options
| author | Guillaume Horel <guillaume.horel@gmail.com> | 2018-10-26 16:06:57 -0400 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@gmail.com> | 2019-02-22 13:40:20 -0500 |
| commit | 28a13d3d95cf70f8bdd41ad6b930e038cd8de2c5 (patch) | |
| tree | 5abac8aebb1d900bf518919ab13935222ed71b10 | |
| parent | 3446da1875c29d5cba19896d8efcb5d899ade36d (diff) | |
| download | pyisda-28a13d3d95cf70f8bdd41ad6b930e038cd8de2c5.tar.gz | |
it compiles
| -rw-r--r-- | pyisda/_curve.pxd | 14 | ||||
| -rw-r--r-- | pyisda/credit_index.pyx | 6 | ||||
| -rw-r--r-- | pyisda/curve.pxd | 8 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 124 |
4 files changed, 55 insertions, 97 deletions
diff --git a/pyisda/_curve.pxd b/pyisda/_curve.pxd index a3ae417..5d5a003 100644 --- a/pyisda/_curve.pxd +++ b/pyisda/_curve.pxd @@ -14,21 +14,21 @@ cdef extern from "isda/bastypes.h": TDate fDate double fRate -cdef extern from "c_layer/curve.hpp" namespace "pyisda" nogil: +cdef extern from "curve.hpp" namespace "pyisda" nogil: cdef cppclass Curve: Curve(TCurve*) Curve(const TCurve&) unsigned char* serialize(unsigned char*) TCurve* operator() - double zeroRate(TDate d) - double zeroRate(TDate d1, TDate d2) - void tweak(double epsilon, unsigned long mask) + double zeroPrice(TDate d) + double zeroPrice(TDate d1, TDate d2) + void tweak_mask "tweak" (double epsilon, unsigned long mask) void tweak(double epsilon) @staticmethod - void tweak(const TCurve*, double epsilon, unsigned long mask) + void tweak_mask_ "tweak" (const TCurve*, double epsilon, unsigned long mask) @staticmethod - void tweak(const TCurve*, double epsilon) + void tweak_ "tweak" (const TCurve*, double epsilon) double survivalProb(const TDate, const TDate) double survivalProb(const TDate, const TDate, double eps) size_t size() @@ -41,5 +41,5 @@ cdef extern from "c_layer/curve.hpp" namespace "pyisda" nogil: cdef cppclass SpreadCurve(Curve): vector[double] recovery_rates SpreadCurve(const SpreadCurve&) - SpredCurve(TCurve* const ptr, vector[double]&, ticker) + SpreadCurve(TCurve* const ptr, vector[double]&, string ticker) string ticker diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx index 88c51e6..75c1270 100644 --- a/pyisda/credit_index.pyx +++ b/pyisda/credit_index.pyx @@ -497,12 +497,12 @@ cdef class CreditIndex(CurveList): size_t i if inplace: for i in range(self._curves.size()): - (<_curve.SpreadCurve*>self._curves[i].get()).tweak(epsilon, mask) + self._curves[i].get().tweak_mask(epsilon, mask) else: for i in range(self._curves.size()): sc_copy = new _curve.SpreadCurve( deref(<_curve.SpreadCurve*>(self._curves[i].get()))) - sc_copy.tweak(epsilon, mask) + sc_copy.tweak_mask(epsilon, mask) self._curves[i].reset(sc_copy) @@ -645,7 +645,7 @@ cdef double pv(const vector[shared_ptr[Curve]]& curves, for i in prange(curves.size()): curve = <_curve.SpreadCurve*>(curves[i].get()) recovery_rate = curve.recovery_rates.data() - _curve.Curve.tweak(tweaked_curve, epsilon, mask) + _curve.Curve.tweak_mask_(tweaked_curve, epsilon, mask) # FIXME: do something better if isnan(deref(recovery_rate)): preinc(recovery_rate) diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index 2b8ee47..a5c1144 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -4,10 +4,11 @@ from libcpp.vector cimport vector from libcpp cimport bool from libcpp.string cimport string from libcpp.memory cimport shared_ptr -from libc.string cimport memcpy -from libc.stdlib cimport malloc, calloc, free +from libcpp.vector cimport vector +from libc.stdlib cimport malloc, free from libc.stdint cimport uint64_t -from libcpp.memory cimport shared_ptr +from libc.string cimport memcpy + from ._curve cimport TCurve, TRatePt from . cimport _curve @@ -198,7 +199,6 @@ cdef class Curve: cdef class YieldCurve(Curve): cdef _curve.YieldCurve* get_yieldcurve(self) nogil - cdef vector[TDate]& dates(self) cdef class SpreadCurve(Curve): cdef _curve.SpreadCurve* get_spreadcurve(self) nogil diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index 577f10c..31f8a1b 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -11,7 +11,7 @@ from .cdsone cimport JpmcdsStringToStubMethod, TStubMethod from .legs cimport (JpmcdsCdsContingentLegMake, JpmcdsCdsFeeLegMake, JpmcdsContingentLegPV, JpmcdsFeeLegPV, FeeLegAI, JpmcdsFeeLegFree) -from libcpp.memory cimport make_shared, static_pointer_cast +from libcpp.memory cimport make_shared cimport cython cimport numpy as np import numpy as np @@ -32,32 +32,6 @@ cdef extern from "numpy/arrayobject.h": cdef int SUCCESS = 0 -# cdef inline shared_ptr[TCurve] make_shared(TCurve* ptr) nogil: -# return shared_ptr[TCurve](ptr, JpmcdsFreeTCurve) - -cdef inline void double_free(double* ptr) nogil: - free(ptr) - - -# cdef double survival_prob(TCurve* curve, TDate start_date, TDate maturity_date, double eps) nogil: -# cdef: -# double lambda1, lambda2 -# double t1, t2, u -# if start_date == curve.fBaseDate: -# lambda2 = JpmcdsZeroRate(curve, maturity_date) -# t2 = (maturity_date - curve.fBaseDate) / 365. -# if eps != 0.: -# lambda2 *= (1 + eps) -# return exp(-lambda2 * t2) -# else: -# lambda1 = JpmcdsZeroRate(curve, start_date) -# lambda2 = JpmcdsZeroRate(curve, maturity_date) -# t1 = (start_date - curve.fBaseDate) / 365. -# t2 = (maturity_date - curve.fBaseDate) / 365. -# u = lambda1 * t1 - lambda2 * t2 -# if eps != 0.: -# u *= (1 + eps) -# return exp(u) cdef class Curve(object): @@ -93,7 +67,7 @@ cdef class Curve(object): else: cursor = <bytes?>state deserialize(cursor, curve) - instance._thisptr = shared_ptr[_curve.Curve](curve) + instance._thisptr = make_shared[_curve.Curve](curve) return instance def __hash__(self): @@ -218,10 +192,10 @@ cdef class Curve(object): raise ValueError('curve is empty') cdef TDate start_date if d1 is None: - return self._thisptr.get().zeroRate(pydate_to_TDate(d2)) + return self._thisptr.get().zeroPrice(pydate_to_TDate(d2)) else: - return self._thisptr.get().zeroRate(pydate_to_TDate(d1), - pydate_to_TDate(d2)) + return self._thisptr.get().zeroPrice(pydate_to_TDate(d1), + pydate_to_TDate(d2)) cdef fArray_to_list(TRatePt* fArray, int fNumItems): cdef size_t i @@ -260,11 +234,11 @@ cdef class YieldCurve(Curve): """ - cdef _curve.YieldCurve* get_yieldcurve(self): + cdef _curve.YieldCurve* get_yieldcurve(self) nogil: return <_curve.YieldCurve*> self._thisptr.get() - cdef vector[TDate]& dates(self): - return (<_curve.YieldCurve*> self._thisptr.get()).dates + # cdef vector[TDate]& dates(self): + # return (<_curve.YieldCurve*> self._thisptr.get()).dates def __init__(self, date, str types, list periods, double[:] rates, @@ -320,14 +294,14 @@ cdef class YieldCurve(Curve): self._thisptr = shared_ptr[_curve.Curve](new _curve.YieldCurve( JpmcdsBuildIRZeroCurve( value_date, types_bytes, dates.data(), - &rates[0], dates().size(), dcc(mm_dcc), <long> fixed_freq, + &rates[0], dates.size(), dcc(mm_dcc), <long> fixed_freq, <long> float_freq, dcc(fixed_swap_dcc), dcc(float_swap_dcc), bad_day_conv, b"None"), dates) ) def __getstate__(self): cdef: - _curve.YieldCurve* const curve = <_curve.YieldCurve*>self._thisptr.get() + _curve.YieldCurve* curve = <_curve.YieldCurve*>self._thisptr.get() size_t buf_size = curve.size() unsigned char* buf = <unsigned char*>malloc(buf_size) curve.serialize(buf) @@ -402,8 +376,8 @@ cdef class YieldCurve(Curve): JpmcdsDiscountToRateYearFrac(dfs[i], <double>(dates_c[i] - base_date_c)/365., <double>1, &rates[i]) - yc._thisptr = shared_ptr[_curve.Curve](_curve.YieldCurve( - JpmcdsMakeTCurve(base_date_c, yc.dates.data(), rates, dfs.shape[0], + yc._thisptr = shared_ptr[_curve.Curve](new _curve.YieldCurve( + JpmcdsMakeTCurve(base_date_c, dates_c.data(), rates, dfs.shape[0], 1., dcc(day_count_conv)), dates_c) ) free(rates) @@ -427,42 +401,24 @@ cdef class YieldCurve(Curve): vector[TDate] dates vector[double] rates double r + TDate d for d in self.dates(): if d < forward_date_c: continue else: dates.push_back(d) - df = self._thisptr.get().zeroRate(forward_date_c, d) + df = self._thisptr.get().zeroPrice(forward_date_c, d) JpmcdsDiscountToRateYearFrac( df, <double>(d - forward_date_c)/365., 1., &r) rates.push_back(r) yc._thisptr = shared_ptr[_curve.Curve](new _curve.YieldCurve( JpmcdsMakeTCurve( - forward_date_c, dates.data(), rates, dates.size(), + forward_date_c, dates.data(), rates.data(), dates.size(), 1., self.get_curve().fDayCountConv), dates) ) return yc -# @cython.cdivision(True) -# cdef void tweak_curve(const TCurve* sc, TCurve* sc_tweaked, double epsilon, -# unsigned long mask) nogil: -# ## We want to tweak in the forward space, so we convert the hazard rates -# ## into forward rates and then back -# cdef double h1, h2, t1, t2, c -# h1 = t1 = c = 0 -# cdef size_t i - -# for i in range(sc.fNumItems): -# h2 = sc.fArray[i].fRate -# t2 = (sc.fArray[i].fDate - sc.fBaseDate) / 365. -# h = (h2 * t2 - h1 * t1) / (t2 - t1) -# if mask == 0 or (mask >> i) & 1: -# h *= (1 + epsilon) -# c += (t2 - t1) * h -# sc_tweaked.fArray[i].fRate = c / t2 -# h1 = h2 -# t1 = t2 cdef class SpreadCurve(Curve): """ @@ -483,7 +439,7 @@ cdef class SpreadCurve(Curve): Default to True """ - cdef _curve.SpreadCurve* get_spreadcurve(self): + cdef _curve.SpreadCurve* get_spreadcurve(self) nogil: return <_curve.SpreadCurve*> self._thisptr.get() @cython.boundscheck(False) @@ -523,8 +479,9 @@ cdef class SpreadCurve(Curve): cdef unsigned int includes = 0 cdef size_t i cdef bint freeup = False + cdef vector[double] recov - if cash_settle_date_c < yc._thisptr.get().fBaseDate: + if cash_settle_date_c < yc.get_curve().fBaseDate: raise ValueError("cash_settle_date: {0} is anterior to yc's base_date: {1}". format(cash_settle_date, yc.base_date)) @@ -559,7 +516,7 @@ cdef class SpreadCurve(Curve): raise ValueError("can't convert stub") with nogil: curve = JpmcdsCleanSpreadCurve(today_c, - yc._thisptr.get(), + yc.get_curve(), start_date_c, step_in_date_c, cash_settle_date_c, @@ -586,14 +543,10 @@ cdef class SpreadCurve(Curve): curve = new_curve if freeup: free(end_dates_c) - self._thisptr = make_shared(curve) - self.recovery_rates = shared_ptr[double]( - <double*>malloc(curve.fNumItems * sizeof(double)), - double_free) - memcpy(<void*>self.recovery_rates.get(), &recovery_rates[0], + recov = vector[double](curve.fNumItems) + memcpy(<void*>recov.data(), &recovery_rates[0], curve.fNumItems * sizeof(double)) - if ticker: - self.ticker = ticker + self._thisptr.reset(new _curve.SpreadCurve(curve, recov, ticker)) survival_probability = Curve.__forward_zero_price @@ -611,16 +564,18 @@ cdef class SpreadCurve(Curve): unsigned char* cursor = state size_t ticker_length, size double* temp + cursor = deserialize(cursor, curve) - self._thisptr = make_shared(curve) memcpy(&ticker_length, cursor, sizeof(size_t)) cursor += sizeof(size_t) - self.ticker = string(<char*>cursor, ticker_length) + cdef string ticker = string(<char*>cursor, ticker_length) cursor += ticker_length + cdef vector[double] recovery_rates = vector[double](curve.fNumItems) size = curve.fNumItems * sizeof(double) - self.recovery_rates = shared_ptr[double](<double*>malloc(size), - double_free) - memcpy(self.recovery_rates.get(), cursor, size) + memcpy(recovery_rates.data(), cursor, size) + self._thisptr.reset( + new _curve.SpreadCurve(curve, recovery_rates, ticker) + ) def __deepcopy__(self, dict memo): cdef SpreadCurve sc = SpreadCurve.__new__(SpreadCurve) @@ -645,15 +600,16 @@ cdef class SpreadCurve(Curve): cursor = <bytes?>state cursor = deserialize(cursor, curve) - instance._thisptr = make_shared(curve) + cdef vector[double] recovery_rates = vector[double](curve.fNumItems) + memcpy(&ticker_length, cursor, sizeof(size_t)) cursor += sizeof(size_t) - instance.ticker = string(<char*>cursor, ticker_length) + cdef string ticker = string(<char*>cursor, ticker_length) cursor += ticker_length size = curve.fNumItems * sizeof(double) - instance.recovery_rates = shared_ptr[double]( - <double*>malloc(size), double_free) - memcpy(instance.recovery_rates.get(), cursor, size) + memcpy(recovery_rates.data(), cursor, size) + instance._thisptr = shared_ptr[_curve.Curve]( new _curve.SpreadCurve( + curve, recovery_rates, ticker)) return instance def __hash__(self): @@ -689,9 +645,11 @@ cdef class SpreadCurve(Curve): cdef TDate base_date_c = pydate_to_TDate(base_date) cdef SpreadCurve sc = SpreadCurve.__new__(SpreadCurve) cdef TDate max_date = 200000 # can go higher but this should be more than enough - - sc._thisptr = make_shared(JpmcdsMakeTCurve(base_date_c, &max_date, &rate, 1, - <double>basis, dcc(day_count_conv))) + cdef TCurve* curve = JpmcdsMakeTCurve(base_date_c, &max_date, &rate, 1, + <double>basis, dcc(day_count_conv)) + cdef vector[double] recovery_rates = vector[double](1, recovery) + sc._thisptr = shared_ptr[_curve.Curve]( + new _curve.SpreadCurve(curve, recovery_rates, ticker)) return sc @cython.boundscheck(False) @@ -721,7 +679,7 @@ cdef class SpreadCurve(Curve): else: sc = self if mask != 0: - sc._thisptr.get().tweak(epsilon, mask) + sc._thisptr.get().tweak_mask(epsilon, mask) else: sc._thisptr.get().tweak(epsilon) return sc |
