I'm writing some software that includes a feature to calculate Yield to Maturity for a Bond. I'm using an HP 10bii Financial Calculator to double check the answers produced by my software. I'm running into a problem where the output of my code sometimes doesn't match up with the physical plastic calculator. I don't know much about Bonds except for what I've learned while trying to understand how to write this code. :)
Here's the scenario I've been testing with:
Purchase Price: $110
Call Value: $100
Coupon Rate/CPN%: 5%
Annual Coupons
Actual Year (as opposed to a 360 day year)
Settlement Date: Dec 1, 2009
Maturity Date: Jan 1, 2020
From that, I'm trying to calculate the Yield to Maturity (YTM%). I started with a more "normal" Settlement -> Maturity date (i.e. Jan 1, 2010 -> Jan 1, 2020). For those dates, my code works just fine and I get the right answer (3.780524135%).
However, when I push the Settlement Date back one month (Dec 1, 2009 -> Jan 1, 2020), then my calculated YTM% is slightly wrong.
The plastic 10bii calculator gives me: 3.787688399%
My software gives me: 3.788517337%
That's pretty close, but not close enough for my software. :) Whenever I calculate using a Settlement date that matches up exactly with a period boundary (a coupon date, if I'm using that terminology correctly), then the answer produced by my software is exactly right. Whenever the Settlement Date lands on any other date (non-coupon date), then my answer is slightly wrong. This leads me to believe that the discrepancy is related to the amount of interest which has accrued on the bond during the period leading up to the next coupon... but I really don't know how the interest is supposed to be handled on Bonds. I'm a real estate investor and a computer nerd, so I'm really good with TVM and Notes, but Bonds aren't something I've had a lot of experience with. :)
This is how my algorithm works:
Step 1) Determine the coupon/period dates the surround the Settlement Date.
This Bond uses annual periods, so counting backward from the Maturity Date... Jan 1, 2020 -> Jan 1, 2019 ..etc.. Jan 1, 2010 -> Jan 1, 2009. So, the coupon period that surrounds the Settlement Date is: [Jan 1, 2009 | Settlement: Dec 1, 2009 | Jan 1, 2010].
Rounding down to whole periods, that's 10 periods.
Step 2) Determine the fractional part of the remaining period
First, determine how many days there are from the Settlement Date to the end of the current period. (Dec 1, 2009 -> Jan 1, 2010) = 31. Next, divide that by the total number of days in that period = 365. So, 31/365 = 0.08493150685. Add that to the number of whole periods in Step 1. Num periods from Settlement to Maturity = 10.08493150685
Step 3) Perform a standard interest rate TVM calculation:
N = 10.08493150685
PV = -110
PMT = +5
FV = +100
Interest rate (I/YR) is calculated to be: 3.788517337%
If I put those inputs into my plastic calculator, I get the same interest rate. So, my software is performing Step 3 correctly given those inputs, but since this interest rate doesn't match the YTM% calculated for the overall Bond thats says to me that I'm not giving it the right inputs in Step 3.
Do you see anything I'm doing wrong?
In the above calculation, I'm paying \$110 now, then a month later I receive \$5 (\$100 x 5%) and I continue to receive a $5 payment on each Jan 1st until Jan 1st, 2020 when I receive the face value on the Bond (\$100). Am I modelling how a Bond sale actually works? (albeit a bond that I'm purchasing above par?)
I'm not doing anything with the interest that accrued from Jan 1, 2009 -> Dec 1, 2009 (i.e. the part of the period that comes before the Settlement Date). Is that accrued interest supposed to be included in one of my values in Step 3?
I tried taking the interest rate that the plastic calculator gives me (3.787688399%) and putting that into I/YR and then calculating N to see if I was calculating using the wrong number of periods, but the value I get would be equivalent to 10 years + 27 days instead of 10 years + 31 days. So, that seems wrong. That's why I'm assuming there is a problem with one of my PV, PMT, or FV values (and potentially N).
Any help is appreciated!
Edit:
I did some automated testing to compare my software output with the plastic 10bii output. I found that the farther I get away from a coupon date, the worse my answer and the closer I get, the better.
#: Difference | Settlement Date
0: 0.000828938 | 2009-12-01
1: 0.000000000 | 2010-01-01
2: 0.000827953 | 2010-02-01
3: 0.001450767 | 2010-03-01
4: 0.001999783 | 2010-04-01
5: 0.002388311 | 2010-05-01
6: 0.002639847 | 2010-06-01
7: 0.002735772 | 2010-07-01
8: 0.002679892 | 2010-08-01
9: 0.002463739 | 2010-09-01
10: 0.002099264 | 2010-10-01
11: 0.001559277 | 2010-11-01
12: 0.000875747 | 2010-12-01
13: 0.000000000 | 2011-01-01
14: 0.000875541 | 2011-02-01
This says to me that it's not the accrued interest, because if it was the AccInt then the discrepancy would grow and grow and then drop to 0 at each coupon period. The fact that it grows for 6 months and then shrinks for 6 months says to me something else is going on.
What aspect of the YTM am I missing?
Edit 2:
I've tried calculating the amount of accrued interest and both adding and subtracting that from the PV (which I think is the "dirty" price?), but that just makes my YTM calculation go much further away from the target number. Interest accrued from Jan 1, 2009 -> Nov 30, so the amount accrued was 4.58 out of 5.00. So, when I make the PV -114.58 or -105.42 that just gives me wildly wrong answers. :(