summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2019-02-22 17:11:42 -0500
committerGuillaume Horel <guillaume.horel@gmail.com>2019-02-22 17:11:42 -0500
commitea4ca5a28b9bf9c8eec3d727dc35b6863c1f5d01 (patch)
tree81616f79a1b5dcf4a1fe0b9cededd22542fc144c
parenta0e798113024114c3002e3eee1e09ae194dbf3f4 (diff)
downloadpyisda-more_cpp.tar.gz
bugfixesmore_cpp
-rw-r--r--c_layer/curve.cpp40
-rw-r--r--c_layer/curve.hpp24
-rw-r--r--pyisda/_curve.pxd9
-rw-r--r--pyisda/credit_index.pyx16
-rw-r--r--pyisda/curve.pyx30
-rw-r--r--pyisda/legs.pyx2
6 files changed, 68 insertions, 53 deletions
diff --git a/c_layer/curve.cpp b/c_layer/curve.cpp
index 2f84d01..221f27c 100644
--- a/c_layer/curve.cpp
+++ b/c_layer/curve.cpp
@@ -64,7 +64,7 @@ namespace pyisda {
}
}
- void Curve::tweak(TCurve* const ptr, double epsilon) {
+ void Curve::tweak(TCurve* ptr, double epsilon) {
double h1, h2, t1, t2, c;
h1 = t1 = c = 0;
TRatePt cur;
@@ -79,18 +79,22 @@ namespace pyisda {
}
}
- void Curve::tweak(TCurve* const ptr, double epsilon, unsigned long mask) {
- double h1, h2, t1, t2, c;
- h1 = t1 = c = 0;
- TRatePt cur;
- for(int i = 0;i < ptr->fNumItems; i++) {
- cur = ptr->fArray[i];
- h2 = cur.fRate;
- t2 = (cur.fDate - ptr->fBaseDate) / 365.;
- c += (h2 * t2 - h1 * t1 ) * (1 + epsilon * (( mask >> i) & 1));
- cur.fRate = c / t2;
- h1 = h2;
- t1 = t2;
+ void Curve::tweak(TCurve* ptr, double epsilon, unsigned long mask) {
+ if (mask == 0) {
+ Curve::tweak(ptr, epsilon);
+ } else {
+ double h1, h2, t1, t2, c;
+ h1 = t1 = c = 0;
+ TRatePt cur;
+ for(int i = 0; i < ptr->fNumItems; i++) {
+ cur = ptr->fArray[i];
+ h2 = cur.fRate;
+ t2 = (cur.fDate - ptr->fBaseDate) / 365.;
+ c += (h2 * t2 - h1 * t1 ) * (1 + epsilon * (( mask >> i) & 1));
+ cur.fRate = c / t2;
+ h1 = h2;
+ t1 = t2;
+ };
}
}
@@ -117,7 +121,8 @@ namespace pyisda {
}
size_t SpreadCurve::size() {
- return Curve::size() + recovery_rates.size() * sizeof(double) + 8;
+ return Curve::size() + recovery_rates.size() * sizeof(double) +
+ 8 + sizeof(TDate) + sizeof(Seniority);
}
unsigned char* SpreadCurve::serialize(unsigned char* const buf) {
@@ -131,7 +136,12 @@ namespace pyisda {
} else {
ticker.copy((char*)cur, 8, 0);
}
- return cur + 8;
+ cur += 8;
+ memcpy(cur, &event_date, sizeof(TDate));
+ cur += sizeof(TDate);
+ memcpy(cur, &seniority, sizeof(Seniority));
+ cur += sizeof(Seniority);
+ return cur;
}
}
diff --git a/c_layer/curve.hpp b/c_layer/curve.hpp
index 5cc796a..39fdce9 100644
--- a/c_layer/curve.hpp
+++ b/c_layer/curve.hpp
@@ -5,6 +5,7 @@
#include "isda/bastypes.h"
#include "isda/cdate.h"
#include "isda/tcurve.h"
+#include <iostream>
namespace pyisda {
class Curve {
@@ -17,7 +18,7 @@ namespace pyisda {
~Curve() {
JpmcdsFreeTCurve(ptr);
}
- explicit operator TCurve*() const { return ptr; }
+ TCurve* get_TCurve() const {return ptr; }
unsigned char* serialize(unsigned char* buf);
double zeroPrice(const TDate date);
double zeroPrice(const TDate date1, const TDate date2);
@@ -36,7 +37,7 @@ namespace pyisda {
public:
YieldCurve(TCurve* const curve, const std::vector<TDate>& dates) :
Curve(curve),
- dates(dates) {};
+ dates(std::move(dates)) {};
YieldCurve(const YieldCurve &curve2) :
Curve(curve2),
dates(std::move(curve2.dates)) {};
@@ -47,18 +48,29 @@ namespace pyisda {
class SpreadCurve : public Curve {
public:
+ enum Seniority {
+ Senior,
+ Subordinated
+ };
+
SpreadCurve(TCurve* const curve, const std::vector<double>& recovery_rates,
- const std::string& ticker) :
+ const std::string& ticker, TDate event_date = -1,
+ Seniority sen = Senior) :
Curve(curve),
recovery_rates(recovery_rates),
- ticker(ticker) {};
+ ticker(ticker),
+ event_date(event_date),
+ seniority(sen) {};
SpreadCurve(const SpreadCurve &curve2) :
Curve(curve2),
recovery_rates(std::move(curve2.recovery_rates)),
- ticker(std::move(curve2.ticker)) {};
-
+ ticker(std::move(curve2.ticker)),
+ event_date(curve2.event_date),
+ seniority(curve2.seniority) {};
std::vector<double> recovery_rates;
std::string ticker;
+ TDate event_date;
+ SpreadCurve::Seniority seniority;
size_t size();
unsigned char* serialize(unsigned char* buf);
};
diff --git a/pyisda/_curve.pxd b/pyisda/_curve.pxd
index 5d5a003..430a4ea 100644
--- a/pyisda/_curve.pxd
+++ b/pyisda/_curve.pxd
@@ -19,16 +19,13 @@ cdef extern from "curve.hpp" namespace "pyisda" nogil:
Curve(TCurve*)
Curve(const TCurve&)
unsigned char* serialize(unsigned char*)
- TCurve* operator()
+ TCurve* get_TCurve() const
double zeroPrice(TDate d)
double zeroPrice(TDate d1, TDate d2)
- void tweak_mask "tweak" (double epsilon, unsigned long mask)
- void tweak(double epsilon)
+ void tweak(double epsilon, unsigned long mask)
@staticmethod
- void tweak_mask_ "tweak" (const TCurve*, double epsilon, unsigned long mask)
- @staticmethod
- void tweak_ "tweak" (const TCurve*, double epsilon)
+ void tweak_static "tweak" (TCurve*, double epsilon, unsigned long mask)
double survivalProb(const TDate, const TDate)
double survivalProb(const TDate, const TDate, double eps)
size_t size()
diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx
index 76c77a1..7e93cd0 100644
--- a/pyisda/credit_index.pyx
+++ b/pyisda/credit_index.pyx
@@ -1,4 +1,5 @@
#cython: cdivision=True, boundscheck=False, c_string_type=unicode, c_string_encoding=ascii
+# distutils: sources = c_layer/curve.cpp
from libc.stdlib cimport malloc, free
from libc.math cimport nan, isnan
from libc.string cimport memcpy, memset
@@ -471,7 +472,7 @@ cdef class CreditIndex(CurveList):
step_in_date_c,
cash_settle_date_c,
yc.get_curve(),
- <TCurve*>deref(sc),
+ sc.get().get_TCurve(),
True,
&fl_pv)
r += self._weights[i] * fl_pv
@@ -498,12 +499,12 @@ cdef class CreditIndex(CurveList):
size_t i
if inplace:
for i in range(self._curves.size()):
- self._curves[i].get().tweak_mask(epsilon, mask)
+ self._curves[i].get().tweak(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_mask(epsilon, mask)
+ sc_copy.tweak(epsilon, mask)
self._curves[i].reset(sc_copy)
@@ -627,7 +628,7 @@ cdef double pv(const vector[shared_ptr[Curve]]& curves,
cash_settle_date,
step_in_date,
yc,
- <TCurve*>deref(curve),
+ curve.get_TCurve(),
recovery_rate,
&cl_pv)
JpmcdsFeeLegPV(legs.second,
@@ -635,19 +636,20 @@ cdef double pv(const vector[shared_ptr[Curve]]& curves,
step_in_date,
cash_settle_date,
yc,
- <TCurve*>deref(curve),
+ curve.get_TCurve(),
True,
&fl_pv)
r += weights[i] * (cl_pv - fl_pv * fixed_rate)
else:
with parallel():
- tweaked_curve = JpmcdsCopyCurve(<TCurve*>deref(curves[0].get()))
+
cl_pv = 0.
fl_pv = 0.
for i in prange(curves.size()):
curve = <_curve.SpreadCurve*>(curves[i].get())
+ tweaked_curve = JpmcdsCopyCurve(curve.get_TCurve())
recovery_rate = curve.recovery_rates[0]
- _curve.Curve.tweak_mask_(tweaked_curve, epsilon, mask)
+ _curve.Curve.tweak_static(tweaked_curve, epsilon, mask)
# FIXME: do something better
if isnan(recovery_rate):
recovery_rate = curve.recovery_rates[1]
diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx
index cd12213..40d596d 100644
--- a/pyisda/curve.pyx
+++ b/pyisda/curve.pyx
@@ -6,7 +6,7 @@ from .date cimport (JpmcdsStringToDateInterval, pydate_to_TDate, dcc, TMonthDayY
JpmcdsDateIntervalToFreq, JpmcdsDateFwdThenAdjust, TDate_to_pydate,
JpmcdsDateFromBusDaysOffset, JpmcdsStringToDayCountConv, ACT_360,
BadDay, FOLLOW, MODIFIED, NONE)
-from date import dcc_tostring
+from .date import dcc_tostring
from .date cimport _previous_twentieth, _roll_date
from .cdsone cimport JpmcdsStringToStubMethod, TStubMethod
from .legs cimport (JpmcdsCdsContingentLegMake, JpmcdsCdsFeeLegMake,
@@ -37,7 +37,7 @@ cdef int SUCCESS = 0
cdef class Curve(object):
cdef inline TCurve* get_curve(self) nogil:
- return <TCurve*>(deref(self._thisptr))
+ return self._thisptr.get().get_TCurve()
def __getstate__(self):
cdef:
@@ -89,11 +89,11 @@ cdef class Curve(object):
dict
contains `base_date`, `basis`, `day_count_counvention` and `data`
"""
- cdef TCurve* curve = <TCurve*>deref(self._thisptr)
+ cdef TCurve* curve = self.get_curve()
return {'base_date': self.base_date,
- 'basis': self.get_curve().fBasis,
- 'day_count_convention': dcc_tostring(self.get_curve().fDayCountConv),
- 'data': fArray_to_list(self.get_curve().fArray, self.get_curve().fNumItems)}
+ 'basis': curve.fBasis,
+ 'day_count_convention': dcc_tostring(curve.fDayCountConv),
+ 'data': fArray_to_list(curve.fArray, curve.fNumItems)}
@cython.boundscheck(False)
@cython.cdivision(True)
@@ -127,10 +127,10 @@ cdef class Curve(object):
def __iter__(self):
cdef:
- TCurve* curve = <TCurve*>deref(self._thisptr)
+ TCurve* curve = self.get_curve()
size_t i = 0
- TRatePt* it = self.get_curve().fArray
- for i in range(self.get_curve().fNumItems):
+ TRatePt* it = curve.fArray
+ for i in range(curve.fNumItems):
yield (TDate_to_pydate(it[i].fDate), it[i].fRate)
def __len__(self):
@@ -346,7 +346,6 @@ cdef class YieldCurve(Curve):
cursor = deserialize(cursor, curve)
- instance._thisptr = make_shared[_curve.Curve](curve)
memcpy(&num_instr, cursor, sizeof(size_t))
cdef vector[TDate] dates = vector[TDate](num_instr)
memcpy(dates.data(), cursor, num_instr * sizeof(TDate))
@@ -456,7 +455,6 @@ cdef class SpreadCurve(Curve):
cdef TDate step_in_date_c
cdef TDate cash_settle_date_c
cdef TDate start_date_c
-
if start_date is None:
start_date_c = _previous_twentieth(today_c, True)
if start_date_c == -1:
@@ -481,7 +479,6 @@ cdef class SpreadCurve(Curve):
cdef size_t i
cdef bint freeup = False
cdef vector[double] recov
-
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))
@@ -679,10 +676,7 @@ cdef class SpreadCurve(Curve):
)
else:
sc = self
- if mask != 0:
- sc._thisptr.get().tweak_mask(epsilon, mask)
- else:
- sc._thisptr.get().tweak(epsilon)
+ sc._thisptr.get().tweak(epsilon, mask)
return sc
@cython.boundscheck(False)
@@ -717,8 +711,8 @@ cdef class SpreadCurve(Curve):
ACT_360,
<long>b'M',
b'NONE',
- <TCurve*>deref(yc._thisptr),
- <TCurve*>deref(self._thisptr),
+ yc.get_curve(),
+ self.get_curve(),
&recovery_rates[0],
par_spreads)
free(end_dates_c)
diff --git a/pyisda/legs.pyx b/pyisda/legs.pyx
index 39e60e8..cce31ac 100644
--- a/pyisda/legs.pyx
+++ b/pyisda/legs.pyx
@@ -1,7 +1,7 @@
from cython.operator cimport dereference as deref
from libc.stdlib cimport free
from .date cimport pydate_to_TDate, TDate_to_pydate, dcc
-from date import dcc_tostring
+from .date import dcc_tostring
from .cdsone cimport JpmcdsStringToStubMethod, TStubMethod
from .curve cimport YieldCurve, SpreadCurve