summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyisda/date.pyx57
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 \