Hi Cheng,
As a workaround, I implemented a new method in Bond class to determine if the given settlement date falls into the last period or not.
bool Bond::isSettlementLastCouponPeriod(const Date& settlementDate)
const
{
Date refStartDate, refEndDate;
//
// Reverse iterate the cashflows to determine if the settlement falls into the last coupon period.
//
for (Size i = cashflows_.size() - 1; i>=0; --i)
{
shared_ptr<Coupon> coupon = boost::dynamic_pointer_cast<Coupon>(cashflows_[i]);
if (coupon)
{
refStartDate = coupon->referencePeriodStart();
refEndDate = coupon->referencePeriodEnd();
return refStartDate <= settlementDate && settlementDate <= refEndDate;
}
}
return false;
}
Then I did.
bool bIsSettlementLastCouponPeriod = bond.isSettlementLastCouponPeriod(settlementDate);
Compounding compoundingMethod = bIsSettlementLastCouponPeriod ? SimpleThenCompounded : Compounded
Real ql_clean_price = BondFunctions::cleanPrice( bond, ql_yield, bondDayCount, compoundingMethod, frequency,
settlementDate);
With this workaround, our prices matched with Bloomberg to a higher precision.
Thanks
-Senevi
From: Cheng Li [mailto:[hidden email]]
Sent: Sunday, December 08, 2013 10:22 AM
To: Senevi J Kankanamge Don; 'Smith, Dale (Norcross)'; [hidden email]
Subject: 答复: [Quantlib-users] Yield, Macaulay duration and Convexity calculation for Notes/Bonds
Hi Senevi,
I have met the same problem when I try to make my yield calculation matching with market quote in China bond market. The difference in compounding style is same. When bond is in last period,
simple compounding is used while not then compounded is used.
I think we have no work around. Maybe some new compounding style should be used? It may not be easy in current framework. We have to pass in more information.
Regards,
Cheng
发件人: Senevi J Kankanamge Don [[hidden email]]
发送时间: 2013年11月6日
22:55
收件人: Smith, Dale (Norcross);
[hidden email]
主题: Re: [Quantlib-users] Yield, Macaulay duration and Convexity calculation for Notes/Bonds
Hi Dale,
I appreciate your time looking into this. Thanks for your response.
We only use QuantLib to compute the yield, duration and convexity for individual instruments and we don’t build yield curve in QuantLib.
Bloomberg being the standard we adhere to, we are trying our best to match QuantLib results with Bloomberg.
Further investigation revealed why QuantLib
yield is different to that of Bloomberg.
If the settlement date falls into the last period (i.e. between 31-Mar-2015 and 30-Sep-2015 in my example), Bloomberg discounts the future cash flows (i.e. Redemption + Last coupon payment) to present value using
simple discount method. When the settlement is before 31-Mar-2015, Bloomberg discounts all future cash flows using compound discount method.
Using QuantLib, I am not able to figure out how to achieve the same.
If I do in my code,
Compounding compoundingMethod = SimpleThenCompounded;
QuantLib yield match 100% with Bloomberg when the settlement is in the last period. When the settlement is prior to the last period, QuantLib discounts the cash flow next to the settlement in simple discount
and the rest in compound method and hence the value is slightly different to Bloomberg which discounts all cash flows using compound method.
If I do in my code,
Compounding compoundingMethod = Compounded;
QuantLib yield match 100% with Bloomberg when the settlement is prior to the last period. When the settlement is in the last period, QuantLib discount the cash flow using compound method and hence the value is
different to Bloomberg which does a simple discount.
If this can be resolved, QuantLib yield will match 100% with Bloomberg.
Thanks
-Senevi
From: Smith, Dale (Norcross) [[hidden email]]
Sent: Wednesday, November 06, 2013 1:26 PM
To: Senevi J Kankanamge Don; [hidden email]
Subject: RE: [Quantlib-users] Yield, Macaulay duration and Convexity calculation for Notes/Bonds
Thanks for posting your code. It’s refreshing to see someone actually get this close to Bloomberg’s results. I salute you, as I know how hard it is to get this far. What yield curve are you using on Bloomberg
�C I25? How are you building your yield curve in QuantLib?
Based on my own experience, I would say you are very close to Bloomberg. I suspect it’s simply not worth chasing down the discrepancy, unless you want to fully investigate differences in
・
Day counts
・
Business rules (modified following, etc)
・
Yield curve interpolation
・
Compounding
・
Max evaluations
・
Etc
In other words, subtle differences in, say, Actual/Actual implementations between QuantLib and Bloomberg
may be causing these small differences. Is it really worth chasing them down when you can’t necessarily change them to match the Bloomberg implementation?
Dale Smith, Ph.D.
Senior Financial Quantitative Analyst
Financial & Risk Management Solutions
Fiserv
Office: 678-375-5315
From: Senevi J Kankanamge Don [[hidden email]]
Sent: Monday, November 04, 2013 10:25 AM
To: [hidden email]
Subject: [Quantlib-users] Yield, Macaulay duration and Convexity calculation for Notes/Bonds
Hi,
I am attempting to use QuantLib library in order to calculate yield, Macaulay duration and convexity for US Treasury Notes and Bonds.
This is how the values compare in Bloomberg and QuantLib for one example where the price is 99.8984375.
Bloomberg QuantLib
Yield 0.302775 0.3027679582
Macaulay Duration 1.928 1.9129221698
Convexity 0.047 0.0460608896
Can you please let me know what I need to change in my code in order to get the results matching with Bloomberg?
This is a snippet of my code.
double ql_price = 99.8984375;
Date settlementDate = Date(25, Oct, 2013);
Date firstCouponDate = Date(31, Mar, 2014);
Date datedDate = Date(30, Sep, 2013);
Date maturityDate = Date(30, Sep, 2015);
//
// Parameters required to define the bond
//
Natural settlementDays = 0;
Real faceAmount = 100;
DayCounter bondDayCount = ActualActual(ActualActual::Bond);
BusinessDayConvention paymentConvention = ModifiedFollowing;
Real redemption = 100.0;
Compounding compoundingMethod = SimpleThenCompounded;
DateGeneration::Rule dateGeneration = DateGeneration::Forward;
Frequency frequency = Semiannual;
Real accuracy = 1.0e-11;
Size maxEvaluations = 100;
//
// Create the Schedule
//
Schedule fixedBondSchedule(
datedDate, // Dated Date
maturityDate, // Maturity Date
Period(Semiannual), // Period
UnitedStates(UnitedStates::GovernmentBond), // Calendar
Unadjusted, // BusinessDayConvention - convention
Unadjusted, // BusinessDayConvention - terminationDateConvention
dateGeneration, // DateGeneration::Rule rule
false, // endOfMonth
firstCouponDate); // First Date
//
// Create the Fixed Rate Bond
//
FixedRateBond bond(
settlementDays, // Settlement Days
faceAmount, // Face Amount
fixedBondSchedule, // Schedule
std::vector<Rate>(1, ql_coupon), // Coupons
bondDayCount, // DayCounter
paymentConvention, // BusinessDayConvention
redemption); // Redemption
Real ql_yield = BondFunctions::yield( bond, ql_price, bondDayCount, compoundingMethod, frequency, settlementDate, accuracy, maxEvaluations);
InterestRate interestRate(ql_yield, bondDayCount, compoundingMethod, frequency );
Real ql_convexity = BondFunctions::convexity( bond, interestRate, settlementDate );
Compounding compoundingMethod4Duration = Compounded;
Time ql_duration = BondFunctions::duration( bond, ql_yield, bondDayCount, compoundingMethod4Duration, frequency, Duration::Macaulay, settlementDate );
Thanks
-Senevi
| Free forum by Nabble | Edit this page |