Skip to content

Latest commit

 

History

History
154 lines (147 loc) · 5.62 KB

File metadata and controls

154 lines (147 loc) · 5.62 KB

Quickstart Guide to Credit Derivatives

We wish to set up and value a CDS contract.

To do this we need the Date and other utility classes such as Frequency and DayCounts. The easiest way to do this is to use a wildcard import.

from financepy.utils import *

As we will need interest rates to build the CDS curve we load in the rates modules

from financepy.products.rates import *

And of course we need the credit modules

from financepy.products.credit import *

In each case we load everything. As we become more expert in the library we can learn to just import exactly what we need.

We now define our CDS contract. It was traded first on 1st Dec 2024. We value it today 10th Jan 2026, and it matures on the 20th March 2029. The contractual coupon is set at 100 basis points. And we are long protection with a notional of $1,000,000. We therefore define

effective_dt = Date(1, 12, 2024)
maturity_dt = Date(20, 3, 2028)
cds_coupon = 0.010
notional = ONE_MILLION
long_protection = True

We can then define the CDS contract as follows

cds_contract = CDS(value_dt, maturity_dt, cds_coupon, notional, long_protection)

We can print the contract to ensure that it is as we wish

***Output***
OBJECT TYPE: CDS
STEP-IN DATE: 01-DEC-2024
MATURITY: 20-MAR-2028
NOTIONAL: 1000000
LONG PROTECTION: True
RUN COUPON: 100.0bp
DAYCOUNT: DayCountTypes.ACT_360
FREQUENCY: FrequencyTypes.QUARTERLY
CALENDAR: CalendarTypes.WEEKEND
BUSDAYRULE: BusDayAdjustTypes.FOLLOWING
DATEGENRULE: DateGenRuleTypes.BACKWARD
PAYMENT_dt, YEAR_FRAC, ACCRUAL_START, ACCRUAL_END, FLOW
20-DEC-2024,     0.252778, 20-SEP-2024, 19-DEC-2024,  2527.777778
20-MAR-2025,     0.250000, 20-DEC-2024, 19-MAR-2025,  2500.000000
20-JUN-2025,     0.255556, 20-MAR-2025, 19-JUN-2025,  2555.555556
22-SEP-2025,     0.261111, 20-JUN-2025, 21-SEP-2025,  2611.111111
22-DEC-2025,     0.252778, 22-SEP-2025, 21-DEC-2025,  2527.777778
20-MAR-2026,     0.244444, 22-DEC-2025, 19-MAR-2026,  2444.444444
22-JUN-2026,     0.261111, 20-MAR-2026, 21-JUN-2026,  2611.111111
21-SEP-2026,     0.252778, 22-JUN-2026, 20-SEP-2026,  2527.777778
21-DEC-2026,     0.252778, 21-SEP-2026, 20-DEC-2026,  2527.777778
22-MAR-2027,     0.252778, 21-DEC-2026, 21-MAR-2027,  2527.777778
21-JUN-2027,     0.252778, 22-MAR-2027, 20-JUN-2027,  2527.777778
20-SEP-2027,     0.252778, 21-JUN-2027, 19-SEP-2027,  2527.777778
20-DEC-2027,     0.252778, 20-SEP-2027, 19-DEC-2027,  2527.777778
20-MAR-2028,     0.255556, 20-DEC-2027, 20-MAR-2028,  2555.555556

We see the details of the contract that would be found on its term sheet. The premium leg starts paying in December 2024.

To value this CDS, we first need to load the rates curve. This is usually based on IBOR instruments, specifically Deposits, Futures and Swaps. However to keep things simple for the quick start, we will assume a flat discount curve. We therefore define

interest_rate = 0.03

We also pull in the required curve type

from financepy.market.curves import DiscountCurveFlat

We then construct this flat curve

discount_curve = DiscountCurveFlat(value_dt, interest_rate, FrequencyTypes.CONTINUOUS)

Next we need to construct the CDS curve. For this we need to specify a term structure of CDS contracts with their corresponding par CDS spread. We do not need to use CDS maturity dates - we can simply specify their tenor i.e. how many years they each last. We first create the settlement date which is value date plus one

settle_dt = value_dt.add_days(1)

and then we specify the 1Y, 2Y, 3Y and 5Y CDS contracts with CDS par spreads of 80, 85, 90, 95 bps

cds1 = CDS(settle_dt, "1Y", 0.0065)
cds2 = CDS(settle_dt, "2Y", 0.0070)
cds3 = CDS(settle_dt, "3Y", 0.0075)
cds5 = CDS(settle_dt, "5Y", 0.0080)

We store these in a list

cdss = [cds1, cds2, cds3, cds5]

We also need to specify a recovery rate (market standard is to assume 40%)

recovery_rate = 0.40

and we create our CDS curve

cds_curve = CDSCurve(value_dt, cds_list, discount_curve, recovery_rate)

We can print this to see what is stored

print(cds_curve)

Output:

OBJECT TYPE: CDSCurve
TIME,SURVIVAL_PROBABILITY
 0.0000000,  1.0000000
 1.2136986,  0.9865973
 2.2164384,  0.9739514
 3.2164384,  0.9597968
 5.2164384,  0.9314422

We see the term structure of years and risk-neutral survival probabilities.

We can now value the CDS contract. First we calculate the par CDS spread for this maturity. Recall that our CDS contract protection costs us 100bp a year.

spd = cds_contract.par_spread(value_dt, cds_curve, recovery_rate) * 10000.0
print("FAIR CDS SPREAD %10.5f bp"% spd)

Which gives

FAIR CDS SPREAD   69.999 bp

This makes sense. It agrees with the current market par spread of 70bps for a 2Y contract. Note that a 2Y contract matures in 2 years on the next IMM date which is the 20 March 2028.

The value of the contract is given by the difference between the par spread of 70bps and the 100bps that we are paying for the 2.25 years of protection remaining. It should be negative and equal to 30bps times 2.25 years. Let us see.

v = cds_contract.value(settle_dt, cds_curve, recovery_rate)

This has two components:

dirty_pv = v['dirty_pv']
clean_pv = v['clean_pv']

We print these

print("DIRTY VALUE %12.2f"% dirty_pv)
print("CLEAN VALUE %12.2f"% clean_pv)

which gives

DIRTY VALUE      -6752.97
CLEAN VALUE      -6475.19

We see that the dirty price (that the contract is worth) is approximately equal to -30bps x 2.25 x $1m = -$6,750.

We can get this as a clean price

cleanp = cds_contract.clean_price(settle_dt, cds_curve, recovery_rate)
print("CLEAN PRICE %12.6f"% cleanp)

which gives

CLEAN PRICE   100.646919