Discussion:
[Quantlib-users] Fail to replicate ISDA Fair Value CDS Model
wwd1015
2017-05-25 22:14:31 UTC
Permalink
Hi,I'm really new to quantlib so please pardon me for any stupid questions. I
have built Quantlib using the SWIG bindings for Python and tried to use it
to replicate the ISDA Fair Value CDS pricing engine (i.e. using real yield
curve and spread curve and assuming piecewise constant harzard rate). I
modified Luigi's sample code on GitHub and created the sample code below. It
seems that the hazard curve generated from the code is very different from
the Bloomberg result (see screenshot below). Any ideas why this
happens?Thanks in advance...Alanfrom QuantLib import *calendar = TARGET()#
Set evaluation datetodaysDate = Date(23, 5, 2017);todaysDate =
calendar.adjust(todaysDate) # business day
adjustmentSettings.instance().evaluationDate = todaysDate# CDS
parametersrecovery_rate = 0.4quoted_spreads = [0.001192, 0.002158, 0.003165,
0.004384, 0.005732, 0.007000, 0.009490, 0.011103]tenors =
[Period(6, Months), Period(1, Years), Period(2, Years), Period(3,
Years), Period(4, Years), Period(5, Years), Period(7, Years),
Period(10, Years)]maturities = [calendar.adjust(todaysDate + x, Following)
for x in tenors]spotRates = [0.010294, 0.010989, 0.011920,
0.014193, 0.017265, 0.015215, 0.016575, 0.017645, 0.018625,
0.019415, 0.020185, 0.020830, 0.021310, 0.021855, 0.022705,
0.023460, 0.024160, 0.024335, 0.024440]spotPeriod = [Period(1,
Months), Period(2, Months), Period(3, Months), Period(6,
Months), Period(1, Years), Period(2, Years),
Period(3, Years), Period(4, Years), Period(5, Years), Period(6,
Years), Period(7, Years), Period(8, Years),
Period(9, Years), Period(10, Years), Period(12, Years),
Period(15, Years), Period(20, Years), Period(25, Years),
Period(30, Years)]spotDates = [todaysDate + x for x in
spotPeriod]risk_free_rate = YieldTermStructureHandle(
ZeroCurve(spotDates, spotRates, Actual360()))# CDS instrumentsinstruments =
[ SpreadCdsHelper(QuoteHandle(SimpleQuote(s)), tenor,
0, calendar, Quarterly,
Following, DateGeneration.TwentiethIMM,
Actual360(), recovery_rate,
risk_free_rate) for s, tenor in zip(quoted_spreads, tenors)]hazard_curve
= PiecewiseFlatHazardRate(todaysDate, instruments,
Actual360())print("Calibrated hazard rate values: ")for x in
hazard_curve.nodes(): print("hazard rate on %s is %.7f" % x)# reprice
instrumentsnominal = 1000000.0probability =
DefaultProbabilityTermStructureHandle(hazard_curve)# create a cds for every
maturityall_cds = []for maturity, s in zip(maturities, quoted_spreads):
schedule = Schedule(todaysDate, maturity, Period(Quarterly),
calendar, Following, Following,
DateGeneration.TwentiethIMM, False) cds =
CreditDefaultSwap(Protection.Seller, nominal, s,
schedule, Following, Actual360()) engine = MidPointCdsEngine(probability,
recovery_rate, risk_free_rate) cds.setPricingEngine(engine)
all_cds.append(cds)print("Repricing of quoted CDSs employed for calibration:
")for i in range(len(tenors)): print("%s fair spread: %.7g" % (tenors[i],
all_cds[i].fairSpread())) print(" NPV: %g" % all_cds[i].NPV())
print(" default leg: %.7g" % all_cds[i].defaultLegNPV()) print("
coupon leg: %.7g" % all_cds[i].couponLegNPV())
<Loading Image...>



--
View this message in context: http://quantlib.10058.n7.nabble.com/Fail-to-replicate-ISDA-Fair-Value-CDS-Model-tp18310.html
Sent from the quantlib-users mailing list archive at Nabble.com.
Luigi Ballabio
2017-05-29 13:16:03 UTC
Permalink
May you post the code as an attachment? For some reason, its lines got all
mashed together, which made it unreadable.

Luigi
Hi, I'm really new to quantlib so please pardon me for any stupid
questions. I have built Quantlib using the SWIG bindings for Python and
tried to use it to replicate the ISDA Fair Value CDS pricing engine (i.e.
using real yield curve and spread curve and assuming piecewise constant
harzard rate). I modified Luigi's sample code on GitHub and created the
sample code below. It seems that the hazard curve generated from the code
is very different from the Bloomberg result (see screenshot below). Any
ideas why this happens? Thanks in advance... Alan from QuantLib import *
calendar = TARGET() # Set evaluation date todaysDate = Date(23, 5, 2017);
todaysDate = calendar.adjust(todaysDate) # business day adjustment
Settings.instance().evaluationDate = todaysDate # CDS parameters
recovery_rate = 0.4 quoted_spreads = [0.001192, 0.002158, 0.003165,
0.004384, 0.005732, 0.007000, 0.009490, 0.011103] tenors = [Period(6,
Months), Period(1, Years), Period(2, Years), Period(3, Years), Period(4,
Years), Period(5, Years), Period(7, Years), Period(10, Years)] maturities =
[calendar.adjust(todaysDate + x, Following) for x in tenors] spotRates =
[0.010294, 0.010989, 0.011920, 0.014193, 0.017265, 0.015215, 0.016575,
0.017645, 0.018625, 0.019415, 0.020185, 0.020830, 0.021310, 0.021855,
0.022705, 0.023460, 0.024160, 0.024335, 0.024440] spotPeriod = [Period(1,
Months), Period(2, Months), Period(3, Months), Period(6, Months), Period(1,
Years), Period(2, Years), Period(3, Years), Period(4, Years), Period(5,
Years), Period(6, Years), Period(7, Years), Period(8, Years), Period(9,
Years), Period(10, Years), Period(12, Years), Period(15, Years), Period(20,
Years), Period(25, Years), Period(30, Years)] spotDates = [todaysDate + x
for x in spotPeriod] risk_free_rate = YieldTermStructureHandle(
ZeroCurve(spotDates, spotRates, Actual360()) ) # CDS instruments
instruments = [ SpreadCdsHelper(QuoteHandle(SimpleQuote(s)), tenor, 0,
calendar, Quarterly, Following, DateGeneration.TwentiethIMM, Actual360(),
recovery_rate, risk_free_rate) for s, tenor in zip(quoted_spreads, tenors)]
hazard_curve = PiecewiseFlatHazardRate(todaysDate, instruments,
Actual360()) print("Calibrated hazard rate values: ") for x in
hazard_curve.nodes(): print("hazard rate on %s is %.7f" % x) # reprice
instruments nominal = 1000000.0 probability =
DefaultProbabilityTermStructureHandle(hazard_curve) # create a cds for
every maturity all_cds = [] for maturity, s in zip(maturities,
quoted_spreads): schedule = Schedule(todaysDate, maturity,
Period(Quarterly), calendar, Following, Following,
DateGeneration.TwentiethIMM, False) cds =
CreditDefaultSwap(Protection.Seller, nominal, s, schedule, Following,
Actual360()) engine = MidPointCdsEngine(probability, recovery_rate,
risk_free_rate) cds.setPricingEngine(engine) all_cds.append(cds)
print("Repricing of quoted CDSs employed for calibration: ") for i in
range(len(tenors)): print("%s fair spread: %.7g" % (tenors[i],
all_cds[i].fairSpread())) print(" NPV: %g" % all_cds[i].NPV()) print("
default leg: %.7g" % all_cds[i].defaultLegNPV()) print(" coupon leg: %.7g"
% all_cds[i].couponLegNPV())
------------------------------
View this message in context: Fail to replicate ISDA Fair Value CDS Model
<http://quantlib.10058.n7.nabble.com/Fail-to-replicate-ISDA-Fair-Value-CDS-Model-tp18310.html>
Sent from the quantlib-users mailing list archive
<http://quantlib.10058.n7.nabble.com/quantlib-users-f3.html> at
Nabble.com.
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
QuantLib-users mailing list
https://lists.sourceforge.net/lists/listinfo/quantlib-users
wwd1015
2017-05-30 02:09:49 UTC
Permalink
Thanks for the reply, Luigi. I have attached the modified code as the
attachment.

Alan



--
View this message in context: http://quantlib.10058.n7.nabble.com/Fail-to-replicate-ISDA-Fair-Value-CDS-Model-tp18310p18317.html
Sent from the quantlib-users mailing list archive at Nabble.com.
Luigi Ballabio
2017-06-01 10:34:24 UTC
Permalink
Hello Alan,
as far as I can see, you're using the available classes correctly, but
the existing mid-point engine doesn't implement the ISDA model exactly. We
have a pull request for that (https://github.com/lballabio/QuantLib/pull/112)
which for some reason has not yet been merged on the master branch. You
can try checking the PR out and using it, but you'll have to export the new
classes to Python.

Luigi
Post by wwd1015
Thanks for the reply, Luigi. I have attached the modified code as the
attachment.
Alan
--
http://quantlib.10058.n7.nabble.com/Fail-to-replicate-ISDA-Fair-Value-CDS-Model-tp18310p18317.html
Sent from the quantlib-users mailing list archive at Nabble.com.
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
QuantLib-users mailing list
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Loading...