QuantLib CDS Calibration Failures on Roll Dates
Summary
The question describes a QuantLib credit-default-swap curve calibration that fails on CDS roll dates. The author builds a piecewise hazard-rate curve from CDS helpers and reports matching market values on some dates, but receives a root-not-bracketed error for the first live instrument on specified roll dates. The failure occurs with the ISDA pricing model and zero settlement days; using a midpoint pricer avoids the error, but the author says it does not match the newer standard calculation.
The post also notes that changing settlement days alters the resulting tenor dates. It provides code and instrument inputs to make the setup reproducible, but no answer or fix is included. Thus, it is a useful troubleshooting case about interactions among CDS schedule conventions, settlement timing, roll dates, and the ISDA model, rather than a validated calibration recipe. The described behavior is specific to the setup and dates given; the document does not establish a general cause.
Key ideas
- The reported CDS hazard-curve calibration fails at the first live pillar on certain roll dates.
- In the described setup, the failure occurs with the ISDA pricing model and zero settlement days.
- Using a midpoint pricer avoids the reported error but may not reproduce the desired standard calculation.
- Changing settlement days affects the tenor dates used to build the curve.
- The document provides a reproducible case but no diagnosis or confirmed resolution.
Tags
Full text
# Why Quantlib CreditDefaultSwap::ISDA fail on roll dates: 1st iteration: failed at 1st alive instrument, pillar
# Why Quantlib CreditDefaultSwap::ISDA fail on roll dates: 1st iteration: failed at 1st alive instrument, pillar
I am experimenting with Quantlib CDS engine, I create a piecwise hzard rate based on CDSHelpers and try to compute default probability with it and then some specific upfront.
I managed to match BBG values on the few dates I tested, but when i tried the roll dates ie 19 March 2019 or 19 September 2019 I got the error below 1st iteration: failed at 1st alive instrument, pillar June 21st, 2019, maturity June 21st, 2019, reference date March 19th, 2019: root not bracketed: f[2.22045e-16,1] -> [1.202135e-02,6.639330e+00]
This error happen only when I use CreditDefaultSwap::ISDA as a model while creating the cdshelpers, it doesn't occur if I use midPoint pricer. But as it was mentioned in http://quantlib.10058.n7.nabble.com/Fail-to-replicate-ISDA-Fair-Value-CDS-Model-td18310.html The midPoint pricer is unable to match the new standard calculation.
Also I probably should mention that this error happen only when I assume a 0 settelment days, but if I assume 1 day the curve I end up creating use June's tenors (for a trade date of 19 march) instead of December's.
code:
```
Date todaysDate(19, March, 2019);
Settings::instance().evaluationDate() = todaysDate;
.
./ create isdaRateHelper
.
Handle<YieldTermStructure> rateTs(
ext::make_shared<PiecewiseYieldCurve<Discount, LogLinear> >(
0, WeekendsOnly(), isdaRateHelper, Actual365Fixed()));
CreditDefaultSwap::PricingModel model = CreditDefaultSwap::ISDA;
std::vector<ext::shared_ptr<DefaultProbabilityHelper> > isdaCdsHelpers;
std::vector<float> quotes={0.01202135, 0.01237659, 0.01290271, 0.01331895,
0.01375619, 0.01420986, 0.01425261, 0.01419832};
std::vector<Period> periods{6 * Months,1 * Years,2 * Years,3 * Years,4 *
Years,5 * Years,7 * Years,10 * Years};
for(unsigned int i=0;i<quotes.size();i++){
ext::shared_ptr<CdsHelper> cds(new SpreadCdsHelper(
quotes[i], periods[i], 0, WeekendsOnly(), Quarterly, Unadjusted,
DateGeneration::CDS2015, Actual360(), 0.4, rateTs, true, true, todaysDate,Actual360(true), true,model));
isdaCdsHelpers.push_back(cds);
}
ext::shared_ptr<PiecewiseDefaultCurve<HazardRate, BackwardFlat> > hazardRateStructure(new PiecewiseDefaultCurve<HazardRate, BackwardFlat>(todaysDate,isdaCdsHelpers, Actual365Fixed()));
Handle<DefaultProbabilityTermStructure> isdaCts = Handle<DefaultProbabilityTermStructure>(hazardRateStructure);
//check
for(unsigned int i=0;i< hazardRateStructure->dates().size();i++)
cout<<hazardRateStructure->dates()[i]<<endl;
std::cout << "default probability = " << isdaCts->DefaultProbability(Date(20,June,2019)) << std::endl;
std::cout << "default probability = " << isdaCts-defaultProbability(Date(20,June,2019)) << std::endl;
```
```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.