| Contents | Index |
A credit default swap (CDS) is a contract that protects against losses resulting from credit defaults. The transaction involves two parties, the protection buyer and the protection seller, and also a reference entity, usually a bond. The protection buyer pays a stream of premiums to the protection seller, who in exchange offers to compensate the buyer for the loss in the bond's value if a credit event occurs. The stream of premiums is called the premium leg, and the compensation when a credit event occurs is called the protection leg. Credit events usually include situations in which the bond issuer goes bankrupt, misses coupon payments, or enters a restructuring process. Fixed-Income Toolbox software supports:
CDS Functions
Function | Purpose |
|---|---|
Compute default probability parameters from CDS market quotes. | |
Compute breakeven spreads for the CDS contracts. | |
Compute the price for the CDS contracts. |
In a typical workflow, pricing a new CDS contract involves first estimating a default probability term structure using cdsbootstrap. This requires market quotes of existing CDS contracts, or quotes of CDS indices (e.g., iTraxx). The estimated default probability curve is then used as input to cdsspread or cdsprice. If the default probability information is already known, cdsbootstrap can be bypassed and cdsspread or cdsprice can be called directly.
The market information in this example is provided in the form of running spreads of CDS contracts maturing on the CDS standard payment dates closest to 1, 2, 3, 5, and 7 years from the valuation date.
Settle = '17-Jul-2009';
MarketDates = datenum({'20-Sep-10','20-Sep-11','20-Sep-12','20-Sep-14',...
'20-Sep-16'});
MarketSpreads = [140 175 210 265 310]';
MarketData = [MarketDates MarketSpreads];
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];
[ProbData,HazData] = cdsbootstrap(ZeroData,MarketData,Settle);The bootstrapped default probability curve is plotted against time, in years, from the valuation date.
ProbTimes = yearfrac(Settle,ProbData(:,1));
figure
plot([0; ProbTimes],[0; ProbData(:,2)])
grid on
axis([0 ProbTimes(end,1) 0 ProbData(end,2)])
xlabel('Time (years)')
ylabel('Cumulative Default Probability')
title('Bootstrapped Default Probability Curve')

The associated hazard rates are returned as an optional output. The convention is that the first hazard rate applies from the settlement date to the first market date, the second hazard rate from the first to the second market date, etc., and the last hazard rate applies from the second-to-last market date onwards. The following plot displays the bootstrapped hazard rates, plotted against time, in years, from the valuation date:
HazTimes = yearfrac(Settle,HazData(:,1));
figure
stairs([0; HazTimes(1:end-1,1); HazTimes(end,1)+1],...
[HazData(:,2);HazData(end,2)])
grid on
axis([0 HazTimes(end,1)+1 0.9*HazData(1,2) 1.1*HazData(end,2)])
xlabel('Time (years)')
ylabel('Hazard Rate')
title('Bootstrapped Hazard Rates')

The breakeven, or running, spread is the premium a protection buyer must pay, with no upfront payments involved, to receive protection for credit events associated to a given reference entity. Spreads are expressed in basis points (bp). There is a notional amount associated to the CDS contract to determine the monetary amounts of the premium payments.
New quotes for CDS contracts can be obtained with cdsspread. After obtaining a default probability curve using cdsbootstrap, you get quotes that are consistent with current market conditions.
In this example, instead of standard CDS payment dates, define new maturity dates. Using the period from 3 and 5 years (CDS standard dates), maturities are defined within this range spaced at quarterly intervals (measuring time from the valuation date):
Settle = '17-Jul-2009';
MarketDates = datenum({'20-Sep-10','20-Sep-11','20-Sep-12','20-Sep-14',...
'20-Sep-16'});
MarketSpreads = [140 175 210 265 310]';
MarketData = [MarketDates MarketSpreads];
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];
[ProbData,HazData] = cdsbootstrap(ZeroData,MarketData,Settle);
Maturity1 = datestr(daysadd('17-Jul-09',360*(3.25:0.25:5),1));
Spread1 = cdsspread(ZeroData,ProbData,Settle,Maturity1);
figure
scatter(yearfrac(Settle,Maturity1),Spread1,'*')
hold on
scatter(yearfrac(Settle,MarketData(3:4,1)),MarketData(3:4,2))
hold off
grid on
xlabel('Time (years)')
ylabel('Spread (bp)')
title('CDS Spreads')
legend('New Quotes','Market','location','SouthEast')This plot displays the resulting spreads:

To evaluate the effect of the recovery rate parameter, instead of 40% (default value), use a recovery rate of 35%:
Spread1Rec35 = cdsspread(ZeroData,ProbData,Settle,Maturity1,...
'RecoveryRate',0.35);
figure
plot(yearfrac(Settle,Maturity1),Spread1,...
yearfrac(Settle,Maturity1),Spread1Rec35,'--')
grid on
xlabel('Time (years)')
ylabel('Spread (bp)')
title('CDS Spreads with Different Recovery Rates')
legend('40%','35%','location','SouthEast')The resulting plot shows that smaller recovery rates produce higher premia, as expected, since in the event of default, the protection payments will be higher:

The current value, or mark-to-market, of an existing CDS contract is the amount of money the contract holder would receive (if positive) or pay (if negative) to unwind this contract. The upfront of the contract is the current value expressed as a fraction of the notional amount of the contract, and it is commonly used to quote market values.
The value of existing CDS contracts is obtained with cdsprice. By default, cdsprice treats contracts as long positions. Whether a contract position is long or short is determined from a protection standpoint, that is, long means protection was bought, and short means protection was sold. In the following example, an existing CDS contract pays a premium that is lower than current market conditions. The price is positive, as expected, since it would be more costly to buy the same type of protection today.
Settle = '17-Jul-2009';
MarketDates = datenum({'20-Sep-10','20-Sep-11','20-Sep-12','20-Sep-14',...
'20-Sep-16'});
MarketSpreads = [140 175 210 265 310]';
MarketData = [MarketDates MarketSpreads];
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];
[ProbData,HazData] = cdsbootstrap(ZeroData,MarketData,Settle);
Maturity2 = '20-Sep-2012';
Spread2 = 196;
[Price,AccPrem,PaymentDates,PaymentTimes,PaymentCF] = cdsprice(ZeroData,...
ProbData,Settle,Maturity2,Spread2);
fprintf('Dirty Price: %8.2f\n',Price);
fprintf('Accrued Premium: %8.2f\n',AccPrem);
fprintf('Clean Price: %8.2f\n',Price-AccPrem);
fprintf('\nPayment Schedule:\n\n');
fprintf('Date \t\t Time Frac \t Amount\n');
for k = 1:length(PaymentDates)
fprintf('%s \t %5.4f \t %8.2f\n',datestr(PaymentDates(k)),...
PaymentTimes(k),PaymentCF(k));
endThis resulting payment schedule is:
Dirty Price: 41630.75 Accrued Premium: 15244.44 Clean Price: 26386.30 Payment Schedule: Date Time Frac Amount 20-Sep-2009 0.1806 35388.89 20-Dec-2009 0.2528 49544.44 20-Mar-2010 0.2500 49000.00 20-Jun-2010 0.2556 50088.89 20-Sep-2010 0.2556 50088.89 20-Dec-2010 0.2528 49544.44 20-Mar-2011 0.2500 49000.00 20-Jun-2011 0.2556 50088.89 20-Sep-2011 0.2556 50088.89 20-Dec-2011 0.2528 49544.44 20-Mar-2012 0.2528 49544.44 20-Jun-2012 0.2556 50088.89 20-Sep-2012 0.2556 50088.89
Additionally, you can use cdsprice to value a portfolio of CDS contracts. In the following example, a simple hedged position with two vanilla CDS contracts, one long, one short, with slightly different spreads is priced in a single call and the value of the portfolio is the sum of the returned prices:
[Price2,AccPrem2] = cdsprice(ZeroData,ProbData,Settle,...
repmat(datenum(Maturity2),2,1),[Spread2;Spread2+3],...
'Notional',[1e7; -1e7]);
fprintf('Contract \t Dirty Price \t Acc Premium \t Clean Price\n');
fprintf(' Long \t $ %9.2f \t $ %9.2f \t $ %9.2f \t\n',...
Price2(1), AccPrem2(1), Price2(1) - AccPrem2(1));
fprintf(' Short \t $ %8.2f \t $ %8.2f \t $ %8.2f \t\n',...
Price2(2), AccPrem2(2), Price2(2) - AccPrem2(2));
fprintf('Mark-to-market of hedged position: $ %8.2f\n',sum(Price2));This resulting value of the portfolio is:
Contract Dirty Price Acc Premium Clean Price
Long $ 41630.75 $ 15244.44 $ 26386.30
Short $ -32709.87 $ -15477.78 $ -17232.10
Mark-to-market of hedged position: $ 8920.87A CDS market quote is given in terms of a standard spread (usually 100 bp or 500 bp) and an upfront payment, or in terms of an equivalent running or breakeven spread, with no upfront payment. The functions cdsbootstrap, cdsspread, and cdsprice perform upfront to running or running to upfront conversions.
For example, to convert the market quotes to upfront quotes for a standard spread of 100 bp:
Settle = '17-Jul-2009';
MarketDates = datenum({'20-Sep-10','20-Sep-11','20-Sep-12','20-Sep-14',...
'20-Sep-16'});
MarketSpreads = [140 175 210 265 310]';
MarketData = [MarketDates MarketSpreads];
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];
[ProbData,HazData] = cdsbootstrap(ZeroData,MarketData,Settle);
Maturity3 = MarketData(:,1);
Spread3Run = MarketData(:,2);
Spread3Std = 100*ones(size(Maturity3));
Price3 = cdsprice(ZeroData,ProbData,Settle,Maturity3,Spread3Std);
Upfront3 = Price3/10000000; % Standard notional of 10MM
display(Upfront3);This resulting value is:
Upfront3 =
0.0047
0.0158
0.0327
0.0737
0.1182
The conversion can be reversed to convert upfront quotes to market quotes:
ProbData3Upf = cdsbootstrap(ZeroData,[Maturity3 Upfront3 Spread3Std],Settle); Spread3RunFromUpf = cdsspread(ZeroData,ProbData3Upf,Settle,Maturity3); display([Spread3Run Spread3RunFromUpf]);
Comparing the results of this conversion to the original market spread demonstrates the reversal:
ans = 140.0000 140.0000 175.0000 175.0000 210.0000 210.0000 265.0000 265.0000 310.0000 310.0000
Under the flat-hazard rate (FHR) quoting convention, a single market quote is used to calibrate a probability curve. This convention yields a single point in the probability curve, and a single hazard rate value. For example, assume a 4-year (standard dates) CDS contract with a current FHR-based running spread of 550 bp needs conversion to a CDS contract with a standard spread of 500 bp:
Maturity4 = datenum('20-Sep-13');
Spread4Run = 550;
ProbData4Run = cdsbootstrap(ZeroData,[Maturity4 Spread4Run],Settle);
Spread4Std = 500;
Price4 = cdsprice(ZeroData,ProbData4Run,Settle,Maturity4,Spread4Std);
Upfront4 = Price4/10000000;
fprintf('A running spread of %5.2f is equivalent to\n',Spread4Run);
fprintf(' a standard spread of %5.2f with an upfront of %8.7f\n',...
Spread4Std,Upfront4);
A running spread of 550.00 is equivalent to
a standard spread of 500.00 with an upfront of 0.0167583To reverse the conversion:
ProbData4Upf = cdsbootstrap(ZeroData,[Maturity4 Upfront4 Spread4Std],Settle);
Spread4RunFromUpf = cdsspread(ZeroData,ProbData4Upf,Settle,Maturity4);
fprintf('A standard spread of %5.2f with an upfront of %8.7f\n',...
Spread4Std,Upfront4);
fprintf(' is equivalent to a running spread of %5.2f\n',Spread4RunFromUpf);
A standard spread of 500.00 with an upfront of 0.0167583
is equivalent to a running spread of 550.00As discussed in Beumee et. al., 2009 (see Credit Derivatives), the FHR approach is a quoting convention only, and leads to quotes inconsistent with market data. For example, calculating the upfront for the 3-year (standard dates) CDS contract with a standard spread of 100 bp using the FHR approach and comparing the results to the upfront amounts previously calculated, demonstrates that the FHR-based approach yields a different upfront amount:
Maturity5 = MarketData(3,1);
Spread5Run = MarketData(3,2);
ProbData5Run = cdsbootstrap(ZeroData,[Maturity5 Spread5Run],Settle);
Spread5Std = 100;
Price5 = cdsprice(ZeroData,ProbData5Run,Settle,Maturity5,Spread5Std);
Upfront5 = Price5/10000000;
fprintf('Relative error of FHR-based upfront amount: %3.1f%%\n',...
((Upfront5-Upfront3(3))/Upfront3(3))*100);
Relative error of FHR-based upfront amount: -0.8%The following two examples demonstrate the behavior of bootstrapping with inverted CDS market curves, that is, market quotes with higher spreads for short-term CDS contracts. The first example is handled normally by cdsbootstrap:
Settle = '17-Jul-2009';
MarketDates = datenum({'20-Sep-10','20-Sep-11','20-Sep-12','20-Sep-14',...
'20-Sep-16'});
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];
MarketSpreadsInv1 = [750 650 550 500 450]';
MarketDataInv1 = [MarketDates MarketSpreadsInv1];
[ProbDataInv1,HazDataInv1] = cdsbootstrap(ZeroData,MarketDataInv1,Settle);In the second example, cdsbootstrap generates a warning:
MarketSpreadsInv2 = [800 550 400 250 100]'; MarketDataInv2 = [MarketDates MarketSpreadsInv2]; [ProbDataInv2,HazDataInv2] = cdsbootstrap(ZeroData,MarketDataInv2,Settle); Warning: Found non-monotone default probabilities (negative hazard rates)
A non-monotone bootstrapped probability curve implies negative default probabilities and negative hazard rates for certain time intervals. Extreme market conditions can lead to these types of situations. In these cases, you must assess the reliability and usefulness of the bootstrapped results.
The following plot illustrates these bootstrapped probability curves. The curves are concave, meaning that the marginal default probability decreases with time. This result is consistent with the market information that indicates a higher default risk in the short term. The second bootstrapped curve is non-monotone, as indicated by the warning.
ProbTimes = yearfrac(Settle, MarketDates);
figure
plot([0; ProbTimes],[0; ProbDataInv1(:,2)])
hold on
plot([0; ProbTimes],[0; ProbDataInv2(:,2)],'--')
hold off
grid on
axis([0 ProbTimes(end,1) 0 ProbDataInv1(end,2)])
xlabel('Time (years)')
ylabel('Cumulative Default Probability')
title('Probability Curves for Inverted Spread Curves')
legend('1st instance','2nd instance','location','SouthEast')The resulting plot

Also in line with the previous plot, the hazard rates for these bootstrapped curves are decreasing because the short-term risk is higher. Some bootstrapped parameters in the second curve are negative, as indicated by the warning.
HazTimes = yearfrac(Settle, MarketDates);
figure
stairs([0; HazTimes(1:end-1,1); HazTimes(end,1)+1],...
[HazDataInv1(:,2);HazDataInv1(end,2)])
hold on
stairs([0; HazTimes(1:end-1,1); HazTimes(end,1)+1],...
[HazDataInv2(:,2);HazDataInv2(end,2)],'--')
hold off
grid on
xlabel('Time (years)')
ylabel('Hazard Rate')
title('Hazard Rates for Inverted Spread Curves')
legend('1st instance','2nd instance','location','NorthEast')The resulting plot shows the hazard rates for both bootstrapped curves:

For further discussion on inverted curves, and their relationship to arbitrage, see O'Kane and Turnbull, 2003 (Credit Derivatives).
![]() | Credit Derivatives | Credit Default Swap Option | ![]() |
View demos and recorded presentations led by industry experts.
Now On Demand
Network with industry peers and learn the latest applications of the leading software product for computational finance.
| © 1984-2012- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |