<jupyter_start><jupyter_text>Loss Distribution Builder We build a credit default loss distribution first for a homogeneous portfolio and then for a inhomogeneous portfolio. I compare the result with my fast adjusted binomial approximation.<jupyter_code>import sys
sys.path.append("..")
sys.path.append("..\\..")
from importlib import reload
import numpy as np
import matplotlib.pyplot as plt
from financepy.finutils.FinTestCases import FinTestCases, globalTestCaseMode
from financepy.models.FinGaussianCopula1FModel import lossDbnRecursionGCD
from financepy.models.FinGaussianCopula1FModel import lossDbnHeterogeneousAdjBinomial<jupyter_output><empty_output><jupyter_text>The Homogeneous Credit Portfolio We set the portfolio size<jupyter_code>numCredits = 500<jupyter_output><empty_output><jupyter_text>We set the market factor weight and homogeneous default probability<jupyter_code>beta = 0.50
defaultProb = 0.30<jupyter_output><empty_output><jupyter_text>We set the credit quality and factor correlation for each credit, here all assumed to be the same<jupyter_code>defaultProbs = np.ones(numCredits) * defaultProb
betaVector = np.ones(numCredits) * beta<jupyter_output><empty_output><jupyter_text>We also define the vector of loss units that defines the number of units of loss for each credit. Here we assume that the default of each credit results in the same loss of one.<jupyter_code>lossUnits = np.ones(numCredits)<jupyter_output><empty_output><jupyter_text>There is an internal integration over the Gaussian market factor<jupyter_code>numSteps = 100<jupyter_output><empty_output><jupyter_text>Now we determine the full loss distribution<jupyter_code>%%time
dbn1 = lossDbnRecursionGCD(numCredits, defaultProbs, lossUnits, betaVector, numSteps)
x = np.linspace(0, numCredits, numCredits + 1)
plt.figure()
plt.plot(x, dbn1, label='GCD FULL')
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>Using Fast Approximate Scheme The call is identical.<jupyter_code>%%time 
dbn2 = lossDbnHeterogeneousAdjBinomial(numCredits, defaultProbs, lossUnits, betaVector, numSteps)<jupyter_output>Wall time: 14 ms<jupyter_text>We can plot them both<jupyter_code>x = np.linspace(0, numCredits, numCredits + 1)
plt.figure()
plt.plot(x, dbn1, label='GCD FULL')
plt.plot(x, dbn2, label='ADJ BIN')
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>The difference is computed simply as follows<jupyter_code>diff = dbn2 - dbn1<jupyter_output><empty_output><jupyter_text>We can also set the put schedule - the price and date on which the owner can put back the bond to the issuer. This is given with reference to a price of 100. Making the put price very low means it will never be put.<jupyter_code>x = np.linspace(0, numCredits, numCredits + 1)
plt.figure()
plt.plot(x, diff, label='DIFFERENCE')
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>This is negligible. The approximate method is 10-20 times faster than the exact method for effectively the same result. This is good. But we need to see how it does on an inhomogeneous credit portfolio.  Inhomogeneous Credit Portfolio<jupyter_code>numCredits = 200
beta = 0.50
defaultProb = 0.10
numSteps = 500<jupyter_output><empty_output><jupyter_text>Note that these all have to be vectors of floats which is why I divide them by a float<jupyter_code>defaultProbs = np.random.randint(1,3, size=(numCredits)) / 10.0
betaVector = np.random.randint(2,10, size=(numCredits)) / 10.0
lossUnits = np.random.randint(1,10, size=(numCredits)) / 1.0
%%time
dbn1 = lossDbnRecursionGCD(numCredits, defaultProbs, lossUnits, betaVector, numSteps)
numLossUnits = int(lossUnits.sum())
x1 = np.linspace(0, numLossUnits, numLossUnits + 1)
plt.figure()
plt.plot(x1/numLossUnits, dbn1, label='GCD FULL')
plt.legend()
plt.show()
averageLoss = lossUnits.sum() / numCredits
lossRatio = lossUnits / averageLoss
%%time 
dbn2 = lossDbnHeterogeneousAdjBinomial(numCredits, defaultProbs, lossRatio, betaVector, numSteps)
x2 = np.linspace(0, numCredits, numCredits + 1) * averageLoss
plt.plot(x1/numLossUnits, dbn1, label='GCD FULL')
plt.plot(x2/numLossUnits, dbn2 / averageLoss, label='ADJ BIN')
plt.legend()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09490960989533777, 'fraction_numerical': 0.018553758325404377, 'mean_word_length': 7.0095238095238095, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '607564', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1497, 'n_tokens_neox': 1414, 'n_words': 392, 'path': 'examples/products/credit/CREDIT_LossDistributionBuilder.ipynb', 'repo_name': 'suhasghorp/FinancePy', 'size': '4204'}