Login  Register

Question: small discrepancy in bond.cleanPrice() versus calling BondFunctions.cleanPrice() ?? help!

Posted by Nick Pierce on Dec 06, 2016; 5:09pm
URL: http://quantlib.414.s1.nabble.com/Question-small-discrepancy-in-bond-cleanPrice-versus-calling-BondFunctions-cleanPrice-help-tp17898.html

Hi

I’m very new to Quantlib - about a week in (quite amazed so far!), but I have managed to get some bonds working in Python 2.7, using SWIG. QL v 1.9.

I have set up a bond and the schedule is correct. When I calculate the clean price by inputting a yield (using BondFunctions.cleanPrice(…pass in yield)), this is correct (and yield from clean price), accrued is also correct and duration is fine as yield is not far out.

However, when I attach a yield curve (flat forward) with the same yield, I get a fractionally different / price yield calc. Dates in the schedule are unadjusted, not modified following.

Results:

Clean Price Expected                     : 179.03
Clean Price BondFunctions.cleanPrice()   : 179.03
Clean Price bond.cleanPrice()            : 179.09
Difference                               : 0.0626431535518

Yield Expected                           : -0.0145461
Yield BondFunctions.BondYield()          : -0.0145461
Yield bond.bondYield()                   : -0.01455624
Difference                               : 1.01382016107e-05

Duration Expected                        : 34.52
Duration BondFunctions.duration()        : 34.52
Accrued Expected                         : 0.0483425414365
Accrued BondFunctions.accruedAmount()    : 0.0483425414365
Accrued bond.accruedAmount()             : 0.0483425414365
Program ended with exit code: 0

As you can see the calculated clean price from bond.cleanPrice() is 6 cents different (incorrect)..and it’s been driving me mad!! The yield is different from the 5th decimal place.

This is a real bond and the input numbers have been verified using a manual calc in excel, they match the officially published numbers from the UK debt management office (negative yield
 is the real yield for an inflation linked gilt, i.e. the quote of 179.03 is the market quote (clean) for the UKTI 52’s, before the index ratio is applied).

In this example the price is the closing price for 30th Nov and settlement date is 1st Dec, 2016.

If anyone can point out where I have gone wrong it would be much appreciated.

Code is below.

Many thanks 

Nick

import QuantLib as ql
import datetime as dt
calendar = ql.UnitedKingdom()
coupons=[0.0025]
exCouponPeriod=ql.Period(6,ql.Days)
calendarCoupon=ql.UnitedKingdom()
faceValue=100
businessConvention = ql.Unadjusted
businessConventionCoupon=ql.Unadjusted

today = ql.Date(30,11,2016)
evaluationDate = calendar.adjust(today)
issue_date = calendar.advance(evaluationDate,-1, ql.Years)
maturity_date = ql.Date(22,3,2052)

settlementDays=1
settlementDate=today+1
dayCount=ql.ActualActual(ql.ActualActual.ISMA)


ql.Settings.instance().setEvaluationDate(evaluationDate)

#input values to be checked
inputYield=-0.014546100
inputCleanPrice=179.03
inputDuration=34.52
inputAccrued=0.0483425414365


#create schedule
fixedSchedule = ql.Schedule(issue_date,maturity_date,ql.Period(ql.Semiannual),calendar,ql.Unadjusted,ql.Unadjusted,ql.DateGeneration.Backward,False)

#create bond
fixed_rate_bond = ql.FixedRateBond(settlementDays,faceValue,fixedSchedule,coupons,dayCount,businessConvention,100,issue_date,calendar,exCouponPeriod,calendarCoupon,businessConventionCoupon,False)

#curve
ts_curve=ql.FlatForward(evaluationDate, inputYield, dayCount, ql.Compounded, ql.Semiannual)

#curve handle
ts_handle = ql.YieldTermStructureHandle(ts_curve)

#create bond engine
bond_engine = ql.DiscountingBondEngine(ts_handle)#set bond engine

#set pricing engine
fixed_rate_bond.setPricingEngine(bond_engine)

#calculate yield from clean price
#calculations using BondFunctions
bf_gry=ql.BondFunctions.bondYield(fixed_rate_bond,inputCleanPrice,dayCount,ql.Compounded,ql.Semiannual,settlementDate)
bf_cp=ql.BondFunctions.cleanPrice(fixed_rate_bond,bf_gry,dayCount,ql.Compounded,ql.Semiannual,settlementDate)
bf_ai=ql.BondFunctions.accruedAmount(fixed_rate_bond,settlementDate)
bf_md=ql.BondFunctions.duration(fixed_rate_bond,bf_gry,dayCount,ql.Compounded,ql.Semiannual,ql.Duration.Modified,settlementDate)

#Calculations using bond
b_gry=fixed_rate_bond.bondYield(dayCount,ql.Compounded,ql.Semiannual)
b_cp=fixed_rate_bond.cleanPrice()
b_ai=fixed_rate_bond.accruedAmount()

print "Clean Price Expected                     :",inputCleanPrice
print "Clean Price BondFunctions.cleanPrice()   :",round(bf_cp,2)
print "Clean Price bond.cleanPrice()            :",round(b_cp,2)
print "Difference                               :",b_cp-bf_cp
print ""
print "Yield Expected                           :",round(inputYield,8)
print "Yield BondFunctions.BondYield()          :",round(bf_gry,8)
print "Yield bond.bondYield()                   :",round(b_gry,8)
print "Difference                               :",bf_gry-b_gry
print ""

print "Duration Expected                        :",inputDuration
print "Duration BondFunctions.duration()        :",round(bf_md,2)

print "Accrued Expected                         :", inputAccrued
print "Accrued BondFunctions.accruedAmount()    :", bf_ai
print "Accrued bond.accruedAmount()             :", b_ai

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today.http://sdm.link/xeonphi
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users