In [11]:
%matplotlib inline
In [1]:
import numpy as np
import pandas as pd
import tensorflow as tf
from scipy.stats import mvn, norm
import itertools
marker = itertools.cycle((',', '+', '.', 'o', '*'))
from IPython.core.pylabtools import figsize
figsize(15, 4)
pd.options.display.max_colwidth = 60
from pprint import pprint
def np_cdf(mean, diag_sigma, value, name=None):
low = np.array([-30, -30])
cdf = list()
for s in value:
# mvn.mvnun(low, upp, mean, cov)
p, _ = mvn.mvnun(low, upper=s, covar=diag_sigma, means=mean)
cdf.append(p)
cdfs = np.asarray(cdf, dtype=np.float32).reshape([-1, 1])
return cdfs
def cartesian(arrays, out=None):
"""
Generate a cartesian product of input arrays.
Parameters
----------
arrays : list of array-like
1-D arrays to form the cartesian product of.
out : ndarray
Array to place the cartesian product in.
Returns
-------
out : ndarray
2-D array of shape (M, len(arrays)) containing cartesian products
formed of input arrays.
Examples
--------
>>> cartesian(([1, 2, 3], [4, 5], [6, 7]))
array([[1, 4, 6],
[1, 4, 7],
[1, 5, 6],
[1, 5, 7],
[2, 4, 6],
[2, 4, 7],
[2, 5, 6],
[2, 5, 7],
[3, 4, 6],
[3, 4, 7],
[3, 5, 6],
[3, 5, 7]])
"""
arrays = [np.asarray(x) for x in arrays]
dtype = arrays[0].dtype
n = np.prod([x.size for x in arrays])
if out is None:
out = np.zeros([n, len(arrays)], dtype=dtype)
m = n / arrays[0].size
out[:,0] = np.repeat(arrays[0], m)
if arrays[1:]:
cartesian(arrays[1:], out=out[0:m,1:])
for j in range(1, arrays[0].size):
out[j*m:(j+1)*m,1:] = out[0:m,1:]
return out
In [13]:
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator
import matplotlib.pyplot as plt
import numpy as np
low = np.array([-10, -10])
upp = np.array([.1, -.2])
mean = np.array([0, 1])
cov = np.array([(1, .5), (.5, 1)])
fig = plt.figure()
ax = fig.gca(projection='3d')
X0 = np.arange(-5, 5, 0.25)
xlen = len(X0)
Y0 = np.arange(-5, 5, 0.25)
ylen = len(Y0)
X, Y = np.meshgrid(X0, Y0)
data = cartesian(arrays=[X0, Y0])
# init(data, low, upp, 5, 20)
Z = np_cdf(mean=mean, diag_sigma=cov, value=data, name=None).reshape([xlen,ylen])
colortuple = ('y', 'b')
colors = np.empty(X.shape, dtype=str)
for y in range(ylen):
for x in range(xlen):
colors[x, y] = colortuple[(x + y) % len(colortuple)]
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=colors,
linewidth=0, antialiased=False)
ax.set_zlim3d(-1, 1)
ax.w_zaxis.set_major_locator(LinearLocator(6))
plt.show()
I am reviewing this Tuesday’s slide. In page 11(lecture 9), the tranche notional is calculated as J(K1,K2)=Q(K1,K2,T)*(K2-K1). I do not quite understand what this notional mean.
According to page 9, tranche notional loss = E[min(LT,K2)]-E[min(LT,K1)]. Is this notional the same one as J(K1,K2)?
If they are the same, then J(K1,K2)=[1-Q(K1,K2,T)] * (K2-K1), by using Q(K1,K2,T) = 1-{E[min(LT,K2)]-E[min(LT,K1)] / (K2-K1)}. Is this right?
In [14]:
R=0.4
PD= 0.05 # Probability of default per year
PD = np.array([0.05*x for x in range(1,100) ]) # Probability of default per year
beta = 0.3
CT = norm.ppf(PD)
x = 0.5
In [15]:
def AA(CT,x,R):
AAA = CT - np.sqrt(1-beta*beta)*norm.ppf(x/(1-R))
AAA[AAA < -10]=-10
AAA[AAA > 10] = 10
return AAA
In [16]:
def Emin(K,R,CT,beta):
mean=np.array([0,0])
cov = np.array([[1,-beta],[-beta,1]])
AAK = AA(CT=CT,x=K,R=R)
upp = np.array([(x,y) for x,y in zip(CT,-AAK)])
A = np_cdf(mean=mean, diag_sigma=cov, value=upp, name=None)
A = np.asarray(A, dtype=np.float32).reshape([-1, 1])
B = norm.cdf(AAK)
B = np.asarray(B, dtype=np.float32).reshape([-1, 1])
return K*((1-R)*A + B)
In [17]:
def Q(K1,K2,CT,R,beta):
QQ1 = Emin(K=K1,R=R,CT=CT,beta=beta)
QQ2 = Emin(K=K2,R=R,CT=CT,beta=beta)
QQ =1- (QQ2-QQ1)/(K2-K1)
return QQ,QQ1,QQ2
In [18]:
K1=0.03
K2 = 0.06
R=0.4
beta=0.3
QQ,QQ1,QQ2= Q(K1,K2,CT,R,beta)
In [19]:
x=CT
fig = plt.figure()
fig.suptitle('CDO Tranche Loss Function', fontsize=14, fontweight='bold')
ax = fig.add_subplot(111)
ax.set_xlabel('CDO Tranche Loss versus Default Barrier Height')
ax.set_ylabel('Accumulated Tranche Loss')
ax.plot(x,QQ1)
ax.plot(x,QQ2)
plt.show()
In [20]:
fig = plt.figure()
fig.suptitle('CDO Tranche Survival Function', fontsize=14, fontweight='bold')
ax = fig.add_subplot(111)
ax.set_xlabel('CDO Tranche Loss versus Default Barrier Height')
ax.set_ylabel('Tranche Survival Function')
ax.plot(x,QQ)
plt.show()
In [ ]: