As I am getting the library running for my needs, I thought a good way to figure it all out would be to enter all the examples from Standard Securities Calculation Methods as test cases. Everything
was going great until I got to formula 9 page 74, Odd Long First Coupon.
There is a difference in the methodology used to calculate odd coupon periods. After stepping throught the code, it appears that quantlib uses the percent of a year to generate the odd coupon interest. It ends up
getting the fraction from DayCounter.yearFraction.
In Standard Securities Calculation Methods, the odd coupon is basically calculated as a percent of period. The difference does not appear until you get to the third decimal of precision on yield / clean price calculations.
I am not a real bond person so this may not be an issue but it seems that there is probably a "right" way that matches industry (i.e. bloomberg or IDC data).
Can anyone provide any insight on this?
As an additional not I am building my schedule using the issue date and maturity date, and the first / last coupon as the last two arguments to the constructor. My Pricing engine is the DiscountingBondEngine using
a YieldTermStructure for the curve.
------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Tue, Sep 8, 2009 at 4:11 PM, Mike Benson<[hidden email]> wrote:
> As I am getting the library running for my needs, I thought a good way to > figure it all out would be to enter all the examples from Standard > Securities Calculation Methods as test cases. Everything was going great > until I got to formula 9 page 74, Odd Long First Coupon. I don't have the Mayle's book, so more detail about that specific case would be appreciated. As far as I know the only issue might arise with act/act ISMA for irregular short/long coupon ciao -- Nando ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Thanks for the response, here is what I am using:
Settlement Date: 11/11/1992 (mm/dd/yyyy) Maturity Date: 03/01/2005 (mm/dd/yyyy) Issue Date: 06/15/1992 (mm/dd/yyyy) First Coupon Date: 03/01/1993 (mm/dd/yyyy) Day Count Basis: Actual/Actual Mayle: Rate: 9.35% Expected Yield: 7.75% Expected Price: 112.478106 Quantlib (My test case); Yield (Given price): 7.7499% Price (Given Yield) : 112.477135 In the Standard Securities Calculation manual they use "quasi coupon periods" to calculate accrued income. In a nutshell, you create one or more quasi coupon periods from issue to first coupon and use those quasi periods to calculate the accrued income / price. As I said in my original email, I am new to the library so perhaps I am setting something up incorrectly. My Test Case: [TestMethod] public void Tips_Volume1_Page75_OddLongFirstCoupon() { Double issuePrice = 100D; Double redemptionPrice = 100D; Date issueDate = new Date(15, Month.June, 1992); Date maturityDate = new Date(01, Month.March, 2005); Date firstCoupon = new Date(01, Month.March, 1993); Date lastCoupon = new Date(01, Month.September, 2004); Date settlementDate = new Date(11, Month.November, 1992); Double rate = .0935; Double yield = .0775; Double price = 112.478106D; Schedule schedule = new Schedule( issueDate, //effectiveDate maturityDate, //terminationDate new Period(6, TimeUnit.Months), //tenor new UnitedStates(), //calendar BusinessDayConvention.Unadjusted, //convention BusinessDayConvention.Unadjusted, //termination convention DateGeneration.Rule.Forward, //rule false, //end of month firstCoupon, //first date lastCoupon); //next to last date DayCounter counter = new ActualActual(ActualActual.Convention.ISDA); DoubleVector coupons = new DoubleVector { .0935D }; FixedRateBond bond = new FixedRateBond( 0, //settlementDays issuePrice, //faceAmount schedule, //schedule coupons, //coupons counter, //paymentDayCounter BusinessDayConvention.Unadjusted, //paymentConvention redemptionPrice,//redemption issueDate); //issueDate RelinkableYieldTermStructureHandle termstructure = new RelinkableYieldTermStructureHandle(); FlatForward ff = new FlatForward(issueDate, rate, counter); termstructure.linkTo(ff); PricingEngine pe = new DiscountingBondEngine(termstructure); bond.setPricingEngine(pe); double p = bond.cleanPrice(yield, counter, Compounding.Compounded, Frequency.Semiannual, settlementDate); double y = bond.yield(price, counter, Compounding.Compounded, Frequency.Semiannual, settlementDate); Assert.AreEqual(price, p); // fails -- p = 112.477135 Assert.AreEqual(yield, y); // fails -- y = 0.077499 } ________________________________________ From: [hidden email] [[hidden email]] On Behalf Of Ferdinando Ametrano [[hidden email]] Sent: Tuesday, September 08, 2009 8:53 AM To: Mike Benson Cc: [hidden email] Subject: Re: [Quantlib-users] Odd coupon periods On Tue, Sep 8, 2009 at 4:11 PM, Mike Benson<[hidden email]> wrote: > As I am getting the library running for my needs, I thought a good way to > figure it all out would be to enter all the examples from Standard > Securities Calculation Methods as test cases. Everything was going great > until I got to formula 9 page 74, Odd Long First Coupon. I don't have the Mayle's book, so more detail about that specific case would be appreciated. As far as I know the only issue might arise with act/act ISMA for irregular short/long coupon ciao -- Nando ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Tue, 2009-09-08 at 08:40 -0700, Mike Benson wrote:
> Thanks for the response, here is what I am using: > > Issue Date: 06/15/1992 (mm/dd/yyyy) > First Coupon Date: 03/01/1993 (mm/dd/yyyy) > > In the Standard Securities Calculation manual they use "quasi coupon > periods" to calculate accrued income. In a nutshell, you create one > or more quasi coupon periods from issue to first coupon and use those > quasi periods to calculate the accrued income / price. Mike, just to spell it out---you're saying that instead of T = yearFraction(issueDate, firstCouponDate) one should use T = yearFraction(issueDate, d) + yearFraction(d, firstCouponDate) with d being one regular coupon after the issue, i.e., 12/15/1992 or something like it? Luigi -- Ogden's Law: The sooner you fall behind, the more time you have to catch up. ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Thats not quite correct
Short first coupon: T = yearFraction(issueDate, settlementDate) / yearFraction(d, firstCoupon) d = The date a normal coupon would have paid prior to the first coupon date. Short last coupon: T = yearFraction(lastcoupon, settlement) / yearFraction(lastCoupon, d) d = The date a normal coupon would have paid after last coupon date. Long coupons are a bit more complicated, you have to turn this into two quasi coupon periods and add them together. Long first coupon: T = (yearFraction(issueDate, d1) / yearFraction(d2, d1)) + (yearFraction(d1, settlement) / yearFraction(firstCoupon)) d1 = The date a normal coupon would have paid prior to the first coupon date d2 = The date a second normal coupon would have paid prior to d1 My C++ is way to rusty to substitue and test this, but if we have a volunteer, I could put together 30-40 sets of test case data to check. Its also worth a note the Municipal bonds ignore this for price / yield calcualtions but not accrued interest. Since I am wrapping the library I just dont set the coupons for first / last on munis when calculating price / yield. Here are the explanations from Standard Securities Calculation Methods (SCCM). >From SCCM volume 1 page 30 - Short Coupon Formula To determine the accrued interest in a short coupon period, that coupon period's length must be adjusted to represent a normal length (NL) or quasi-coupon* period (NL replaces D in the standard formula). This is done in one of the tow following ways; Odd first coupon: by working backwards in time from the short coupon's interest payment date (first coupon date) to a date representing the first day of teh quasi coupon period; Odd lat coupon: by working forward in time from the short coupon's interest payment date (last coupon date before redemption) to a date representing the last day of the quasi coupon period. ..... Accrued Interest = P * R/M * A/NL A = Accrued days M = Number of coupon periods per year NL = Number of days representing the quasi-coupon period P = Par Value R = Annual coupon rate * The term "quasi-coupon period" is used to represent the length of the coupon period that is standard for the security (semi-annual, annual, etc.). Thus, a semi-annual corporate bond with three months for its first coupon period has one quasi-coupon period of 180 days. Example: Day Count 30/360 Issue 07/01/1992 First Interest Date: 10/01/1992 Settlement Date: 08/18/1992 M = 2 Semi-annual coupon payments NL = 180 Since day count basis is 30/360 and the number of coupons per year is 2 (360/2 =180) P = 1000 R = .05 A = 47 accrued days are found by determining the number of days from issue date to settlemetn date (07/01/1992 to 08/18/1992) Thus: Accrued Interest = 1000 * (.05/2) * (47/180) = 6.53 >From SCCM volume 1 page 32 - Long Coupon Formula To determine the accrued interest for long coupon periods, the number (NC) of quasi-coupon* periods must be calculated. This is done in one of the two following ways; Odd long first coupon: by working backwards in time fromt eh long coupon's interest payment dare (first coupon date) and adding together the number of standard coupon periods that would fist in the long coupon, round up to the next whole number; Odd long last coupon: by working forward in time from the long coupon's interest payment date (last coupon date before redemption) and adding together the number of standard coupon periods that would fit in the long coupon founding up to the next whole number. For example, between the issue date of 07/01/199 and the first coupon date of 04/01/1993 there are 1 1/2 six month periods or 2(NC=2) quasi coupon periods. Accured Interest = P * (R/M) * ( Sum 1 to NC(Ai/NLi)) Ai = number of accruded days for the ith quasi coupon period within odd period M = number of coupon periods per year NC = Number of quasi-coupon periods that fit in odd period. If this number contains a fractional part, raise it to the the next whole number. NLi= Normal length in days of the ith quasi-coupon period within odd period P = Par Value R = Annual interest rate * The term "quasi-coupon period" is used to represent the length of the coupon period that is standard for the security (semi-annual, annual, etc.). Thus, a semi-annual municipal bond with nine months for its first coupon period has two quasi-coupon periods, each with a length of 180 days Example: Day Count Basis: Acutual/Actual Issue Date: 07/01/1992 First Interest Date: 04/01/1993 Settlement Date: 02/01/1993 M = 2 A1 = 123 (10/01/1992-02/01/1993) A2 = 92 (07/01/1992-10/01/1992) NC = 2 (10/01/1992-04/01/1993) (04/01/1992-10/01/1992) NL1 = 182 (10/01/1992-04/01/1993) NL2 = 183 (04/01/1992-10/01/1992) P = 10000 R = .075 Accrued Interest = 10000 * (.075/2) * (123/182 + 92/183) = 441.96 Visually: |---A2-----|-----A2------| 04/01/92---07/01/92---10/01/1992----02/01/92--04/01/93 |--------NL2-----------|-----------NL1---------| --- My notes NC in this case are the quasi coupon periods. The first coupon date is 04/01/1993 you have to work backwards until you cross the issue date. Going back from 04/01/1993, the prior normal coupon would have been 10/01/1992 (not before issue date). Go back again, 04/01/1992, since this is before the issue date, you have to use two quasi coupon periods. ________________________________________ From: Luigi Ballabio [[hidden email]] Sent: Friday, September 11, 2009 8:09 AM To: Mike Benson Cc: [hidden email] Subject: Re: [Quantlib-users] Odd coupon periods On Tue, 2009-09-08 at 08:40 -0700, Mike Benson wrote: > Thanks for the response, here is what I am using: > > Issue Date: 06/15/1992 (mm/dd/yyyy) > First Coupon Date: 03/01/1993 (mm/dd/yyyy) > > In the Standard Securities Calculation manual they use "quasi coupon > periods" to calculate accrued income. In a nutshell, you create one > or more quasi coupon periods from issue to first coupon and use those > quasi periods to calculate the accrued income / price. Mike, just to spell it out---you're saying that instead of T = yearFraction(issueDate, firstCouponDate) one should use T = yearFraction(issueDate, d) + yearFraction(d, firstCouponDate) with d being one regular coupon after the issue, i.e., 12/15/1992 or something like it? Luigi -- Ogden's Law: The sooner you fall behind, the more time you have to catch up. ------------------------------------------------------------------------------ Come build with us! The BlackBerry® Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9-12, 2009. Register now! http://p.sf.net/sfu/devconf _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Free forum by Nabble | Edit this page |