From 961963c48c1dcd7629247459cfa243c6d4da9746 Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Tue, 17 Apr 2018 17:36:27 -0400 Subject: add next_business_day --- pyisda/date.pxd | 14 ++++++++++++-- pyisda/date.pyx | 18 ++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/pyisda/date.pxd b/pyisda/date.pxd index b3ed150..6da8e85 100644 --- a/pyisda/date.pxd +++ b/pyisda/date.pxd @@ -33,6 +33,7 @@ cdef extern from "isda/dateconv.h" nogil: int JpmcdsMDYToDate(TMonthDayYear*, TDate*) cdef extern from "isda/ldate.h" nogil: + int JpmcdsDateFwdThenAdjust(TDate date, TDateInterval* interval, long badDayMethod, char* holidayFile, TDate *advAdjustedDate) int JpmcdsDtFwdAny(TDate date, TDateInterval* interval, TDate* sumDate) @@ -42,11 +43,20 @@ cdef enum DCC: ACT_365F = 2L ACT_360 = 3L -cdef extern from "isda/busday.h": +cdef extern from "isda/busday.h" nogil: int JpmcdsDateFromBusDaysOffset(TDate fromDate, # (I) input date long offset, # (I) number of business days char *holidayFile, # (I) holiday file specification - TDate *result) nogil + TDate *result) + int JpmcdsBusinessDay(TDate date, # Input Date + long method, # See ldate.h + char *holidayFile, # Filename w/ Holidays + TDate *outDate) + int JPMCDS_BAD_DAY_FOLLOW + int JPMCDS_BAD_DAY_PREVIOUS + int JPMCDS_BAD_DAY_NONE + int JPMCDS_BAD_DAY_MODIFIED + cpdef TDate pydate_to_TDate(c_datetime.date d) cpdef c_datetime.date TDate_to_pydate(TDate d) diff --git a/pyisda/date.pyx b/pyisda/date.pyx index 5cca9d1..f858d1a 100644 --- a/pyisda/date.pyx +++ b/pyisda/date.pyx @@ -38,7 +38,7 @@ def dcc_tostring(long day_count): s = c_string return s -cdef TDate _previous_twentieth(TDate d) nogil: +cdef TDate _previous_twentieth(TDate d, bint roll=True) nogil: cdef TMonthDayYear mdy if JpmcdsDateToMDY(d, &mdy) != SUCCESS: return -1 @@ -59,11 +59,14 @@ cdef TDate _previous_twentieth(TDate d) nogil: if JpmcdsMDYToDate(&mdy, &r) != SUCCESS: return -1 else: - return r + if roll: + return next_business_day(r) + else: + return r -def previous_twentieth(d): +def previous_twentieth(d, bint roll=True): cdef TDate date = pydate_to_TDate(d) - return TDate_to_pydate(_previous_twentieth(date)) + return TDate_to_pydate(_previous_twentieth(date, roll)) cdef TMonthDayYear next_twentieth(TDate d) nogil: cdef TMonthDayYear mdy @@ -83,6 +86,13 @@ cdef TMonthDayYear next_twentieth(TDate d) nogil: mdy.year += 1 return mdy +cdef inline TDate next_business_day(TDate date) nogil: + cdef TDate r + if JpmcdsBusinessDay(date, JPMCDS_BAD_DAY_FOLLOW, "NONE", &r) != SUCCESS: + return -1 + else: + return r + cdef void _roll_date(TDate d, double* tenors, int n_dates, TDate* output) nogil: cdef: TDate cutoff = 151472 # 2015-09-20 -- cgit v1.2.3-70-g09d2