summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2018-03-19 15:09:53 -0400
committerGuillaume Horel <guillaume.horel@gmail.com>2018-03-19 18:07:04 -0400
commitdd34b0aa8599933e118a4b6d0efdd347d5541a4a (patch)
treed47bfa4b044d2346362a399c8606e907f9ac37e1
parenta1554f98515d506e5b494b4d849b91306744163e (diff)
downloadpyisda-dd34b0aa8599933e118a4b6d0efdd347d5541a4a.tar.gz
add roll_date function
-rw-r--r--pyisda/curve.pyx66
-rw-r--r--pyisda/date.pxd1
-rw-r--r--pyisda/date.pyx2
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