summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@serenitascapital.com>2016-06-28 15:30:16 -0400
committerGuillaume Horel <guillaume.horel@serenitascapital.com>2016-06-28 15:30:16 -0400
commit60e49a606ae270fb4d455da1b565e0ea656ffb3c (patch)
treeada0b2e8bfa6b5bb4dc8180f7d83ca57572378e5
downloadpyisda-60e49a606ae270fb4d455da1b565e0ea656ffb3c.tar.gz
initial import
-rw-r--r--Makefile2
-rw-r--r--__init__.py0
-rw-r--r--convert.pxd15
-rw-r--r--setup.py6
-rw-r--r--yearfrac.pxd4
-rw-r--r--yearfrac.pyx11
-rw-r--r--zerocurve.pxd17
-rw-r--r--zerocurve.pyx68
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)