summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyisda/curve.pyx47
1 files changed, 23 insertions, 24 deletions
diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx
index eb3d40e..d721666 100644
--- a/pyisda/curve.pyx
+++ b/pyisda/curve.pyx
@@ -289,6 +289,24 @@ cdef class YieldCurve(Curve):
<double>1, self._thisptr.fDayCountConv)
return yc
+cdef inline void tweak_curve(TCurve* sc, TCurve* sc_tweaked, double epsilon,
+ double* h, double* T, bint* mask, int n):
+ cdef h1, h2, t1, t2
+ h1 = t1 = 0
+ for i in range(n):
+ h2 = sc.fArray[i].fRate
+ t2 = T[i]
+ h[i] = (h2 * t2 - h1 * t1) / (t2 - t1)
+ if mask[i]:
+ h[i] *= (1 + epsilon)
+ h1, t1 = h2, t2
+ t1 = 0
+ cdef double c = 0
+ for i in range(n):
+ c += (T[i] - t1) * h[i]
+ sc_tweaked.fArray[i].fRate = c/T[i]
+ t1 = T[i]
+
cdef class SpreadCurve(Curve):
"""
Initialize a SpreadCurve from a list of spreads and maturity.
@@ -405,39 +423,20 @@ cdef class SpreadCurve(Curve):
## into forward rates and then back
cdef double t1, h1, t2, h2
cdef TCurve* curve = self._thisptr
+ cdef TCurve* curve_tweaked
cdef SpreadCurve sc
cdef int num_items = curve.fNumItems
if not inplace:
sc = SpreadCurve.__new__(SpreadCurve)
- sc._thisptr = JpmcdsCopyCurve(curve)
-
- t1 = 0
- h1 = 0
+ sc._thisptr = curve_tweaked = JpmcdsCopyCurve(curve)
+ else:
+ curve_tweaked = curve
cdef double* h = <double*>malloc(num_items * sizeof(double))
cdef double* T = <double*>malloc(num_items * sizeof(double))
if mask is not None:
if mask.size != curve.fNumItems:
raise ValueError("mask size need to be the same as the number of Items")
- for i in range(num_items):
- h2 = curve.fArray[i].fRate
- t2 = T[i] = (curve.fArray[i].fDate - curve.fBaseDate)/365.
- h[i] = (h2 * t2 - h1 * t1) / (t2 - t1)
- if mask is None or mask[i]:
- h[i] *= (1+epsilon)
- h1 = h2
- t1 = t2
- t1 = 0
- cdef double c = 0
- cdef TRatePt* update
- if inplace:
- update = curve.fArray
- else:
- update = curve.fArray
-
- for i in range(curve.fNumItems):
- c += (T[i] - t1) * h[i]
- update[i].fRate = c/T[i]
- t1 = T[i]
+ tweak_curve(curve, curve_tweaked, epsilon, h, T, &mask[0], num_items)
free(h)
free(T)
if inplace: