Bond Valuation Differences in RQuantLib and Manual Discounting
Summary
The document compares a manually discounted fixed-rate bond price with the output from RQuantLib. Its example uses a five-year bond with annual coupons, a flat interest rate, and a settlement date one day after the evaluation date. The manual calculation discounts each coupon and the final principal payment, while the library output reports net present value, clean and dirty prices, accrued coupon, yield, duration, and scheduled cash flows.
The question focuses on why the library’s net present value differs from the hand calculation and why changing the accrual day counter appears not to change accrued interest. It raises practical valuation considerations: settlement timing, day-count conventions, curve setup, and how a pricing library applies bond schedules. However, the document contains no answer identifying the cause of the discrepancies, so it serves as a troubleshooting example rather than a resolved explanation. It does not establish which calculation is correct or provide a general rule for configuring the library.
Key ideas
- Bond present value can be calculated by discounting each coupon and principal payment.
- Settlement date and evaluation date can affect accrued interest and reported bond prices.
- Clean price excludes accrued coupon, while dirty price includes it.
- The example reports a mismatch between manual discounting and library valuation.
- The question does not resolve why the selected day-count convention appears ineffective.
Tags
Full text
# Issue on pricing bond using RQuantLib
# Issue on pricing bond using RQuantLib
trying to pricing a simple bond using RQuantLib, but cannot get the right values. For example, consider a bond with 2% annual coupon rate and flat interest rate of 3%, a 5 year maturity, and \$100 face value. I can get the $\textrm{NPV} = 95.42029$ by simple calculation:
$$2/(1+0.03) + 2/(1+0.03)^2 + 2/(1+0.03)^3 + 2/(1+0.03)^4 + 102/(1+0.03)^5.$$
However, when I use RQuantLib:
```
bond <- list(settlementDays=1,
issueDate=as.Date("2010-02-16"),
faceAmount=100,
accrualDayCounter='ActualActual.Bond',
paymentConvention='Unadjusted')
schedule <- list(effectiveDate=as.Date("2010-02-16"),
maturityDate=as.Date("2015-02-16"),
period='Annual',
calendar='UnitedStates/GovernmentBond',
businessDayConvention='Unadjusted',
terminationDateConvention='Unadjusted',
dateGeneration='Backward',
endOfMonth=0)
calc=list(dayCounter='ActualActual.Bond',
compounding='Compounded',
freq='Annual',
durationType='Modified')
coupon.rate <- c(0.02)
params <- list(tradeDate=as.Date('2010-02-16'),
settleDate=as.Date('2010-02-17'),
dt=.25,
interpWhat="discount",
interpHow="loglinear")
setEvaluationDate(as.Date("2010-02-16"))
discountCurve.flat <- DiscountCurve(params, list(flat=0.03))
FixedRateBond(bond,
coupon.rate,
schedule,
calc,
discountCurve=discountCurve.flat)
```
I got the following results:
```
Concise summary of valuation for FixedRateBond
Net present value : 95.22618
clean price : 95.221
dirty price : 95.226
accrued coupon : 0.0055556
yield : 0.030454
duration : 4.6575
settlement date : 2010-02-17
cash flows :
Date Amount
2011-02-16 2
2012-02-16 2
2013-02-16 2
2014-02-16 2
2015-02-16 2
2015-02-16 100
```
Another strange thing happens when I change the accrualDayCounter = Actual365NoLeap. I should expect the accrued coupon = 2/365 = 0.005479 (because only 1-day accrual). However, RQuantLib still gives 0.0055556 (=2/360). It seems changing the daycounter does not have any effect. What am I doing wrong here? Thank you for your help.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.