CDS Calibration Errors Can Reveal Arbitrage-Inconsistent Inputs
Summary
The document explains a QuantLib credit default swap calibration failure that occurs with a higher assumed recovery rate for the supplied market spreads. The calibration seeks risk neutral survival probabilities by solving for curve parameters. If the inputs cannot produce a no arbitrage set of probabilities, the root finder may fail because there is no valid solution within its search interval.
The answer interprets the error as a possible arbitrage inconsistency: at a given set of quoted spreads, increasing assumed recovery can make protection prices inconsistent with risk free trading. A lower recovery assumption in the example calibrates successfully, while the higher one does not. This is a diagnosis of the example rather than a universal recovery threshold. The exchange does not compare QuantLib’s conventions with Bloomberg’s settings, and different assumptions or contract details could affect the discrepancy.
Key ideas
- CDS curve calibration uses quoted spreads and recovery assumptions to infer risk neutral survival probabilities.
- A failed root search can indicate that the supplied inputs do not admit a valid calibrated curve.
- Increasing assumed recovery can make a given set of CDS quotes inconsistent with no arbitrage conditions.
- Differences in model assumptions or contract details may contribute to discrepancies across valuation systems.
Tags
Full text
# Quantlib CDS model
# Quantlib CDS model
I have started working on CDS model using Quantlib and as a starting point, utilized code provided in GitHub Quantlib/Python examples with modifications in initial code as given at the end and have following query:
When using Recovery Rate as 0.60, getting error as "RuntimeError: 1st iteration: failed at 3rd alive instrument, pillar June 21st, 2021, maturity June 21st, 2021, reference date March 22nd, 2019: root not bracketed: f[2.22045e-16,1] -> [1.320123e-01,1.328986e-02]" but haven't observed any error when valuing on BBG calculator. Also Recovery Rate of 0.4 provides perfectly fine value. Why this discrepancy with BBG?
```
todaysDate = Date(22,March,2019);
todaysDate = calendar.adjust(todaysDate)
Settings.instance().evaluationDate = todaysDate
risk_free_rate = YieldTermStructureHandle(
FlatForward(todaysDate, 0.01,
Actual365Fixed()
)
)
recovery_rate = 0.60
quoted_spreads = [ 0.1214, 0.1769, 0.2471, 0.2816]
tenors = [ Period(6, Months), Period(1, Years),
Period(2, Years),Period(3, Years)]
```
## Answer by Dimitri Vulis (score 2)
https://quant.stackexchange.com/a/44973
As you increase the recovery assumption, it becomes possible for the same CDS quotes to admit risk-free arbitrage (where you can buy some protection, sell some protection, and never lose money, and likely make money). The library calls a root finder to look for risk-neutral no-arbitrage probabilities of survival; but the root finder says it is not possible for these inputs, i.e. that your inputs admit arbitrage. It would be friendlier if the error message explained this. It would be even friendlier if the library "suggested" nearest inputs that don't admit arbitrage. (It also would be better if the recovery assumption had term structure.:)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.