summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyisda/_curve.pxd14
-rw-r--r--pyisda/credit_index.pyx6
-rw-r--r--pyisda/curve.pxd8
-rw-r--r--pyisda/curve.pyx124
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