From c4b8148b8419ca1e281a8e69aeea578e057c4c4d Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Wed, 29 Jun 2016 12:25:46 -0400 Subject: work in progress --- date.pxd | 3 ++- setup.py | 7 +++++-- zerocurve.pxd | 6 +++++- zerocurve.pyx | 24 ++++++++++++++---------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/date.pxd b/date.pxd index 22ea9f6..c17a786 100644 --- a/date.pxd +++ b/date.pxd @@ -7,6 +7,7 @@ ctypedef long TDate cdef extern from "isda/convert.h": int JpmcdsStringToDateInterval(char* input, char* label, TDateInterval* interval) int JpmcdsMakeDateInterval(int num_periods, char period_type, TDateInterval* interval) + char* JpmcdsFormatDate(TDate date) cdef extern from "isda/date_sup.h": int JpmcdsDateIntervalToFreq(TDateInterval* interval, double* freq) @@ -18,7 +19,7 @@ cdef extern from "isda/ldate.h": int JpmcdsDateFwdThenAdjust(TDate date, TDateInterval* interval, long badDayMethod, char* holidayFile, TDate *advAdjustedDate) -cdef enum BadDay: +cpdef public enum BadDay: FOLLOW = 'F' PREVIOUS = 'P' NONE = 'N' diff --git a/setup.py b/setup.py index 54d65cc..9162d58 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,9 @@ from distutils.core import setup +from distutils.extension import Extension from Cython.Build import cythonize +extensions = Extension("*", ["*.pyx"], + libraries = ["cds"]) setup( - ext_modules = cythonize("*.pyx") -) + name = "pyisda", + ext_modules = cythonize(extensions)) diff --git a/zerocurve.pxd b/zerocurve.pxd index f3aaf57..cc3063e 100644 --- a/zerocurve.pxd +++ b/zerocurve.pxd @@ -8,7 +8,11 @@ cdef extern from "isda/zerocurve.h": ctypedef struct TDateInterval: pass - TCurve* JpmcdsBuildIRZeroCurve(TDate valueDate, char* instrNames, TDate* dates, double* rates, long nInstr, long mmDCC, long fixedSwapFreq, long floatSwapFreq, long fixedSwapDCC, long floatSwapDCC, long badDayConv, char* holidayFile) + TCurve* JpmcdsBuildIRZeroCurve(TDate valueDate, char* instrNames, + TDate* dates, double* rates, long nInstr, + long mmDCC, long fixedSwapFreq, long floatSwapFreq, + long fixedSwapDCC, long floatSwapDCC, + long badDayConv, char* holidayFile) cdef extern from "isda/tcurve.h": void JpmcdsFreeTCurve(TCurve* curve) diff --git a/zerocurve.pyx b/zerocurve.pyx index e56a38e..96e7036 100644 --- a/zerocurve.pyx +++ b/zerocurve.pyx @@ -3,7 +3,7 @@ from libc.stdlib cimport malloc, free from pyisda.zerocurve cimport JpmcdsBuildIRZeroCurve from pyisda.yearfrac cimport dcc from pyisda.date cimport (JpmcdsStringToDateInterval, JpmcdsDateIntervalToFreq, - JpmcdsDate, JpmcdsDateFwdThenAdjust, NONE) + JpmcdsDate, JpmcdsDateFwdThenAdjust, BadDay) cdef int SUCCESS = 0 @@ -11,12 +11,14 @@ cdef class ZeroCurve: cdef TCurve* _thisptr cdef TDate* _dates - def __cinit__(self, date, str types, + def __init__(self, date, str types, list periods, double[:] rates, str mm_dcc, str fixed_swap_period, str float_swap_period, - str fixed_swap_dcc, str float_swap_dcc, char bad_day_conv, - char* holidayFile): + str fixed_swap_dcc, str float_swap_dcc, BadDay bad_day_conv): + """ Initialize a zero coupon curve + instruments need to be sorted by tenor + """ cdef: double fixed_freq double float_freq @@ -29,15 +31,15 @@ cdef class ZeroCurve: else: raise ValueError - cdef TDate* _dates = malloc(len(periods) * sizeof(TDate)) + self._dates = malloc(len(periods) * sizeof(TDate)) cdef TDateInterval tmp for i, p in enumerate(periods): period_bytes = p.encode('utf-8') - if JpmcdsStringToDateInterval(p, routine, &tmp) != SUCCESS: + if JpmcdsStringToDateInterval(period_bytes, routine, &tmp) != SUCCESS: raise ValueError if JpmcdsDateFwdThenAdjust(value_date, &tmp, NONE, - "None", &_dates[i]) != SUCCESS: + "None", &self._dates[i]) != SUCCESS: raise ValueError('Invalid interval') fixed_bytes = fixed_swap_period.encode('utf-8') @@ -52,11 +54,12 @@ cdef class ZeroCurve: raise ValueError if JpmcdsDateIntervalToFreq(&ivl, &float_freq) != SUCCESS: raise ValueError + self._thisptr = JpmcdsBuildIRZeroCurve( - value_date, types_bytes, _dates, + value_date, types_bytes, self._dates, &rates[0], len(periods), dcc(mm_dcc), fixed_freq, float_freq, - dcc(fixed_swap_dcc), dcc(fixed_swap_dcc), bad_day_conv, "None" + dcc(fixed_swap_dcc), dcc(float_swap_dcc), bad_day_conv, b"None" ) def __dealloc__(self): @@ -66,10 +69,11 @@ cdef class ZeroCurve: free(self._dates) def discount_factor(self, date): + if self._thisptr is NULL: + raise ValueError('curve is empty') cdef TDate discount_date if isinstance(date, datetime.date): discount_date = JpmcdsDate(date.year, date.month, date.day) else: raise ValueError - return JpmcdsZeroPrice(self._thisptr, discount_date) -- cgit v1.2.3-70-g09d2