Skip to content
All library documents

Bond Valuation Differences in RQuantLib and Manual Discounting

Article Quant Q&A · Author: jjkk

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.