Reconciling CDS Upfront Pricing Between Two Models
Summary
The document presents a pricing reconciliation problem: a user compares a clean euro upfront amount from a market converter with a value produced by QuantLib’s ISDA CDS engine. The reported values differ slightly. The accompanying Python example builds a euro interest-rate curve from deposit and swap quotes, infers a flat hazard rate from a quoted credit default swap, then prices a conventional coupon CDS to obtain its fair upfront amount.
No answer identifies the source of the discrepancy or confirms which setup matches the converter. The example is therefore useful as a record of the inputs and modeling steps involved in a CDS pricing comparison, but it does not establish a reconciliation method or resolve the difference. Potential sources would need to be checked against the conventions and market inputs used by both systems, including dates, schedules, day counts, curve construction, and upfront treatment. The document provides a specific setup, not independent validation of either price.
Key ideas
- The question compares a market converter’s clean CDS upfront amount with a QuantLib ISDA engine result.
- The example constructs a discount curve from deposit and swap quotes and infers a hazard rate from a quoted CDS spread.
- A conventional coupon CDS is then priced to calculate a fair upfront amount.
- The document reports a discrepancy but supplies no explanation or verified fix.
Tags
Full text
# Match CDS upfront amount between Quantlib and Markit Converter model
# Match CDS upfront amount between Quantlib and Markit Converter model
I'm trying to reconciliate the upfront amount between the Markit converter model (https://cds.ihsmarkit.com/converter.jsp) and the result from the quantlib IsdaCdsEngine function.
the difference is very tight, however after some research on the web and trying to modify the code, I still can't match the amount. as you can see in the below print, the clean upfront amount is 344,110 - 25,000 = 319,110 EUR
with quantlib, I'm calculating 319,287 EUR, see the python code below
Just wonder if someone has encountered the same issue and can help me on that.
thanks in advance and Merry Christmas
```
import QuantLib as ql
import pandas as pd
interactive = 'get_ipython' in globals()
trade_date = ql.Date(18,12,2023)
ql.Settings.instance().setEvaluationDate(trade_date)
ql.IborCoupon.createAtParCoupons()
dep_tenors = [1,3,6]
dep_quotes = [0.039009,0.038972,0.037575]
isdaRateHelpers = [ql.DepositRateHelper(dep_quotes[i],
dep_tenors[i]*ql.Period(ql.Monthly),
2,ql.WeekendsOnly(),
ql.ModifiedFollowing,
False,ql.Actual360())
for i in range(len(dep_tenors))]
swap_tenors = [1, 2, 3, 4, 5, 6]
swap_quotes = [0.033231,
0.026972,
0.024380,
0.023181,
0.022662,
0.022522]
isda_ibor = ql.IborIndex('IsdaIbor',3*ql.Period(ql.Monthly),2,
ql.EURCurrency(),ql.WeekendsOnly(),
ql.ModifiedFollowing,False,ql.Actual360())
isdaRateHelpers = isdaRateHelpers + [
ql.SwapRateHelper(swap_quotes[i],swap_tenors[i]*ql.Period(ql.Annual),
ql.WeekendsOnly(),ql.Semiannual,ql.ModifiedFollowing,
ql.Thirty360(ql.Thirty360.BondBasis),isda_ibor)
for i in range(len(swap_tenors))]
spot_date = ql.WeekendsOnly().advance(trade_date, 2 * ql.Period(ql.Daily))
swap_curve = ql.PiecewiseFlatForward(trade_date, isdaRateHelpers, ql.Actual365Fixed())
discountCurve = ql.YieldTermStructureHandle(swap_curve)
probabilityCurve = ql.RelinkableDefaultProbabilityTermStructureHandle()
termDate = ql.Date(20, 12, 2028)
spread = 0.003212
recovery = 0.4
upfront_date = ql.WeekendsOnly().advance(trade_date, 3 * ql.Period(ql.Daily))
cdsSchedule = ql.Schedule(trade_date, termDate,
3*ql.Period(ql.Monthly),
ql.WeekendsOnly(),
ql.Following, ql.Unadjusted,
ql.DateGeneration.CDS, False)
quotedTrade = ql.CreditDefaultSwap(
ql.Protection.Buyer,10000000,0,spread,cdsSchedule,
ql.Following,ql.Actual360(),True,True,trade_date,
upfront_date, ql.FaceValueClaim(), ql.Actual360(True))
h = quotedTrade.impliedHazardRate(0,discountCurve,ql.Actual365Fixed(),
recovery,1e-10,
ql.CreditDefaultSwap.ISDA)
probabilityCurve.linkTo(ql.FlatHazardRate(0,ql.WeekendsOnly(),
ql.QuoteHandle(ql.SimpleQuote(h)),
ql.Actual365Fixed()))
engine = ql.IsdaCdsEngine(probabilityCurve,recovery,discountCurve)
conventionalTrade = ql.CreditDefaultSwap(ql.Protection.Buyer,10000000,0,0.01,cdsSchedule,
ql.Following,ql.Actual360(),True,True,trade_date,
upfront_date, ql.FaceValueClaim(), ql.Actual360(True))
conventionalTrade.setPricingEngine(engine)
upfront = -conventionalTrade.notional() * conventionalTrade.fairUpfront()
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.