diff options
| -rw-r--r-- | pyisda/date.pyx | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/pyisda/date.pyx b/pyisda/date.pyx index bc4507a..e3cc325 100644 --- a/pyisda/date.pyx +++ b/pyisda/date.pyx @@ -43,6 +43,17 @@ cdef TDate _previous_twentieth(TDate d, bint roll) nogil: cdef TMonthDayYear mdy if JpmcdsDateToMDY(d, &mdy) != SUCCESS: return -1 + __previous_twentieth(&mdy) + cdef TDate r + if JpmcdsMDYToDate(&mdy, &r) != SUCCESS: + return -1 + if roll: + return next_business_day(r, FOLLOW) + else: + return r + + +cdef inline void __previous_twentieth(TMonthDayYear* mdy) nogil: if mdy.day < 20: if mdy.month == 1: mdy.month = 12 @@ -56,19 +67,35 @@ cdef TDate _previous_twentieth(TDate d, bint roll) nogil: if mdy.month <= 0: mdy.month += 12 mdy.year -= 1 - cdef TDate r - if JpmcdsMDYToDate(&mdy, &r) != SUCCESS: - return -1 - else: - if roll: - return next_business_day(r, FOLLOW) + + + +def previous_twentieth(c_datetime.date d, bint roll=True): + cdef: + TMonthDayYear mdy = [date_month(d), date_day(d), date_year(d)] + TDate r + __previous_twentieth(&mdy) + if roll: + if JpmcdsMDYToDate(&mdy, &r) != SUCCESS: + raise ValueError("Incorrect date") else: - return r + return TDate_to_pydate(next_business_day(r, FOLLOW)) + else: + return c_datetime.date_new(mdy.year, mdy.month, mdy.day) -def previous_twentieth(d, bint roll=True): - cdef TDate date = pydate_to_TDate(d) - return TDate_to_pydate(_previous_twentieth(date, roll)) +def next_twentieth(d, bint roll=True): + cdef: + TMonthDayYear mdy = [date_month(d), date_day(d), date_year(d)] + TDate r + _next_twentieth(&mdy) + if roll: + if JpmcdsMDYToDate(&mdy, &r) != SUCCESS: + raise RuntimeError + else: + return TDate_to_pydate(next_business_day(r, FOLLOW)) + else: + return c_datetime.date_new(mdy.year, mdy.month, mdy.day) @cython.cdivision(True) @@ -83,9 +110,7 @@ def cds_accrued(d, double coupon, bint include_cashflow=False): return (date - date_prev)/360. * coupon -cdef TMonthDayYear next_twentieth(TDate d) nogil: - cdef TMonthDayYear mdy - JpmcdsDateToMDY(d, &mdy) +cdef TMonthDayYear _next_twentieth(TMonthDayYear* mdy) nogil: if mdy.day > 20: if mdy.month == 12: mdy.month = 1 @@ -99,7 +124,7 @@ cdef TMonthDayYear next_twentieth(TDate d) nogil: if mdy.month > 12: mdy.month -= 12 mdy.year += 1 - return mdy + cdef inline TDate next_business_day(TDate date, long method) nogil: cdef TDate r @@ -116,8 +141,10 @@ cdef void _roll_date(TDate d, const double* tenors, int n_dates, TDate* output) int months size_t i + if d <= cutoff: - d_rolled = next_twentieth(d + 1) + JpmcdsDateToMDY(d + 1, &d_rolled) + _next_twentieth(&d_rolled) else: JpmcdsDateToMDY(d, &d_rolled) if ((d_rolled.month > 9) or ((d_rolled.month == 9) and (d_rolled.day >= 20))) or \ |
