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? |
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 |
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.
|
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 |
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 |
Free forum by Nabble | Edit this page |