Re: FixedCouponBond pricing wrong?

Posted by Luigi Ballabio on
URL: http://quantlib.414.s1.nabble.com/FixedCouponBond-pricing-wrong-tp3741p3747.html

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