# Quantlib-SWIG Python: impliedHazardRate requires “warm” discountcurve

I am getting different results from the CreditDefaultSwap().impliedHazardRate() method, depending on whether the discount curve passed is "cold" i.e. just created and never used or "warm" i.e used at least once.

Using the standard ISDA engine example as a starting point: isda-engine.py

For simplicity, I picked

termDate = ql.Date(20, 6, 2019)
recovery = 0.4


and added a for _ in range(4) statement just above the quotedTrade.impliedHazardRate call to loop over that part of the code. See code below.

Surprisingly, the output of the first pass is different from the rest, despite the inputs being apparently the same:

Hazard: 0.0016898148745633896 Upfront: 795519.1252566372
Hazard: 0.0016827677048894731 Upfront: 795915.9786476545
Hazard: 0.0016827677048894731 Upfront: 795915.9786476545
Hazard: 0.0016827677048894731 Upfront: 795915.9786476545


If I "warm up" the yield curve by adding a

_ = discountCurve.discount(tradeDate+1)


before the loop, the problem disappears and the outputs are consistent. Does anyone know what is causing this behaviour?

Thanks

code below:

import QuantLib as ql

dep_tenors = [1,2,3,6,9,12]
dep_quotes = [0.003081,0.005525,0.007163,0.012413,0.014,0.015488]
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 = [2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30]
swap_quotes = [0.011907,
0.01699,
0.021198,
0.02444,
0.026937,
0.028967,
0.030504,
0.031719,
0.03279,
0.034535,
0.036217,
0.036981,
0.037246,
0.037605]

isda_ibor = ql.IborIndex('IsdaIbor',3*ql.Period(ql.Monthly),2,
ql.USDCurrency(),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(),isda_ibor)
for i in range(len(swap_tenors))]

isdaRateHelpers,
ql.Actual365Fixed()))
termDate = ql.Date(20, 6, 2019)
recovery = 0.4
tolerance = 1.0e-6

3*ql.Period(ql.Monthly),
ql.WeekendsOnly(),
ql.DateGeneration.CDS, False)

ql.FaceValueClaim(), ql.Actual360(True))

for _ in range(4):
recovery,1e-10,
ql.CreditDefaultSwap.ISDA)

ql.FlatHazardRate(0,ql.WeekendsOnly(),
ql.QuoteHandle(ql.SimpleQuote(h)),
ql.Actual365Fixed()))

engine = ql.IsdaCdsEngine(probabilityCurve,recovery,discountCurve)
$$$$
`