I am new to QuantLib. Hope sb. can help me this out.
See the test_suite/bonds.cpp, testCachedYield() function. For bond1, the marketPrice1=99.203125. However, my caculation on scratch paper shows the price p = c*(u+u^2+u^3+u^4) + 1*u^4 = 98.41 where c = 0.025, u =1/(1+y/2) The two results differ. I realize that I use a different calendar and daycounting scheme. So I hack the bonds.cpp code to use Calandar bondCalendar = TARGET(); DayCounter bondDayCount = OneDayCounter(); then, the program computes the price = 95.91, still differ! Anybody knows why? |
On 04/22/05 01:09:04, Feng Ning wrote:
> > See the test_suite/bonds.cpp, testCachedYield() function. > For bond1, the marketPrice1=99.203125. > However, my caculation on scratch paper shows the price > p = c*(u+u^2+u^3+u^4) + 1*u^4 = 98.41 > where c = 0.025, u =1/(1+y/2) What figures did you put into your calculation? The formula is correct (and the calendar and day counter used in testCachedYield are consistent with it,) but I get c = 0.025/2 = 0.0125 y = 0.02925 u = 1/(1+y/2) = 0.98559 p = c*(u+u^2+u^3+u^4) + 1*u^4 = 99.18 (not 98.41) There's still a difference, but it is due to the fact that your formula gives you the price at the issue date. The test calculates the bond price on November 22nd, 2004---22 days after. The difference is the discount factor between the two dates. If one edits the test and writes Date today(30,October,2004); the result is consistent with the formula. Later, Luigi ---------------------------------------- Barker's Proof: Proofreading is more effective after publication. |
In reply to this post by Feng Ning
Thanks to Luigi for his reply. But the problem persist.
1) I am not clear what it means: Date today(30, October, 2004); I assume it means we should set the evaluation date, so I use: Settings::instance().setEvaluationDate(Date(31,October,2004)); It turns out: calculated clean price=95.92, dirty price = 98.42. 2) my computation differs from Luigi's bcoz I feel that the coupon is semiannual value, so I use c=0.025/2, instead of c=0.025. I verify this by printing out the cashflows as in the code. The complete code is below: // bond-tester.cpp #include <iostream> #include <ql/quantlib.hpp> using namespace QuantLib; int main() { Settings::instance().setEvaluationDate(Date(31,October,2004)); std::cout << "today date: "<< Date::todaysDate() << std::endl; Calendar bondCalendar = nullCalendar(); DayCounter bondDayCount = OneDayCounter(); Integer settlementDays = 1; // actual market values from the evaluation date FixedCouponBond bond1(Date(1,November,2004), Date(31,October,2004), Date(31,October,2006), settlementDays, 0.025, Semiannual, bondDayCount, bondCalendar, Unadjusted, 100.0); Real marketPrice1 = 99.203125; Rate marketYield1 = 0.02925; // check Real tolerance = 1.0e-6; Real price, dprice, yield; // calculated values Real cachedPrice1 = 99.204505; Rate cachedYield1 = 0.029257; price = bond1.cleanPrice(marketYield1); dprice = bond1.dirtyPrice(marketYield1); std::cout << " calculated clean price: " << DecimalFormatter::toString(price,6) << "\n" << " calculated dirty price: " << DecimalFormatter::toString(dprice,6) << "\n" << " expected: " << DecimalFormatter::toString(cachedPrice1,6) << "\n" << " error: " << DecimalFormatter::toString(price-cachedPrice1,6) << std::endl; std::cout << " Show cashflow: \n"; std::vector<boost::shared_ptr<CashFlow> > cashflows = bond1.cashflows(); for (Size i=0; i<cashflows.size(); ++i) { std::cout << cashflows[i]->date() << ": " << cashflows[i]->amount() <<"\n"; } return 0; } //main |
In reply to this post by Feng Ning
Ning,
I think you present one extreme condition in the way you use FixedCouponBond: 1. the issue date is 11/1/04; 2. the settlement date is 11/1/04; In reality, I dont know if you can do this. However, you make a case that the price/yield calculation should consider this, or prevent further calculation because of the invalid entry. Let me think about how this should be addressed. You can certainly put in some more realistic inputs to test it out. Cheers, Jeff -----Original Message----- From: [hidden email] [mailto:[hidden email]]On Behalf Of Feng Ning Sent: Friday, April 22, 2005 10:23 AM To: [hidden email] Cc: [hidden email] Subject: Re: [Quantlib-users] FixedCouponBond pricing wrong? Thanks to Luigi for his reply. But the problem persist. 1) I am not clear what it means: Date today(30, October, 2004); I assume it means we should set the evaluation date, so I use: Settings::instance().setEvaluationDate(Date(31,October,2004)); It turns out: calculated clean price=95.92, dirty price = 98.42. 2) my computation differs from Luigi's bcoz I feel that the coupon is semiannual value, so I use c=0.025/2, instead of c=0.025. I verify this by printing out the cashflows as in the code. The complete code is below: // bond-tester.cpp #include <iostream> #include <ql/quantlib.hpp> using namespace QuantLib; int main() { Settings::instance().setEvaluationDate(Date(31,October,2004)); std::cout << "today date: "<< Date::todaysDate() << std::endl; Calendar bondCalendar = nullCalendar(); DayCounter bondDayCount = OneDayCounter(); Integer settlementDays = 1; // actual market values from the evaluation date FixedCouponBond bond1(Date(1,November,2004), Date(31,October,2004), Date(31,October,2006), settlementDays, 0.025, Semiannual, bondDayCount, bondCalendar, Unadjusted, 100.0); Real marketPrice1 = 99.203125; Rate marketYield1 = 0.02925; // check Real tolerance = 1.0e-6; Real price, dprice, yield; // calculated values Real cachedPrice1 = 99.204505; Rate cachedYield1 = 0.029257; price = bond1.cleanPrice(marketYield1); dprice = bond1.dirtyPrice(marketYield1); std::cout << " calculated clean price: " << DecimalFormatter::toString(price,6) << "\n" << " calculated dirty price: " << DecimalFormatter::toString(dprice,6) << "\n" << " expected: " << DecimalFormatter::toString(cachedPrice1,6) << "\n" << " error: " << DecimalFormatter::toString(price-cachedPrice1,6) << std::endl; std::cout << " Show cashflow: \n"; std::vector<boost::shared_ptr<CashFlow> > cashflows = bond1.cashflows(); for (Size i=0; i<cashflows.size(); ++i) { std::cout << cashflows[i]->date() << ": " << cashflows[i]->amount() <<"\n"; } return 0; } //main ------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click _______________________________________________ Quantlib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users Visit our website at http://www.ubs.com This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message which arise as a result of e-mail transmission. If verification is required please request a hard-copy version. This message is provided for informational purposes and should not be construed as a solicitation or offer to buy or sell any securities or related financial instruments. |
In reply to this post by Feng Ning
On Apr 22, 2005, at 4:23 PM, Feng Ning wrote:
> Thanks to Luigi for his reply. But the problem persist. > 1) I am not clear what it means: > Date today(30, October, 2004); > > I assume it means we should set the evaluation date, so I use: > Settings::instance().setEvaluationDate(Date(31,October,2004)); That is correct. In the test code there was: Date today(...); Settings::instance().setEvaluationDate(today); which does the same thing. > 2) my computation differs from Luigi's bcoz I feel that the coupon is > semiannual value, so I use c=0.025/2, instead of c=0.025. So did I. As I wrote in my previous mail, c = 0.025/2 = 0.0125 (as you do correctly) y = 0.02925 u = 1/(1+y/2) = 0.98559 p = c*(u+u^2+u^3+u^4) + 1*u^4 = 99.18 (not the 98.41 you mentioned.) Can you check your sketch calculation against the above? > The complete code is below: > // bond-tester.cpp > #include <iostream> > #include <ql/quantlib.hpp> > using namespace QuantLib; > > int main() { > Settings::instance().setEvaluationDate(Date(31,October,2004)); > std::cout << "today date: "<< Date::todaysDate() << std::endl; > Calendar bondCalendar = nullCalendar(); > DayCounter bondDayCount = OneDayCounter(); OneDayCounter is wrong. The ActualActual(ActualActual::ISMA) in the test was correct; use that one. Alternatively, you can try SimpleDayCounter(). > Integer settlementDays = 1; > > // actual market values from the evaluation date > > FixedCouponBond bond1(Date(1,November,2004), > Date(31,October,2004), > Date(31,October,2006), > settlementDays, > 0.025, Semiannual, > bondDayCount, bondCalendar, > Unadjusted, 100.0); > > Real marketPrice1 = 99.203125; > Rate marketYield1 = 0.02925; > // check > Real tolerance = 1.0e-6; > Real price, dprice, yield; > // calculated values > > Real cachedPrice1 = 99.204505; This is expected for evaluation date = November 22nd. For October 30 you should get 99.18 due to discounting between the two dates. > Rate cachedYield1 = 0.029257; price = > bond1.cleanPrice(marketYield1); > dprice = bond1.dirtyPrice(marketYield1); > std::cout << " calculated clean price: " > << DecimalFormatter::toString(price,6) << "\n" > << " calculated dirty price: " > << DecimalFormatter::toString(dprice,6) << "\n" > << " expected: " > << DecimalFormatter::toString(cachedPrice1,6) << "\n" > << " error: " > << DecimalFormatter::toString(price-cachedPrice1,6) > << std::endl; > std::cout << " Show cashflow: \n"; > std::vector<boost::shared_ptr<CashFlow> > cashflows = > bond1.cashflows(); > for (Size i=0; i<cashflows.size(); ++i) { > std::cout << cashflows[i]->date() << ": " << > cashflows[i]->amount() <<"\n"; > } > return 0; > } //main Later, Luigi |
In reply to this post by Jeffrey-J.Yu
On Apr 22, 2005, at 4:38 PM, [hidden email] wrote:
> Ning, > > I think you present one extreme condition in the way you use > FixedCouponBond: > > 1. the issue date is 11/1/04; > 2. the settlement date is 11/1/04; > > In reality, I dont know if you can do this. I don't know if you can in the real world, the calculation should work correctly. At least it does on my machine with the latest code. Luigi |
In reply to this post by Feng Ning
The dated date is when the interest start accrued. In Ning's test code,
he is saying that the bond was traded before the issue date, so it can be settled on the issue date (given the settlement convention he set is T+1.). The cash flow is what determines the price/yield. I am afraid this is a kind of special case, in which the accrued day is 0. Well, I suggest Ning pick a different date in his test drive, at the same time we can think about how to handle this. When the trade date is prior to the issue date, the bond is quoted in yield, instead of price. When it is settled, the price would then be derived from the yield. -----Original Message----- From: Luigi Ballabio [mailto:[hidden email]] Sent: Friday, April 22, 2005 3:55 PM To: Yu, Jeffrey-J Cc: [hidden email]; [hidden email] Subject: Re: [Quantlib-users] FixedCouponBond pricing wrong? On Apr 22, 2005, at 4:38 PM, [hidden email] wrote: > Ning, > > I think you present one extreme condition in the way you use > FixedCouponBond: > > 1. the issue date is 11/1/04; > 2. the settlement date is 11/1/04; > > In reality, I dont know if you can do this. I don't know if you can in the real world, the calculation should work correctly. At least it does on my machine with the latest code. Luigi Visit our website at http://www.ubs.com This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message which arise as a result of e-mail transmission. If verification is required please request a hard-copy version. This message is provided for informational purposes and should not be construed as a solicitation or offer to buy or sell any securities or related financial instruments. |
On Apr 22, 2005, at 10:06 PM, [hidden email] wrote:
> The dated date is when the interest start accrued. In Ning's test > code, > he is saying that the bond was traded before the issue date, so it can > be > settled on the issue date (given the settlement convention he set is > T+1.). > > I am afraid this is a kind of special case, in which the accrued day > is 0. I agree. But this special case is exactly what you need for reproducing Ning's back-of-the-envelope calculation. And indeed, the result is consistent with the formula. Later, Luigi |
Free forum by Nabble | Edit this page |