Re: qunatlib us treasury true yield

Posted by Luigi Ballabio on
URL: http://quantlib.414.s1.nabble.com/qunatlib-us-treasury-true-yield-tp8100p8102.html

Hi,
    you're right, the current implementation doesn't take into account
the reference period.

The changes at <https://github.com/lballabio/quantlib-mods/commit/7403bbe72c1278a55ca605ecd8b1a32e1ecfe3ea>
fix this and bring QuantLib numbers in accord with the quoted ones
(the diffs are not that clear, so you might want to look at the
resulting file at
<https://github.com/lballabio/quantlib-mods/blob/7403bbe72c1278a55ca605ecd8b1a32e1ecfe3ea/QuantLib/ql/cashflows/cashflows.cpp>
instead).

May someone else validate this before I check it in?

Thanks,
     Luigi


On Thu, Nov 1, 2012 at 12:28 PM, aexhg <[hidden email]> wrote:

>
> Hi,
>
> Here's an example for two treasury bonds. The difference between the yields
> is small but this can have a larger impact on the risk calcualtion.
>
>
> #include <iostream>
> #include <ql\quantlib.hpp>
> #include <string>
> #include <boost\function.hpp>
> #include <boost\bind.hpp>
> using namespace QuantLib;
>
>
>
> Real treasuryDirtyPrice(const Bond & bond, const Date & settlementDate,Real
> yield)
> {
>         Leg leg  = bond.cashflows();
>         Real npv = 0.0;
>         Real discount = 1.0;
>         Date lastDate = settlementDate;
>         Integer n     = leg.size();
>
>         for(Integer i = 0; i < n; ++i)
>         {
>                 boost::shared_ptr<CashFlow> cf = leg[i];
>                 Date paydate = cf->date();
>
>                 if(paydate > settlementDate)
>                 {
>                         Real amount = cf->amount();
>                         if(i != n - 1)
>                         {
>                                 boost::shared_ptr<FixedRateCoupon> coupon =
> boost::dynamic_pointer_cast<FixedRateCoupon>(cf);
>                                 if(cf)
>                                 {
>                                         Date accStart = coupon->accrualStartDate();
>                                         Date accEnd   = coupon->accrualEndDate();
>                                         DayCounter dc = coupon->dayCounter();
>                                         Real tau      = dc.yearFraction(lastDate,paydate,accStart,accEnd);
>                                         discount     *= 1.0 / std::pow(( 1.0 + yield *0.5) ,tau * 2.0);
>                                         lastDate      = paydate;
>                                 }
>                         }
>                         npv += discount * amount;
>                 }
>
>         }
>         return npv / bond.notional(settlementDate) * 100.0;
>
> }
>
> Real objFunc(const Bond & bond, const Date & settlementDate, Real
> mktDirtyPrice, Real yield)
> {
>         return mktDirtyPrice - treasuryDirtyPrice(bond,settlementDate,yield);
> }
>
> Real semiAnnualTreasuryYield(const Bond & bond, const Date & settlementDate,
> Real cleanPrice)
> {
>         Real dirtyPrice = cleanPrice + bond.accruedAmount(settlementDate);
>         Secant solver;
>
>         boost::function<Real (Real)>
> f(boost::bind(objFunc,bond,settlementDate,dirtyPrice,_1));
>
>     solver.setMaxEvaluations(100);
>         return solver.solve(f, 1E-10, 0.05,0.005);
> }
>
> int main() {
>
>         const int nBonds = 2;
>         const std::string isins []  = { "US912810FB99" , "US912828TN08"};
>         const Date issueDates []  = { Date(17,Nov,1997) , Date(31,Aug,2012) };
>         const Date maturityDates [] = { Date(15,Nov,2027) , Date(31,Aug,2019) };
>         const Date firstCouponDates [] = { Date(15,May,1998) , Date(31,Aug,2012) };
>         const Integer eom [] = {0, 1};
>         const Real coupons [] = { 0.06125 , 0.01};
>         const Real mktPrices [] = { 149.703125,99.199853 };
>         const Real streetYields [] = { 2.2194243 , 1.220000};
>         const Real trueYields [] = { 2.2193023 , 1.120670 };
>
>         Calendar calendar     = UnitedStates(UnitedStates::GovernmentBond);
>         DayCounter dayCounter = ActualActual(ActualActual::ISMA);
>         Date today        = Date(31,Oct,2012);
>         Date settle       = calendar.advance(today,1,Days);
>
>
>         std::cout << std::setw(15) << "Bond ISIN"     << "|"
>                           << std::setw(12) << "QL Yield"      << "|"
>                           << std::setw(12) << "my Yield"      << "|"
>                           << std::setw(12) << "str. Yield"    << "|"
>                           << std:: setw(12)<< "true Yield"    << "|"
>                           << std::endl;
>
>
>
>         for(int i = 0; i < nBonds; ++i)
>         {
>                 Schedule sched    =
> Schedule(issueDates[i],maturityDates[i],Period(6,TimeUnit::Months),calendar,
>
> Unadjusted,Unadjusted,DateGeneration::Backward,eom[i],firstCouponDates[i]);
>                 FixedRateBond bond(1,100.0,sched,std::vector<Rate>(1,coupons[i]),
>                                                         dayCounter,Following,100.0,
>                                                     issueDates[i],calendar);
>
>                 Real yld          =
> BondFunctions::yield(bond,mktPrices[i],dayCounter,Compounded,Semiannual,settle)
> * 100.0;
>                 Real myyld        = semiAnnualTreasuryYield(bond,settle,mktPrices[i]) *
> 100.0;
>                 Real streetYld    = streetYields[i];
>                 Real trueYld      = trueYields[i];
>                 std::cout<< std::setw(15) << isins[i] << "|"
>                                  << std::setw(12) << yld   << std::setprecision(8) << "|"
>                              << std::setw(12) << myyld << std::setprecision(8) << "|"
>                                  << std::setw(12) << streetYld << std::setprecision(8) << "|"
>                                  << std::setw(12) << trueYld   << std::setprecision(8) << "|"
>                                  << std::endl;
>
>         }
>
>
>         std::cin.get();
>         return 0;
>
> }
>
> and the output I get is:
>
>           Bond ISIN|    QL Yield|      my Yield|     str. Yield|  true
> Yield|
>    US912810FB99|     2.21942|   2.2193023|   2.2194243|   2.2193023|
>    US912828TN08|   1.1219999|    1.120655|           1.22|     1.12067|
>
> Thanks.
>
> aexhg wrote:
>>
>> Hi,
>> I'm trying to match up the true yield calculation of us treasury (bbg)
>> with quantlib. It seems to me that the cashflows::npv() does not take into
>> account the coupon referencePeriodBegin & referencePeriodEnd, so for us
>> treasuries with bad days, specifying a daycount convention of ISMA, I'll
>> never quite match the quoted bbg yield.  I was just wondering if I'm
>> missing something or if there's a workaround?
>>
>>
>>
>
> --
> View this message in context: http://old.nabble.com/qunatlib-us-treasury-true-yield-tp34572445p34628075.html
> Sent from the quantlib-users mailing list archive at Nabble.com.
>
>
> ------------------------------------------------------------------------------
> LogMeIn Central: Instant, anywhere, Remote PC access and management.
> Stay in control, update software, and manage PCs from one command center
> Diagnose problems and improve visibility into emerging IT issues
> Automate, monitor and manage. Do more in less time with Central
> http://p.sf.net/sfu/logmein12331_d2d
> _______________________________________________
> QuantLib-users mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/quantlib-users

------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users