diff options
Diffstat (limited to 'python/tranche_functions.py')
| -rw-r--r-- | python/tranche_functions.py | 82 |
1 files changed, 68 insertions, 14 deletions
diff --git a/python/tranche_functions.py b/python/tranche_functions.py index 72a06b4b..6e095ed5 100644 --- a/python/tranche_functions.py +++ b/python/tranche_functions.py @@ -1,7 +1,8 @@ import numpy as np from ctypes import * +import pdb -libloss = np.ctypeslib.load_library("lossdistribgomez", "/home/share/CorpCdos/code/R") +libloss = np.ctypeslib.load_library("lossdistrib", "/home/share/CorpCDOs/code/R") libloss.fitprob.restype = None libloss.fitprob.argtypes = [np.ctypeslib.ndpointer('double', ndim=1, flags='F'), np.ctypeslib.ndpointer('double', ndim=1, flags='F'), @@ -11,14 +12,29 @@ libloss.fitprob.argtypes = [np.ctypeslib.ndpointer('double', ndim=1, flags='F'), np.ctypeslib.ndpointer('double', ndim=1, flags='F,writeable')] libloss.stochasticrecov.restype = None libloss.stochasticrecov.argtypes = [POINTER(c_double), - POINTER(c_double), - np.ctypeslib.ndpointer('double', ndim=1, flags='F'), - np.ctypeslib.ndpointer('double', ndim=1, flags='F'), - POINTER(c_int), - POINTER(c_double), - POINTER(c_double), - POINTER(c_double), - np.ctypeslib.ndpointer('double', ndim=1, flags='F,writeable')] + POINTER(c_double), + np.ctypeslib.ndpointer('double', ndim=2, flags='F'), + np.ctypeslib.ndpointer('double', ndim=2, flags='F'), + POINTER(c_int), + POINTER(c_double), + POINTER(c_double), + POINTER(c_double), + np.ctypeslib.ndpointer('double', ndim=1, flags='F,writeable')] +libloss.BClossdist.restype = None +libloss.BClossdist.argtypes = [np.ctypeslib.ndpointer('double', ndim=2, flags='F'),# defaultprob + POINTER(c_int),# nrow(defaultprob) + POINTER(c_int),# ncol(defaultprob) + np.ctypeslib.ndpointer('double', ndim=1, flags='F'),# issuerweights + np.ctypeslib.ndpointer('double', ndim=1, flags='F'),# recovery + np.ctypeslib.ndpointer('double', ndim=1, flags='F'),# Z + np.ctypeslib.ndpointer('double', ndim=1, flags='F'),# w + POINTER(c_int), # len(Z) = len(w) + np.ctypeslib.ndpointer('double', ndim=1, flags='F'), # rho + POINTER(c_int), # Ngrid + POINTER(c_int), #defaultflag + np.ctypeslib.ndpointer('double', ndim=2, flags='F,writeable'),# output L + np.ctypeslib.ndpointer('double', ndim=2, flags='F,writeable')# output R + ] libgq = np.ctypeslib.load_library("GHquad", ".") libgq.GHquad.restype = None @@ -36,12 +52,50 @@ def stochasticrecov(R, Rtilde, Z, w, rho, porig, pmod): byref(c_double(rho)), byref(c_double(porig)), byref(c_double(pmod)), q) return q - -# def lossdistZ(p, w, S, N, defaultflag= False, rho, Z, wZ): -# q = np.zeros_like(Z) -# lib.lossdistrib_Z(byref()) - def fitprob(Z, w, rho, p0): result = np.empty_like(Z) libloss.fitprob(Z, w, byref(c_int(Z.size)), byref(c_double(rho)), byref(c_double(p0)), result) return result + +def BClossdist(defaultprob, issuerweights, recov, rho, Z, w, Ngrid = 101, defaultflag = False): + L = np.zeros((Ngrid, defaultprob.shape[1]), order='F') + R = np.zeros_like(L) + rho = np.repeat(rho, issuerweights.size) + libloss.BClossdist(defaultprob, byref(c_int(defaultprob.shape[0])), byref(c_int(defaultprob.shape[1])), + issuerweights, recov, Z, w, byref(c_int(Z.size)), rho, + byref(c_int(Ngrid)), byref(c_int(defaultflag)), L, R) + return L, R + +def trancheloss(L, K1, K2): + np.maximum(L - K1, 0) - np.maximum(L - K2, 0) + +def trancherecov(R, K1, K2): + np.maximum(R - 1 + K2, 0) - np.maximum(R - 1 + K1, 0) + +def tranche_cl(L, R, cs, K1, K2, scaled = False): + if(K1 == K2): + return 0 + else: + support = np.linspace(0, 1, L.shape[0]) + size = K2 - K1 - np.dot(trancheloss(support, K1, K2), L) - + np.dot(trancherecov(support, K1, K2), R) + sizeadj = 0.5 * (size + np.hstack([K2-K1], size[:-1])) + if scaled: + return 1/(K2-K1) * np.dot(sizeadj * cs["coupons"], cs["df"]) + else: + return np.dot(sizeadj * cs["coupons"], cs["df"]) + +def tranche_pl(L, cs, K1, K2, scaled=False): + if(K1 == K2): + return 0 + else: + support = np.linspace(0, 1, L.shape[0]) + cf = K2 - K1 - np.dot(trancheloss(support, K1, K2), L) + cf = np.hstack([K2-K1], cf) + if scaled: + return 1/(K2-K1) * np.dot(np.diff(cf), cs["df"]) + else: + return np.dot(np.diff(cf), cs["df"]) + +def tranche_pv(L, R, cs, K2, K2): + tranche_pl(L, cs, K1, K2) + tranche_cl(L, R, cs, K2, K2) |
