diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | __init__.py | 0 | ||||
| -rw-r--r-- | convert.pxd | 15 | ||||
| -rw-r--r-- | setup.py | 6 | ||||
| -rw-r--r-- | yearfrac.pxd | 4 | ||||
| -rw-r--r-- | yearfrac.pyx | 11 | ||||
| -rw-r--r-- | zerocurve.pxd | 17 | ||||
| -rw-r--r-- | zerocurve.pyx | 68 |
8 files changed, 123 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1ea9bde --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +build: + python setup.py build_ext --inplace diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/__init__.py diff --git a/convert.pxd b/convert.pxd new file mode 100644 index 0000000..0d02c8b --- /dev/null +++ b/convert.pxd @@ -0,0 +1,15 @@ +cdef extern from "isda/cdate.h": + ctypedef struct TDateInterval: + pass + +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) + +cdef extern from "isda/date_sup.h": + int JpmcdsDateIntervalToFreq(TDateInterval* interval, double* freq) + +cdef extern from "isda/dateconv.h": + TDate JpmcdsDate(long year, long month, long day) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..54d65cc --- /dev/null +++ b/setup.py @@ -0,0 +1,6 @@ +from distutils.core import setup +from Cython.Build import cythonize + +setup( + ext_modules = cythonize("*.pyx") +) diff --git a/yearfrac.pxd b/yearfrac.pxd new file mode 100644 index 0000000..739ca90 --- /dev/null +++ b/yearfrac.pxd @@ -0,0 +1,4 @@ +cdef extern from "isda/yearfrac.h": + int JpmcdsStringToDayCountConv(char* day_count, long* type) + +cdef long dcc(str day_count) diff --git a/yearfrac.pyx b/yearfrac.pyx new file mode 100644 index 0000000..48b8995 --- /dev/null +++ b/yearfrac.pyx @@ -0,0 +1,11 @@ +from pyisda.yearfrac cimport JpmcdsStringToDayCountConv + +cdef long dcc(str day_count): + cdef long r + dc_bytes = day_count.encode('utf-8') + cdef char* dc = dc_bytes + cdef err = JpmcdsStringToDayCountConv(<char*> dc, &r) + if err == 0: + return r + else: + raise ValueError('{0} is not a valid day count'.format(day_count)) diff --git a/zerocurve.pxd b/zerocurve.pxd new file mode 100644 index 0000000..f3aaf57 --- /dev/null +++ b/zerocurve.pxd @@ -0,0 +1,17 @@ +cdef extern from "isda/zerocurve.h": + + ctypedef long int TDate + + ctypedef struct TCurve: + pass + + 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) + +cdef extern from "isda/tcurve.h": + void JpmcdsFreeTCurve(TCurve* curve) + +cdef extern from "isda/cxzerocurve.h": + double JpmcdsZeroPrice(TCurve* curve, TDate date) diff --git a/zerocurve.pyx b/zerocurve.pyx new file mode 100644 index 0000000..2918bae --- /dev/null +++ b/zerocurve.pyx @@ -0,0 +1,68 @@ +from cpython cimport datetime +from libc.stdlib cimport malloc, free +from pyisda.zerocurve cimport JpmcdsBuildIRZeroCurve +from pyisda.yearfrac cimport dcc +from pyisda.convert cimport JpmcdsStringToDateInterval, JpmcdsDateIntervalToFreq, JpmcdsDate + +cdef int SUCCESS = 0 + +cdef class Tcurve: + cdef TCurve* _thisptr + cdef TDate* _dates + + def __cinit__(self, date, str types, + list dates, 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): + + cdef: + double fixed_freq + double float_freq + TDateInterval ivl + char* routine = 'zerocurve' + TDate value_date + + if isinstance(date, datetime.date): + value_date = JpmcdsDate(date.year, date.month, date.day) + else: + raise ValueError + + cdef TDate* _dates = <TDate*>malloc(len(dates) * sizeof(TDate)) + + for i, d in enumerate(date): + _dates[i] = JpmcdsDate(d.year, d.month, d.day) + + fixed_bytes = fixed_swap_period.encode('utf-8') + float_bytes = float_swap_period.encode('utf-8') + types_bytes = types.encode('utf-8') + + if JpmcdsStringToDateInterval(fixed_bytes, routine, &ivl) != SUCCESS: + raise ValueError + if JpmcdsDateIntervalToFreq(&ivl, &fixed_freq) != SUCCESS: + raise ValueError + if JpmcdsStringToDateInterval(float_bytes, routine, &ivl) != SUCCESS: + raise ValueError + if JpmcdsDateIntervalToFreq(&ivl, &float_freq) != SUCCESS: + raise ValueError + self._thisptr = JpmcdsBuildIRZeroCurve( + value_date, types_bytes, _dates, + &rates[0], len(dates), dcc(mm_dcc), <long> fixed_freq, + <long> float_freq, + dcc(fixed_swap_dcc), dcc(fixed_swap_dcc), <long>bad_day_conv, "None" + ) + + def __dealloc__(self): + if self._thisptr is not NULL: + JpmcdsFreeTCurve(self._thisptr) + if self._dates is not NULL: + free(self._dates) + + def discount_factor(self, date): + 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) |
