diff options
| author | Guillaume Horel <guillaume.horel@serenitascapital.com> | 2016-06-30 15:02:10 -0400 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@serenitascapital.com> | 2016-06-30 15:02:47 -0400 |
| commit | f1bed268cfd976966b6bab376a59c52dfd0216fa (patch) | |
| tree | d35cf7a08ec376ac0f5e53ec2aa88d12962528f2 /curve.pyx | |
| parent | 6b0a14370d244d4ff3b6277c49a23b04b8957678 (diff) | |
| download | pyisda-f1bed268cfd976966b6bab376a59c52dfd0216fa.tar.gz | |
rename zerocurve to curve, and merge yearfrac with date
Diffstat (limited to 'curve.pyx')
| -rw-r--r-- | curve.pyx | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/curve.pyx b/curve.pyx new file mode 100644 index 0000000..a5eb2d2 --- /dev/null +++ b/curve.pyx @@ -0,0 +1,84 @@ +from cpython cimport datetime +from libc.stdlib cimport malloc, free +from pyisda.zerocurve cimport JpmcdsBuildIRZeroCurve, JpmcdsZeroPrice +from pyisda.yearfrac cimport dcc +from pyisda.date cimport (JpmcdsStringToDateInterval, pydate_to_TDate, + JpmcdsDateIntervalToFreq, JpmcdsDateFwdThenAdjust, TDate_to_pydate, + JpmcdsDateFromBusDaysOffset) + +cdef int SUCCESS = 0 + +cpdef public enum BadDay: + FOLLOW = <long>'F' + PREVIOUS = <long>'P' + NONE = <long>'N' + MODIFIED = <long>'M' + +cdef class ZeroCurve: + + def __init__(self, date, str types, + list periods, double[:] rates, + str mm_dcc, str fixed_swap_period, str float_swap_period, + str fixed_swap_dcc, str float_swap_dcc, BadDay bad_day_conv): + """ Initialize a zero coupon curve + + instruments need to be sorted by tenor + """ + cdef: + double fixed_freq + double float_freq + TDateInterval ivl + char* routine = 'zerocurve' + TDate value_date = pydate_to_TDate(date) + + self._dates = <TDate*>malloc(len(periods) * sizeof(TDate)) + self._ninstr = len(periods) + + cdef TDate settle_date + if JpmcdsDateFromBusDaysOffset(value_date, 2, "None", &settle_date)!= SUCCESS: + raise ValueError + + cdef TDateInterval tmp + for i, p in enumerate(periods): + period_bytes = p.encode('utf-8') + if JpmcdsStringToDateInterval(period_bytes, routine, &tmp) != SUCCESS: + raise ValueError + if JpmcdsDateFwdThenAdjust(settle_date, &tmp, NONE, + "None", &self._dates[i]) != SUCCESS: + raise ValueError('Invalid interval') + + fixed_bytes = fixed_swap_period.encode('utf-8') + float_bytes = float_swap_period.encode('utf-8') + types_bytes = types.encode('utf-8') + + if JpmcdsStringToDateInterval(fixed_bytes, routine, &ivl) != SUCCESS: + raise ValueError + if JpmcdsDateIntervalToFreq(&ivl, &fixed_freq) != SUCCESS: + raise ValueError + if JpmcdsStringToDateInterval(float_bytes, routine, &ivl) != SUCCESS: + raise ValueError + if JpmcdsDateIntervalToFreq(&ivl, &float_freq) != SUCCESS: + raise ValueError + + self._thisptr = JpmcdsBuildIRZeroCurve( + value_date, types_bytes, self._dates, + &rates[0], len(periods), dcc(mm_dcc), <long> fixed_freq, + <long> float_freq, dcc(fixed_swap_dcc), dcc(float_swap_dcc), + bad_day_conv, b"None" + ) + + def __dealloc__(self): + if self._thisptr is not NULL: + JpmcdsFreeTCurve(self._thisptr) + if self._dates is not NULL: + free(self._dates) + + def discount_factor(self, date): + if self._thisptr is NULL: + raise ValueError('curve is empty') + cdef TDate discount_date = pydate_to_TDate(date) + return JpmcdsZeroPrice(self._thisptr, discount_date) + + def list_dates(self): + cdef size_t i + return [TDate_to_pydate(self._dates[i]) for i in range(self._ninstr)] |
