summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2018-05-08 14:51:36 -0400
committerGuillaume Horel <guillaume.horel@gmail.com>2018-05-08 14:51:36 -0400
commit8c1721349b40ec56926c6b74cb5187bb8700fa97 (patch)
tree8f6f5778713ca36968b3c57e63848bd5737fe13e
parenta94509a93d91e0071ad5ee9ef5c4687e2d7a0fea (diff)
downloadpyisda-8c1721349b40ec56926c6b74cb5187bb8700fa97.tar.gz
add default_accrual function
-rw-r--r--pyisda/date.pxd20
-rw-r--r--pyisda/date.pyx42
2 files changed, 60 insertions, 2 deletions
diff --git a/pyisda/date.pxd b/pyisda/date.pxd
index 9755ced..c1f7dd5 100644
--- a/pyisda/date.pxd
+++ b/pyisda/date.pxd
@@ -1,4 +1,5 @@
from cpython cimport datetime as c_datetime
+from cdsone cimport TStubMethod
cdef extern from "isda/yearfrac.h" nogil:
int JpmcdsStringToDayCountConv(char* day_count, long* type)
@@ -9,6 +10,7 @@ cdef long dcc(str day_count) except -1
cdef extern from "isda/cdate.h":
ctypedef struct TDateInterval:
pass
+ ctypedef long TDate
cdef extern from "isda/mdydate.h":
ctypedef struct TMonthDayYear:
@@ -16,8 +18,6 @@ cdef extern from "isda/mdydate.h":
long day
long year
-ctypedef long TDate
-
cdef extern from "isda/convert.h" nogil:
int JpmcdsStringToDateInterval(char* input, char* label, TDateInterval* interval)
int JpmcdsMakeDateInterval(int num_periods, char period_type, TDateInterval* interval)
@@ -58,6 +58,22 @@ cdef extern from "isda/busday.h" nogil:
JPMCDS_BAD_DAY_NONE
JPMCDS_BAD_DAY_MODIFIED
+cdef extern from "isda/defaulted.h" nogil:
+ int JpmcdsDefaultAccrual(
+ TDate tradeDate,
+ TDate edd,
+ TDate startDate,
+ TDate endDate,
+ TDateInterval *couponInterval,
+ TStubMethod *stubType,
+ double notional,
+ double couponRate,
+ long paymentDcc,
+ long badDayConv,
+ char *calendar,
+ int *accrualDays,
+ double *defaultAccrual)
+
cpdef enum BadDay:
FOLLOW = JPMCDS_BAD_DAY_FOLLOW
PREVIOUS = JPMCDS_BAD_DAY_PREVIOUS
diff --git a/pyisda/date.pyx b/pyisda/date.pyx
index 821d224..7e13ce1 100644
--- a/pyisda/date.pyx
+++ b/pyisda/date.pyx
@@ -2,6 +2,7 @@ import datetime
from cpython cimport datetime as c_datetime
from cpython.version cimport PY_MAJOR_VERSION
from libc.stdlib cimport malloc, free
+from cdsone cimport JpmcdsStringToStubMethod
cimport cython
cimport numpy as np
@@ -20,6 +21,7 @@ cpdef c_datetime.date TDate_to_pydate(TDate d):
else:
raise ValueError("incorrect date")
+
cdef long dcc(str day_count) except -1:
cdef long r
dc_bytes = day_count.encode('utf-8')
@@ -30,6 +32,7 @@ cdef long dcc(str day_count) except -1:
else:
raise ValueError('{0} is not a valid day count'.format(day_count))
+
def dcc_tostring(long day_count):
cdef char* c_string = JpmcdsFormatDayCountConv(day_count)
if PY_MAJOR_VERSION >= 3:
@@ -38,6 +41,7 @@ def dcc_tostring(long day_count):
s = c_string
return s
+
cdef TDate _previous_twentieth(TDate d, bint roll) nogil:
cdef TMonthDayYear mdy
if JpmcdsDateToMDY(d, &mdy) != SUCCESS:
@@ -64,15 +68,18 @@ cdef TDate _previous_twentieth(TDate d, bint roll) nogil:
else:
return r
+
def previous_twentieth(d, bint roll=True):
cdef TDate date = pydate_to_TDate(d)
return TDate_to_pydate(_previous_twentieth(date, roll))
+
@cython.cdivision(True)
def cds_accrued(d, double coupon):
cdef TDate date = pydate_to_TDate(d) + 1
return (date - _previous_twentieth(date, True))/360. * coupon
+
cdef TMonthDayYear next_twentieth(TDate d) nogil:
cdef TMonthDayYear mdy
JpmcdsDateToMDY(d, &mdy)
@@ -159,3 +166,38 @@ def roll_date(d, tenor):
tenor_ = <double>tenor
_roll_date(date_, &tenor_, 1, &output_date)
return TDate_to_pydate(output_date)
+
+
+def default_accrual(trade_date, edd, start_date, end_date, double notional,
+ double coupon_rate):
+ cdef:
+ TDate trade_date_c = pydate_to_TDate(trade_date)
+ TDate edd_c = pydate_to_TDate(edd)
+ TDate start_date_c = pydate_to_TDate(start_date)
+ TDate end_date_c = pydate_to_TDate(end_date)
+ TDateInterval ivl
+ TStubMethod stub
+ int accrual_days
+ double default_accrual
+
+ if JpmcdsStringToStubMethod(b"f/s", &stub) != SUCCESS:
+ raise ValueError("can't convert stub")
+
+ if JpmcdsMakeDateInterval(3, "M", &ivl) != SUCCESS:
+ raise ValueError("can't convert to date interval")
+
+ if JpmcdsDefaultAccrual(trade_date_c,
+ edd_c,
+ start_date_c,
+ end_date_c,
+ &ivl,
+ &stub,
+ notional,
+ coupon_rate,
+ ACT_360,
+ FOLLOW,
+ b"None",
+ &accrual_days,
+ &default_accrual) != SUCCESS:
+ raise ValueError("failed to compute default accrual")
+ return accrual_days, default_accrual