The world’s leading publication for data science, AI, and ML professionals.

Predicting bankruptcy: The Contingent Claim Model

An alternative approach used among others by Moody's to rate companies

Photo by Dylan Gillis on Unsplash
Photo by Dylan Gillis on Unsplash

Bankruptcy prediction has been a very active field of research for many years. Important papers include Edward Altman’s 1968 Financial Ratios, Discriminant Analysis and the Prediction of Corporate Bankruptcy which gave birth to his famous Z-score, still used today, and James Ohlson’s 1980 Financial Ratios and the Probabilistic Prediction of Bankruptcy and its O-score, also still applied today. Those papers, and many after them, are based on accounting data and financial ratios. They use different classification and optimisation techniques: logistic regression, discriminant analysis, neural networks, ant colony algorithms and many more, and train them mainly on financial data taken from the income statement, the balance sheet and the cash flow statement.

Robert Merton (MIT, CC BY-SA 4.0)
Robert Merton (MIT, CC BY-SA 4.0)

Other approaches use market data to derive the risk of Bankruptcy. One market based approach in particular uses an idea developed by Black and Scholes in 1973, and Merton in 1974, to price options and corporate debt using what is probably the most emblematic results in financial mathematics: the Black-Scholes equation and the Black-Scholes formula. This corporate debt pricing method is the one used by credit analysts Kealhofer, McQuown, and Vasicek (KMV), acquired by the notation agency Moody’s in 2002.

Before we move to the method, let’s quickly define what options are. An option is a financial derivative allowing its owner to buy (for a "call" option) or sell (a "put" option) an underlying asset (very often a share) at a given price at a given date in the future (in the case of European options, anytime before that date for American options). Merton developed the idea that the equity in a company can be viewed as a European Call Option on the company’s assets, once the debt has been paid out. Because of the limited liability of equity owners, if the assets are not enough to pay the debt, the equity value is simply null. Any assets remaining after the debt has been paid off can then be claimed by the equity owners.

How do we price options or, equivalently, the equity? This is when the Black-Scholes model comes in. Its underlying idea is that a firm’s assets follow a geometric Brownian motion:

In the formula above, W is a standard Wiener process. We see that incorporating volatility is what makes this method different from more traditional accounting-based approaches.

The market value for equity can be obtained by the Black and Scholes formula for European call options as follows:

With

Ve: market of value of equity T: maturity time of the debt X: book value of the debt, equivalent the strike value of the strike price of the call option r: risk-free rate sigma_a: volatility of the assets returns N: cumulative density function of the standard normal distribution;

Now, the probability of bankruptcy is the probability that the market value of the assets is smaller than the face value of the liabilities maturing at time T and it calculated as follows:

But, we don’t know the values of Va and sigma_a so to calculate them we simultaneously solve equation (1) given above and the "optimal hedge" equation (2) given here below:

We can now calculate the drift, mu. It indicates the general trend in the fluctuations of the assets value. It is taken as the maximum between the risk-free rate and the asset returns:

And finally, the probability of failure, which follows a normal distribution:

We use a threshold of 0.5 on the probabilities output by the model to classify companies into bankrupt and non-bankrupt.

It is important to mention we are using a very simple implementation on the model with the following assumptions/limitations:

  • we are not considering dividend payments
  • no transactions costs
  • same rate for borrowing and lending
  • the risk-free rate doesn’t vary

Implementation in Python

We will now see an implementation in Python, using the ideas described above.

We’ll define a function called _probdefault() that takes a ticker as argument and run it for data for all tickers on the NYSE, Nasdaq and OTC markets in 2018.

The function select the daily stock price data corresponding to the ticker passed as argument for the time frame we are considering, we call that dataframe _daily__

"""DATA SELECTION"""    
start_date='2018-01-01'    
end_date='2018-12-31' 

# get data for that ticker    
daily_=daily[(daily.ticker==ticker)&amp;(daily.date>=start_date)&amp;(daily.date<=end_date)]    
# if get an empty dataframe, we skip that ticker    
if daily_.shape[0]==0:        
    print(ticker+" is empty")        
    return False
daily_=daily_.reset_index()
# we show the marketcap in the right unit   
daily_.marketcap=daily_.marketcap*1e6

We then calculate the daily returns on equity for that period using the logarithm of the ratio between the value of the equity 1 day apart:

"""CALCULATING EQUITY RETURNS"""    
for j in range(1,daily_.shape[0]):        
    daily_.loc[j-1, 'returns'] = np.log(daily_.loc[j-1, 'marketcap'] /daily_.loc[j, 'marketcap'])

We can then use these data to calculate the annualised volatility of the equity. To annualise the volatility we multiply the standard deviation of the daily returns by the square root of 252 (the number of trading days in a year)

"""CALCULATING THE VOLATILITY OF EQUITY: SIGE"""  sige=np.std(daily_.returns)*np.sqrt(252)

We can now solve the simultaneous equations (1) and (2) described above to find Va and sigma_a. We use the values 1.7% and 1.5% for the risk-free rate in 2018 and 2017 respectively. For the value of the debt, X, we use the value of the current debt + 50% of the value of the non-current debt.

We can then solve for the market value of the assets and their volatility using the root function of the optimize library on SciPy. We need to find those values for 2018 but also for 2017. Why for 2017? Because we want to find out the average yearly return on assets as well. So we start with 2018.

"""SOLVE SIMULTANEOUS EQUATIONS for 2018"""    
#2018    
# Initialising values    
T=1    
r=0.017    
ve=daily_.loc[0,'marketcap']   
X=df[df.ticker==ticker]['debtc'].values[0]+.5*df[df.ticker==ticker]['debtnc'].values[0]    
sol = optimize.root(fun, [X+ve, sige*ve/(ve+X)])    
va=sol.x[0]    
siga=sol.x[1]

And follow with 2017.

#2017    
T=1    
r=0.015    
ve=daily_.loc[daily_.shape[0]-1,'marketcap']    X=df[df.ticker==ticker]['debtc'].values[0]+.5*df[df.ticker==ticker]['debtnc'].values[0]    
sol = optimize.root(fun, [X+ve, sige*ve/(ve+X)])    
va_1=sol.x[0]    
siga=sol.x[1]

And here comes our final step, we calculate the annual returns on assets by using our va and va_1 variables from 2018 and 2017. When the resulting returns are lower than the risk-free rate, we use the risk-free rate.

We can now calculate the "distance to default" DDt and the probability of default using the normal cdf.

#this gives the annual return    
mu=max((va-va_1)/va_1,r)    
DDt=(np.log(va/X)+(mu-0.5*siga**2)*T)/siga*np.sqrt(T)    
return norm.cdf(-DDt)

We can test our function on Apple, Inc. (‘AAPL’) and Jones Energy, Inc.(‘JONEQ’), we get a probability of 1e-19% for Apple and 60% for Jones Energy. We’ll see in the next section how the method performed for the whole dataset.

The full code can be found below

Results on data from 2018

We can now run the model on the whole dataset from 2017 and 2018 and see how well it predicts bankruptcies happening in 2019. It is a highly imbalanced dataset as we have 3,237 companies and only 30 of them declared bankruptcy in 2019, that is 0.9%. In those cases it is better to use the F1-score to judge the performance of our model, as precision and recall are a lot more meaningful than accuracy in this case.

We used a threshold of 0.5 to classify the firms into bankrupt and non-bankrupt but it looks like a lower threshold would have improved our F1-score.

Looking at the figures below, we obtained 8% precision, 30% recall and a F1-score of 12% (and 96% accuracy). The AUC is 87%.

Results of the contingent claim predictive model: confusion matrix, ROC curve, metrics vs. threshold and the Accuracy Ratio.
Results of the contingent claim predictive model: confusion matrix, ROC curve, metrics vs. threshold and the Accuracy Ratio.

While those results might look bad, it is important to note we implemented a very basic version of the model. We can significantly improve it by:

  • calibrating better the cut-off point for the probabilities. A lower threshold improves the recall (but also generates a lot of false positives).
  • incorporating dividend payments into the model
  • using other distributions than the normal distribution (this is the approach used by Moody’s/KMV)
  • not incorporating OTC markets as reporting requirements are less stringent than the NYSE or NASDAQ

Note from Towards Data Science‘s editors: While we allow independent authors to publish articles in accordance with our rules and guidelines, we do not endorse each author’s contribution. You should not rely on an author’s works without seeking professional advice. See our Reader Terms for details.

References

Hillegeist, S. A., Keating, K. E., Cram, D. P., & Lundstedt, K. G. (2004). Assessing the probability of bankruptcy. Review of Accounting Studies, 9(1), 5–34

Merton, R. C. (1974). On the pricing of corporate debt: the risk structure of interest rates, Journal of Finance, 29(2), 449–470.

Vassalou, M., & Xing, Y. (2004). Default risk in equity returns. Journal of Finance, 59(2), 831–868


Related Articles