diff options
| -rw-r--r-- | pyisda/credit_index.pxd | 5 | ||||
| -rw-r--r-- | pyisda/credit_index.pyx | 81 | ||||
| -rw-r--r-- | pyisda/curve.pxd | 3 |
3 files changed, 43 insertions, 46 deletions
diff --git a/pyisda/credit_index.pxd b/pyisda/credit_index.pxd index bb9f7ba..c6a76ab 100644 --- a/pyisda/credit_index.pxd +++ b/pyisda/credit_index.pxd @@ -2,14 +2,15 @@ from legs cimport TContingentLeg, TFeeLeg from date cimport TDate from curve cimport TCurve, TRatePt, shared_ptr from libcpp.vector cimport vector +from libcpp.map cimport map +from libcpp.string cimport string cdef class CurveList: cdef TDate _base_date cdef vector[shared_ptr[TCurve]] _curves cdef vector[double] _weights cdef vector[double] _T - cdef list _tickers - cdef dict _tickersdict + cdef map[string, size_t] _tickers cdef class CreditIndex(CurveList): cdef _start_date diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx index fda2053..48d188d 100644 --- a/pyisda/credit_index.pyx +++ b/pyisda/credit_index.pyx @@ -14,38 +14,24 @@ import pandas as pd cdef class CurveList: @cython.cdivision(True) - def __init__(self, curves, tickers=None, double[:] weights=None): - cdef SpreadCurve sc - if isinstance(curves[0], tuple): - sc = <SpreadCurve?>(curves[0][1]) - elif isinstance(curves[0], SpreadCurve): + def __init__(self, curves, double[:] weights=None): + cdef: + SpreadCurve sc + size_t i + + if isinstance(curves[0], SpreadCurve): sc = <SpreadCurve>curves[0] else: - raise TypeError("curves need to be a list of SpreadCurve "\ - "or a list of tuple (SpreadCurve, ticker)") + raise TypeError("curves need to be a list of SpreadCurve") self._T = vector[double](sc._thisptr.get().fNumItems) self._base_date = sc._thisptr.get().fBaseDate - cdef size_t i for i in range(self._T.size()): self._T[i] = (sc._thisptr.get().fArray[i].fDate - self._base_date) / 365. - self._tickers = [] - self._tickersdict = {} - if isinstance(curves[0], tuple): - for i, (t, c) in enumerate(curves): - self._curves.push_back((<SpreadCurve?>c)._thisptr) - self._tickers.append(t) - self._tickersdict[t] = i - else: - for c in curves: - self._curves.push_back((<SpreadCurve?>c)._thisptr) + for i, sc in enumerate(curves): + self._curves.push_back(sc._thisptr) + self._tickers[sc.ticker.encode()] = i - if tickers and not self._tickers: - if len(tickers) != self._curves.size(): - raise ValueError("tickers must have the same length as curves") - else: - self._tickers = tickers - self._tickersdict = {t: i for i, t in enumerate(tickers)} if weights is not None: for i in range(weights.shape[0]): self._weights.push_back(weights[i]) @@ -53,43 +39,53 @@ cdef class CurveList: self._weights = vector[double](self._curves.size(), 1./self._curves.size()) def __getitem__(self, str ticker): - cdef SpreadCurve sc - if ticker in self._tickers: + cdef: + map[string, size_t].iterator got = \ + self._tickers.find(ticker.encode()) + SpreadCurve sc + + if got == self._tickers.end(): + raise KeyError(ticker) + else: sc = SpreadCurve.__new__(SpreadCurve) - sc._thisptr = self._curves[self._tickersdict[ticker]] + sc._thisptr = self._curves[deref(got).second] + sc.ticker = ticker return sc - else: - raise KeyError(ticker) def items(self): ## would need to use a shared pointer to avoid a copy cdef SpreadCurve sc - cdef vector[shared_ptr[TCurve]].iterator it = self._curves.begin() - cdef size_t i - while it != self._curves.end(): + cdef map[string, size_t].const_iterator it = self._tickers.const_begin() + while it != self._tickers.const_end(): sc = SpreadCurve.__new__(SpreadCurve) - sc._thisptr = deref(it) - yield (self._tickers[i], sc) + sc._thisptr = self._curves[deref(it).second] + sc.ticker = (deref(it).first).decode() + yield (sc.ticker, sc) preinc(it) - i = i+1 @property def curves(self): """returns the list of curves inside the porfolio. This is returning the curves by reference so don't delete them.""" - cdef list r = [] - cdef SpreadCurve sc - for i in range(self._curves.size()): + cdef: + list r = [] + SpreadCurve sc + map[string, size_t].const_iterator it = self._tickers.const_begin() + + while it != self._tickers.const_end(): sc = SpreadCurve.__new__(SpreadCurve) - sc._thisptr = self._curves[i] + sc._thisptr = self._curves[deref(it).second] + sc.ticker = (deref(it).first).decode() r.append(sc) + preinc(it) return r @curves.setter def curves(self, list l): - if len(l) != self._curves.size(): - raise ValueError("l should have {} elements".format(len(l))) + cdef size_t len_l = len(l) + if len_l != self._curves.size(): + self._curves.resize(len_l) cdef size_t i for i, c in enumerate(l): @@ -185,10 +181,9 @@ cdef class CreditIndex(CurveList): TDate step_in_date_c = pydate_to_TDate(step_in_date) TDate value_date_c = pydate_to_TDate(value_date) TDate maturity_c = pydate_to_TDate(maturity) - - cdef: TContingentLeg* cl TFeeLeg* fl + TStubMethod stub_type for i in range(self._maturities.size()): if self._maturities[i] == maturity_c: diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index 532a530..6ebba44 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -156,13 +156,14 @@ cdef extern from "<memory>" namespace "std" nogil: cdef class Curve: cdef shared_ptr[TCurve] _thisptr + cdef str ticker cdef class YieldCurve(Curve): cdef TDate* _dates cdef size_t _ninstr cdef class SpreadCurve(Curve): - pass + cdef public str ticker cdef fArray_to_list(TRatePt* fArray, int fNumItems) |
