Posted by
ryantaylor on
Feb 28, 2017; 10:50pm
URL: http://quantlib.414.s1.nabble.com/Pricing-fixed-coupon-bonds-with-odd-first-coupon-short-long-first-coupon-tp18126.html
Hey guys,
I've been working through QuantLib over the past few days and I've gotten a decent handle on pricing bonds. I'm building a bond calculator and using Excel's PRICE and ODDFPRICE functions as a point of reference. I'm able to replicate PRICE with around 9 or 10 decimal places of accuracy, but I can only get around 4 decimal places of accuracy when trying to replicate ODDFPRICE. That's good enough for right now, but I'd like to improve that to at least 6 or 7 decimals of accuracy, and I'm not sure where I might be going wrong.
I'm using the following data:
Interest Accrual Date/Effective Date: 17-Jan-2017 (This goes into ODDFPRICE as issue date)
1st Coupon Payment Date: 28-Feb-2017
Settlement Date: 29-Jan-2017
Maturity Date: 28-Feb-2026
Annual Coupon Rate: 4.000%
Yield to Maturity: 3.957%
Payment Frequency: Semiannual
Day Count Convention: Actual/Actual (ISMA)
These inputs give me the following prices...
ODDFPRICE: 100.327679342028
QuantLib: 100.32761767821234855
The same code is accurate to 9 or 10 decimal places when I give it a regular coupon bond.
I found
this discussion from 2009 that seems like it might be related to this discrepancy, but the thread seemed to end without resolution. I've attached my code at the bottom, if anybody has any ideas about replicating ODDFPRICE in QuantLib I would very much appreciate it. Thanks a lot for your time!
Ryan
#include <ql/quantlib.hpp>
#include <iostream>
using namespace QuantLib;
int main() {
std::cout.precision(17);
Calendar calendar = Canada();
Date effectiveDate(17, January, 2017);
Date settlementDate(29, January, 2017);
Date firstCouponDate(28, February, 2017);
Date lastCouponDate(31, August, 2025);
Date maturityDate(28, February, 2026);
Natural settlementDays = 0;
Real faceAmount = 100.0;
Period period(Semiannual);
Rate coupon = 0.04;
Rate yield = 0.03957;
Schedule schedule(effectiveDate, maturityDate, period, calendar, Unadjusted, Unadjusted, DateGeneration::Backward, true, firstCouponDate, lastCouponDate);
InterestRate rate(coupon, ActualActual(ActualActual::ISMA), Simple, Semiannual);
FixedRateBond bond(settlementDays, faceAmount, schedule, std::vector<InterestRate>(1, rate), Unadjusted);
Real price = bond.cleanPrice(yield, ActualActual(ActualActual::ISMA), Compounded, Semiannual, settlementDate);
std::cout << "Price: " << std::fixed << price << std::endl;
return 1;
}