diff options
| author | Guillaume Horel <guillaume.horel@gmail.com> | 2018-03-19 15:09:53 -0400 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@gmail.com> | 2018-03-19 18:07:04 -0400 |
| commit | dd34b0aa8599933e118a4b6d0efdd347d5541a4a (patch) | |
| tree | d47bfa4b044d2346362a399c8606e907f9ac37e1 | |
| parent | a1554f98515d506e5b494b4d849b91306744163e (diff) | |
| download | pyisda-dd34b0aa8599933e118a4b6d0efdd347d5541a4a.tar.gz | |
add roll_date function
| -rw-r--r-- | pyisda/curve.pyx | 66 | ||||
| -rw-r--r-- | pyisda/date.pxd | 1 | ||||
| -rw-r--r-- | pyisda/date.pyx | 2 |
3 files changed, 67 insertions, 2 deletions
diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index 7fbc151..6748f92 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -1,8 +1,11 @@ -from libc.math cimport log1p, log +from libc.math cimport log1p, log, nearbyint +from libc.stdio cimport printf + from date cimport (JpmcdsStringToDateInterval, pydate_to_TDate, dcc, TMonthDayYear, JpmcdsDateIntervalToFreq, JpmcdsDateFwdThenAdjust, TDate_to_pydate, JpmcdsDateFromBusDaysOffset, JpmcdsStringToDayCountConv, ACT_360, - JpmcdsDateToMDY, JpmcdsMDYToDate, JpmcdsFormatDate) + JpmcdsDateToMDY, JpmcdsMDYToDate, JpmcdsMakeDateInterval, + JpmcdsDtFwdAny, JpmcdsFormatDate, JpmcdsFormatDateInterval) from date import dcc_tostring from cdsone cimport JpmcdsStringToStubMethod, TStubMethod from legs cimport (JpmcdsCdsContingentLegMake, JpmcdsCdsFeeLegMake, @@ -63,6 +66,65 @@ cdef TDate previous_twentieth(TDate d) nogil: else: return r +cdef TDate next_twentieth(TDate d) nogil: + cdef TMonthDayYear mdy + if JpmcdsDateToMDY(d, &mdy) != SUCCESS: + return -1 + if mdy.day > 20: + if mdy.month == 12: + mdy.month = 1 + mdy.year += 1 + else: + mdy.month += 1 + mdy.day = 20 + cdef int mod = mdy.month % 3 + if mod != 0: + mdy.month += 3 - mod + if mdy.month > 12: + mdy.month -= 12 + mdy.year += 1 + cdef TDate r + if JpmcdsMDYToDate(&mdy, &r) != SUCCESS: + return -1 + else: + return r + +cpdef TDate roll_date(TDate d, double tenor): + cdef TDate cutoff = 151472 + cdef TDateInterval ivl + cdef TDate d_rolled + cdef TMonthDayYear d1 + if tenor < 1: + if JpmcdsMakeDateInterval(<int>nearbyint(tenor * 12), "M", &ivl) != SUCCESS: + return -1 + else: + if JpmcdsMakeDateInterval(<int>nearbyint(tenor), "A", &ivl) != SUCCESS: + return -1 + if JpmcdsDtFwdAny(d, &ivl, &d_rolled) != SUCCESS: + return -1 + if d <= cutoff: + return next_twentieth(d_rolled + 1) + else: + if JpmcdsDateToMDY(d, &d1) != SUCCESS: + return -1 + if ((d1.month > 9) or ((d1.month == 9) and (d1.day >= 20))) or \ + ((d1.month < 3) or ((d1.month == 3) and (d1.day < 20))): + if JpmcdsDateToMDY(d_rolled, &d1) != SUCCESS: + return -1 + if d1.month <= 3: + d1.year -= 1 + d1.month = 12 + d1.day = 20 + else: + if JpmcdsDateToMDY(d_rolled, &d1) != SUCCESS: + return -1 + d1.month = 6 + d1.day = 20 + if JpmcdsMDYToDate(&d1, &d_rolled) != SUCCESS: + return -1 + else: + return d_rolled + cdef class Curve(object): def __getstate__(self): diff --git a/pyisda/date.pxd b/pyisda/date.pxd index 56d1e45..10693fc 100644 --- a/pyisda/date.pxd +++ b/pyisda/date.pxd @@ -22,6 +22,7 @@ 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) char* JpmcdsFormatDate(TDate date) + char* JpmcdsFormatDateInterval(TDateInterval*) cdef extern from "isda/date_sup.h" nogil: int JpmcdsDateIntervalToFreq(TDateInterval* interval, double* freq) diff --git a/pyisda/date.pyx b/pyisda/date.pyx index 5854e70..50cff66 100644 --- a/pyisda/date.pyx +++ b/pyisda/date.pyx @@ -11,6 +11,8 @@ cpdef c_datetime.date TDate_to_pydate(TDate d): cdef TMonthDayYear date if JpmcdsDateToMDY(d, &date) == 0: return c_datetime.date_new(date.year, date.month, date.day) + else: + raise ValueError("incorrect date") cdef long dcc(str day_count) except -1: cdef long r |
