Login  Register

qunatlib us treasury true yield

classic Classic list List threaded Threaded
5 messages Options Options
Embed post
Permalink
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

qunatlib us treasury true yield

aexhg
2 posts
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?

Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: qunatlib us treasury true yield

Luigi Ballabio
3579 posts
Hi,
    apologies for the delay.  May you provide some code that
reproduces the problem?

Luigi

On Thu, Oct 18, 2012 at 1:29 PM, aexhg <[hidden email]> 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-tp34572445p34572445.html
> Sent from the quantlib-users mailing list archive at Nabble.com.
>
>
> ------------------------------------------------------------------------------
> Everyone hates slow websites. So do we.
> Make your web apps faster with AppDynamics
> Download AppDynamics Lite for free today:
> http://p.sf.net/sfu/appdyn_sfd2d_oct
> _______________________________________________
> QuantLib-users mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/quantlib-users

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: qunatlib us treasury true yield

aexhg
2 posts
In reply to this post by aexhg
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?
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: qunatlib us treasury true yield

Luigi Ballabio
3579 posts
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
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: qunatlib us treasury true yield

Luigi Ballabio
3579 posts
Henri,
    I've added the fix to the repository. Thanks for the heads-up.

Luigi


On Mon, Nov 19, 2012 at 10:45 AM, Luigi Ballabio
<[hidden email]> wrote:

> 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

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users