Main Content

First-to-Default Swaps

This example shows how to price first-to-default (FTD) swaps under the homogeneous loss assumption.

A first-to-default swap is an instrument that pays a predetermined amount when (and if) the first of a basket of credit instruments defaults. The credit instruments in the basket are usually bonds. If you assume that the loss amount following a credit event is the same for all credits in the basket, you are under the homogeneous loss assumption. This assumption makes models simpler because any default in the basket triggers the same payment amount. This example is an implementation of the pricing methodology for these instruments, as described in O'Kane [2]. There are two steps in the methodology:

  • Compute the survival probability for the basket numerically.

  • Use this survival curve and standard single-name credit-default swap (CDS) functionality to find FTD spreads and to price existing FTD swaps.

Fit Probability Curves to Market Data

Given CDS market quotes for each issuer in the basket, use cdsbootstrap to calibrate individual default probability curves for each issuer.

% Interest-rate curve
ZeroDates = datenum({'17-Jan-10','17-Jul-10','17-Jul-11','17-Jul-12',...
'17-Jul-13','17-Jul-14'});
ZeroRates = [1.35 1.43 1.9 2.47 2.936 3.311]'/100;
ZeroData = [ZeroDates ZeroRates];

% CDS spreads
% Each row in MarketSpreads corresponds to a different issuer; each
% column to a different maturity date (corresponding to MarketDates)
MarketDates = datenum({'20-Sep-10','20-Sep-11','20-Sep-12','20-Sep-14',...
'20-Sep-16'});
MarketSpreads = [
   160 195 230 285 330;
   130 165 205 260 305;
   150 180 210 260 300;
   165 200 225 275 295];
% Number of issuers equals number of rows in MarketSpreads
nIssuers = size(MarketSpreads,1);

% Settlement date
Settle = datenum('17-Jul-2009');

In practice, the time axis is discretized and the FTD survival curve is only evaluated at grid points. This example uses one point every three months. To request that cdsbootstrap returns default probability values over the specific grid points that you want, use the optional argument 'ProbDates'. Add the original standard CDS market dates to the grid, otherwise the default probability information on those dates is interpolated using the two closest dates on the grid, and then the prices on market dates will be inconsistent with the original market data.

ProbDates = union(MarketDates,daysadd(Settle,360*(0.25:0.25:8),1));
nProbDates = length(ProbDates);
DefProb = zeros(nIssuers,nProbDates);

for ii = 1:nIssuers
   MarketData = [MarketDates MarketSpreads(ii,:)'];
   ProbData = cdsbootstrap(ZeroData,MarketData,Settle,...
      'ProbDates',ProbDates);
   DefProb(ii,:) = ProbData(:,2)';
end

Here are the calibrated default probability curves for each credit in the basket.

figure
plot(ProbDates',DefProb)
datetick
title('Individual Default Probability Curves')
ylabel('Cumulative Probability')
xlabel('Date')

Figure contains an axes object. The axes object with title Individual Default Probability Curves contains 4 objects of type line.

Determine Latent Variable Thresholds

Latent variables are used in different credit risk contexts, with different interpretations. In some contexts, a latent variable is a proxy for a change in the value of assets, and the domain of this variable is binned, with each bin corresponding to a credit rating. The bins limits, or thresholds, are determined from credit migration matrices. In our context, the latent variable is associated to a time to default, and the thresholds determine bins in a discretized time grid where defaults may occur.

Formally, if the time to default of a particular issuer is denoted by τ, and we know its default probability function P(t), a latent variable A and corresponding thresholds C(t) satisfy

Pr(τt)=P(t)=Pr(AC(t))

or

Pr(sτt)=P(t)-P(s)=Pr(C(s)AC(t))

These relationships make latent variable approaches convenient for both simulations and analytical derivations. Both P(t) and C(t) are functions of time.

The choice of a distribution for the variable A determines the thresholds C(t). In the standard latent variable model, the variable A is chosen to follow a standard normal distribution, from which

C(t)=Φ-1(P(t))

where Φ is the cumulative standard normal distribution.

Use the previous formula to determine the default-time thresholds, or simply default thresholds, corresponding to the default probabilities previously obtained for the credits in the basket.

DefThresh = norminv(DefProb);

Derive Survival Curve for the Basket

Following O'Kane [2], you can use a one-factor latent variable model to derive expressions for the survival probability function of the basket.

Given parameters βi for each issuer i, and given independent standard normal variables Z and ϵi, the one-factor latent variable model assumes that the latent variable Ai associated to issuer i satisfies

Ai=βi*Z+1-βi2*ϵi

This induces a correlation between issuers i and j of βiβj. All latent variables Ai share the common factor Z as a source of uncertainty, but each latent variable also has an idiosyncratic source of uncertainty ϵi. The larger the coefficient βi, the more the latent variable resembles the common factor Z.

Using the latent variable model, you can derive an analytic formula for the survival probability of the basket. The probability that issuer i survives past time tj, in other words, that its default time τi is greater than tj is

Pr(τi>tj)=1-Pr(AiCi(tj))

where Ci(tj) is the default threshold computed above for issuer i, for the j-th date in the discretization grid. Conditional on the value of the one-factor Z, the probability that all issuers survive past time tj is

Pr(No defaults by time tj|Z)

=Pr(τi>tj for all i|Z)

=i[1-Pr(AiCi(tj)|Z)]

where the product is justified because all the ϵi's are independent. Therefore, conditional on Z, the Ai's are independent. The unconditional probability of no defaults by time tj is the integral over all values of Z of the previous conditional probability

Pr(No defaults by time tj)

=Zi[1-Pr(AiCi(tj)|Z)]ϕ(Z)dZ

with ϕ(Z) the standard normal density.

By evaluating this one-dimensional integral for each point tj in the grid, you get a discretization of the survival curve for the whole basket, which is the FTD survival curve.

The latent variable model can also be used to simulate default times, which is the back engine of many pricing methodologies for credit instruments. Loeffler and Posch [1], for example, estimate the survival probability of a basket via simulation. In each simulated scenario a time to default is determined for each issuer. With some bookkeeping, the probability of having the first default on each bucket of the grid can be estimated from the simulation. The simulation approach is also discussed in O'Kane [2]. Simulation is very flexible and applicable to many credit instruments. However, analytic approaches are preferred, when available, because they are much faster and more accurate than simulation.

To compute the FTD survival probabilities in this example, set all betas to the square root of a target correlation. Then you can loop over all dates in the time grid to compute the one-dimensional integral that gives the survival probability of the basket.

Regarding implementation, the conditional survival probability as a function of a scalar Z would be

condProb=@(Z)prod(normcdf((-DefThresh(:,jj)+beta*Z)./sqrt(1-beta.^2)));

However, the integration function requires that the function handle of the integrand accepts vectors. Although a loop around the scalar version of the conditional probability would work, it is far more efficient to vectorize the conditional probability using bsxfun.

beta = sqrt(0.25)*ones(nIssuers,1);

FTDSurvProb = zeros(size(ProbDates));
for jj = 1:nProbDates
   % Vectorized conditional probability as a function of Z
   vecCondProb = @(Z)prod(normcdf(bsxfun(@rdivide,...
      -repmat(DefThresh(:,jj),1,length(Z))+bsxfun(@times,beta,Z),...
      sqrt(1-beta.^2))));
   % Truncate domain of normal distribution to [-5,5] interval
   FTDSurvProb(jj) = integral(@(Z)vecCondProb(Z).*normpdf(Z),-5,5);
end
FTDDefProb = 1-FTDSurvProb;

Compare the FTD probability to the default probabilities of the individual issuers.

figure
plot(ProbDates',DefProb)
datetick
hold on
plot(ProbDates,FTDDefProb,'LineWidth',3)
datetick
hold off
title('FTD and Individual Default Probability Curves')
ylabel('Cumulative Probability')
xlabel('Date')

Figure contains an axes object. The axes object with title FTD and Individual Default Probability Curves contains 5 objects of type line.

Find FTD Spreads and Price Existing FTD Swaps

Under the assumption that all instruments in the basket have the same recovery rate, or homogeneous loss assumption (see O'Kane [2]), you get the spread for the FTD swap using the cdsspread function by passing the FTD probability data just computed.

Maturity = MarketDates;
ProbDataFTD = [ProbDates, FTDDefProb];
FTDSpread = cdsspread(ZeroData,ProbDataFTD,Settle,Maturity);

Compare the FTD spreads with the individual spreads.

figure
plot(MarketDates,MarketSpreads')
datetick
hold on
plot(MarketDates,FTDSpread,'LineWidth',3)
hold off
title('FTD and Individual CDS Spreads')
ylabel('FTD Spread (bp)')
xlabel('Maturity Date')

Figure contains an axes object. The axes object with title FTD and Individual CDS Spreads contains 5 objects of type line.

An existing FTD swap can be priced with cdsprice, using the same FTD probability.

Maturity0 = MarketDates(1); % Assume maturity on nearest market date
Spread0 = 540; % Spread of existing FTD contract
% Assume default values of recovery and notional
FTDPrice = cdsprice(ZeroData,ProbDataFTD,Settle,Maturity0,Spread0);
fprintf('Price of existing FTD contract: %g\n',FTDPrice)
Price of existing FTD contract: 17644.7

Analyze Sensitivity to Correlation

To illustrate the sensitivity of the FTD spreads to model parameters, calculate the market spreads for a range of correlation values.

corr = [0 0.01 0.10 0.25 0.5 0.75 0.90 0.99 1];
FTDSpreadByCorr = zeros(length(Maturity),length(corr));
FTDSpreadByCorr(:,1) = sum(MarketSpreads)';
FTDSpreadByCorr(:,end) = max(MarketSpreads)';

for ii = 2:length(corr)-1
   beta = sqrt(corr(ii))*ones(nIssuers,1);
   FTDSurvProb = zeros(length(ProbDates));
   for jj = 1:nProbDates
      % Vectorized conditional probability as a function of Z
      condProb = @(Z)prod(normcdf(bsxfun(@rdivide,...
         -repmat(DefThresh(:,jj),1,length(Z))+bsxfun(@times,beta,Z),...
         sqrt(1-beta.^2))));
      % Truncate domain of normal distribution to [-5,5] interval
      FTDSurvProb(jj) = integral(@(Z)condProb(Z).*normpdf(Z),-5,5);
   end
   FTDSurvProb = FTDSurvProb(:,1);
   FTDDefProb = 1-FTDSurvProb;
   ProbDataFTD = [ProbDates, FTDDefProb];
   FTDSpreadByCorr(:,ii) = cdsspread(ZeroData,ProbDataFTD,Settle,Maturity);
end

The FTD spreads lie in a band between the sum and the maximum of individual spreads. As the correlation increases to one, the FTD spreads decrease towards the maximum of the individual spreads in the basket (all credits default together). As the correlation decreases to zero, the FTD spreads approach the sum of the individual spreads (independent credits).

figure
legends = cell(1,length(corr));
plot(MarketDates,FTDSpreadByCorr(:,1),'k:')
legends{1} = 'Sum of Spreads';
datetick
hold on
for ii = 2:length(corr)-1
   plot(MarketDates,FTDSpreadByCorr(:,ii),'LineWidth',3*corr(ii))
   legends{ii} = ['Corr ' num2str(corr(ii)*100) '%'];
end
plot(MarketDates,FTDSpreadByCorr(:,end),'k-.')
legends{end} = 'Max of Spreads';

hold off
title('FTD Spreads for Different Correlations')
ylabel('FTD Spread (bp)')
xlabel('Maturity Date')
legend(legends,'Location','NW')

Figure contains an axes object. The axes object with title FTD Spreads for Different Correlations contains 9 objects of type line. These objects represent Sum of Spreads, Corr 1%, Corr 10%, Corr 25%, Corr 50%, Corr 75%, Corr 90%, Corr 99%, Max of Spreads.

For short maturities and small correlations, the basket is effectively independent (the FTD spread is very close to the sum of individual spreads). The correlation effect becomes more significant for longer maturities.

Here is an alternative visualization of the dependency of FTD spreads on correlation.

figure
surf(corr,MarketDates,FTDSpreadByCorr)
datetick('y')
ax = gca;
ax.YDir = 'reverse';
view(-40,10)
title('FTD Spreads for Different Correlations and Maturities')
xlabel('Correlation')
ylabel('Maturity Date')
zlabel('FTD Spread (bp)')

Figure contains an axes object. The axes object with title FTD Spreads for Different Correlations and Maturities contains an object of type surface.

References

[1] Loeffler, Gunter and Peter Posch. Credit risk modeling using Excel and VBA. Wiley Finance, 2007.

[2] O'Kane, Dominic. Modelling single-name and multi-name Credit Derivatives. Wiley Finance, 2008.

See Also

| | |

Related Examples

More About

External Websites