My apologies. I got distracted by life; then so much time had elapased that I didn't know if you were still interested.
I cannot offer a good solution; I think it is best implemented in VBA.
What I provide is a proof of concept with some explanation.
For the discussion below, download the file "oddlprice excelforum.xlsx" from https://app.box.com/s/wyb64fte7i211fjqsxxm2h09sjpr08r2 . Ignore any preview errors, and just download. Also, you are not required to log into box.net/files first.
I tried to test the formulas extensively. Their results seem to be consistent with Excel ODDLPRICE. If you find an example that does not work, I would be happy to investigate it.
[Update: I do find differences with some combinations of dates, frequency and day-count basis. I believe the disparity has to do with date calculations involving leap years in the Excel ODDLPRICE and COUP* functions. When I manipulate the dates to avoid leap years and quasi-coup dates in or at the end of Feb, my results agree with Excel ODDLPRICE for the same frequency and day-count basis combinations.]
-----
[I have never been able to get the HTML tool to work. So I cannot create tables. Refer to the "ODDLPRICE (2)" worksheet in the Excel file.]
First, it is important to understand an arbitrary limitation of ODDLPRICE, namely: maturity > settlement > last coupon (paid). This simplifies the PV calculation insofar as there is only one payment (at maturity). That is why there is only one discount term in the mathematical formula that you found.
In contrast, if we allow for last coupon > settlement, there would be multiple discount terms, similar to NPV. For example, see http://westclintech.com/Blog/tabid/1...st-Coupon.aspx .
Second, the following is an improved description of the variables in the mathematical formula that you found:
The "i" refers to the quasi-coup period number following the last coupon (paid).
However, I cannot see any reason for NLi. I believe it should be the same for all periods. Therefore, I use a constant "NL".
[Update: In hindsight, that might be the reason why my calculation does not agree with Excel ODDLPRICE when leap years are involved. Arguably, NLi might be different for periods including Feb for some combinations of frequency and day-count basis. "The refinement is left as an exercise for the student". (wink)]
The following discussion is for your Example #1. Similar forumlas apply to your Example #2.
You had set up the following input values:
I set up the following additional helper values:
Note the "creative" interpretation of the "settlement" and "maturity" parameters for the COUP* functions. That is the key to the correct calculations of those values and dates for all combinations of frequency and day-count basis.
An important difference with ODDLPRICE calculations is: coup dates are determined forward from last coup date, not back from maturity date. This is because with an odd last period, the maturity date is typically not a regular coupon date (unlike your example).
In contrast, with other bond calculations and with Excel bond functions, the maturity date is assumed to be a regular coupon date. Consequently, other coupon dates can be calculated by counting back from the maturity date, depending on the day-count basis.
That difference is reflected in B13: we need to determine the end of the quasi-coupon period that contains the maturity date. Ostensibly, that is determined by treating the maturity date as the "settlement" date in the COUPNCD function, and by creating a fictitious "maturity" date, which is the last-coup date in the year following the maturity date. The COUPPCD(COUPNCD)=B4 logic handles the special case when the maturity date is a regular coupon date.
The following demonstrates my ODDLPRICE calculation. It relies on a table of helper cells in A25:E57, described below.
"Num" (numerator), "denom" (denominator) and "accr int" (accrued interest) refer to the terms of the mathematical formula that you found.
The real "magic" is performed in the table below, which determines Ai, DCi and DSCi for each quasi-coup period.
Ai is the number of days of accrued interest between the last coup (paid) date and the settlement date. For the quasi-coup period that contains the settlement date, it is the number of days between the previous quasi-coup date and the settlement date. Otherwise, Ai is the full number of days in quasi-coup periods before the settlement period; and it is zero for quasi-coup periods after the settlement period.
DCi is the total number of days of interest (including accrued interest) between the last coup (paid) date and the maturity date. For the quasi-coup period that contains the maturity date, it is the number of days between the previous quasi-coup date and the maturity date. (We must make a special case for when the maturity date is a quasi-coup date, due to an arbitrary limitation of COUPDAYBS.) Otherwise, DCi is the full number of days in each quasi-coup period.
DSCI is the number of days that the payment at maturity is discounted back to the settlement date. Ostensibly, it is the full number of days in quasi-coup periods between the settlement and maturity periods. For the settlement period, DCi is the number of days between the settlement date and the next quasi-coup date. For the maturity period, it is the number of days between the previous quasi-coup date and the maturity date. A special case arises when the settlement and maturity dates are in the same quasi-coup period. The construction of the DCi calculation handles both the normal and the special cases automagically.
SIGN(...)+2 results in the CHOOSE indexes 1, 2 and 3 for the conditions B25<B14, B25=B14 and B25>B14 respectively.
I hope that helps to understand how the Excel ODDLPRICE implements the mathematical formula, at least conceptually.
(I do not have any knowledge about how Excel ODDLPRICE is actually implemented.)
Bookmarks