ODDFYIELD
Quirk foundCategory: Financial · Last tested 2026-09-01
Real compatibility results for the ODDFYIELD function: executed in Excel for the web, Google Sheets and LibreOffice Calc, with desktop Excel behavior from Microsoft’s official documentation (we do not run desktop Excel — Excel for the web is a different application and is executed separately). Syntax and links to that documentation are below.
Support matrix
| Engine | Documented | Live-tested | Verdict |
|---|---|---|---|
| Excel (desktop) | Yes | No — documented only | n/a |
| Excel for the web | — | Yes (recalc, 2026-09-01) | Supported, behaves as documented |
| Google Sheets | No | Yes (Drive import, 2026-08-31) | Unsupported (not recognized) |
| LibreOffice Calc | Yes | Yes (25.8.7.3, 2026-08-31) | Quirk found |
LibreOffice version history
We executed the same test cases under each LibreOffice release to show exactly when ODDFYIELD’s support changed — not documentation claims, real results.
| LibreOffice version | Verdict | Tested |
|---|---|---|
| 24.2.0.3 | Quirk found | 2026-08-31 |
| 24.8.7.2 | Quirk found | 2026-08-31 |
| 25.2.0.3 | Quirk found | 2026-08-31 |
| 25.8.7.3 | Quirk found | 2026-08-31 |
Why isn't ODDFYIELD working in LibreOffice?
ODDFYIELD exists in LibreOffice 25.8.7.3, but it is not a drop-in match for
Excel — our executed tests found real behavioral differences (detailed in the test results on this
page). If a formula that works in Excel or Google Sheets misbehaves in LibreOffice, compare your usage
against the failing cases above before assuming your data is wrong.
Why isn’t ODDFYIELD working in Google Sheets?
Google Sheets does not implement ODDFYIELD: we imported the formula into
Sheets on 2026-08-31 and every case came back #NAME?
(unrecognized function). Sheets is a rolling service with no version to pin, so this is a
statement about the service on that date, and Google’s own
function list does not document it either. Rewrite the formula with a documented
Sheets equivalent — see the
Excel ↔ Sheets equivalents table.
Discovered quirks
-
=ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),4) on
Google Sheets returned
#NAME?, but the documented/expected
result is 0.0772.
Provenance
Microsoft publishes =ODDFYIELD(A2, A3, A4, A5, A6, A7, A8, A9, A10) = 7.72% for a bond settled 2008-11-11, maturing 2021-03-01, issued 2008-10-15, first coupon 2009-03-01, 5.75% coupon, price 84.50, redemption 100, semiannual, 30/360 basis, and the page's own description spells the same figure as "(0.0772, or 7.72%)". DERIVATION: Microsoft publishes no closed form -- "Excel uses an iterative technique to calculate ODDFYIELD. This function uses the Newton method based on the formula used for the function ODDFPRICE" -- so the value here is obtained by root-finding on this batch's own clean-room ODDFPRICE implementation (see data/tests/ODDFPRICE.json for its derivation), solving price(yield) = 84.5 with mpmath at 50 digits. The root is 0.07724554159781..., which is 0.0772 at four places -- Microsoft's published figure. Microsoft's page was re-read live on 2026-08-31 at https://support.microsoft.com/en-us/excel/functions/oddfyield-function (the /en-us/office/<name>-function-<guid> path was returning Microsoft's 'Sorry, the page you're looking for can't be found' body throughout this batch, and the working path serves an 87 KB stub about half the time, so pages were fetched with retries until the payload exceeded 150 KB). EXECUTED RESULT -- NOT IMPLEMENTED, AND NOT SIGNALLED AS SUCH: LibreOffice returns #VALUE! on all four pinned builds (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3), which agree case for case -- for this case, for every other case in this file, and for every argument combination probed while preparing the batch (five bases, three frequencies, settlement before and after the first coupon, dates as serials, as DATE() calls and as text, and a bond whose first period is deliberately regular). Not one input produced a number. The name is RECOGNISED -- the plain spelling parses, while _xlfn.ODDFPRICE, COM.MICROSOFT.ODDFPRICE and ORG.OPENOFFICE.ODDFPRICE are all #NAME? -- so this is not a storage-form artefact, and it is not an .xlsx import artefact either: the same #VALUE! comes back when the formula is parsed natively by LibreOffice's own parser rather than read from OOXML, on a run where ODDLPRICE and PRICE in the same file computed correctly. LibreOffice's source says why, in as many words: scaddins/source/analysis/analysishelper.cxx defines GetOddfyield() and GetOddfprice() as bodies that do nothing but `throw uno::RuntimeException()`, and financial.cxx wraps both call sites in SAL_WNOUNREACHABLE_CODE_PUSH under the comment "Encapsulation violation: We *know* that GetOddfprice() always throws." The argument validation in front of them is real (rate < 0, frequency, date ordering are all checked) but every path that survives it ends in the same exception, which is why the error cases in this file also come back #VALUE! instead of the documented #NUM!. So: the function is listed, documented in LibreOffice's own help, and computes nothing. Its ODDL* siblings, by contrast, compute the documented values exactly.; MISMATCH vs expected: expected 0.0772, got '#NAME?'
-
=ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),8) on
Google Sheets returned
#NAME?, but the documented/expected
result is 0.07724554.
Provenance
Four published decimals leave the iteration untested, so the root is asserted at eight places: 0.07724554. Microsoft states the convergence rule loosely -- "The yield is changed through 100 iterations until the estimated price with the given yield is close to the price" -- without defining "close", so this is exactly the kind of case where two conforming implementations can legitimately differ in the last digit or two; eight places is deliberately short of the fifteen a double carries.; MISMATCH vs expected: expected 0.07724554, got '#NAME?'
-
=ROUND(ODDFYIELD(A2,A3,A4,A5,0.0785,ODDFPRICE(A2,A3,A4,A5,0.0785,0.0625,100,2,1),100,2,1),8) on
Google Sheets returned
#NAME?, but the documented/expected
result is 0.0625.
Provenance
Microsoft's page says outright that ODDFYIELD inverts ODDFPRICE ("See ODDFPRICE for the formula that ODDFYIELD uses"), so composing the two on one bond must return the yield it started from. This assertion contains NO derived constant -- 0.0625 is an input -- which makes it immune to any disagreement about day counts or quasi-coupon schedules: an engine with an unusual but self-consistent odd-period model still passes, and one whose yield solver does not invert its own price function fails. The bond is ODDFPRICE's documented example (7.85% coupon, basis 1), evaluated entirely inside the engine.; MISMATCH vs expected: expected 0.0625, got '#NAME?'
-
=ODDFYIELD(A2,A3,A4,A5,A6,0,A8,A9,A10) on
Google Sheets returned
#NAME?, but the documented/expected
result is #NUM!.
Provenance
Microsoft documents: "If rate < 0 or if pr <= 0, ODDFYIELD returns the #NUM! error value." Note the asymmetry with ODDFPRICE, whose corresponding clause reads "rate < 0 or yld < 0": the price argument is excluded AT zero, the yield argument only BELOW it. Zero is the boundary the <= includes.; MISMATCH vs expected: expected '#NUM!', got '#NAME?'
-
=ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,5) on
Google Sheets returned
#NAME?, but the documented/expected
result is #NUM!.
Provenance
Microsoft documents: "If basis < 0 or if basis > 4, ODDFYIELD returns the #NUM! error value."; MISMATCH vs expected: expected '#NUM!', got '#NAME?'
-
=ODDFYIELD(A5,A3,A4,A2,A6,A7,A8,A9,A10) on
Google Sheets returned
#NAME?, but the documented/expected
result is #NUM!.
Provenance
Microsoft documents: "The following date condition must be satisfied; otherwise, ODDFYIELD returns the #NUM! error value: maturity > first_coupon > settlement > issue."; MISMATCH vs expected: expected '#NUM!', got '#NAME?'
-
=ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),4) on
LibreOffice Calc returned
#VALUE!, but the documented/expected
result is 0.0772.
Provenance
Microsoft publishes =ODDFYIELD(A2, A3, A4, A5, A6, A7, A8, A9, A10) = 7.72% for a bond settled 2008-11-11, maturing 2021-03-01, issued 2008-10-15, first coupon 2009-03-01, 5.75% coupon, price 84.50, redemption 100, semiannual, 30/360 basis, and the page's own description spells the same figure as "(0.0772, or 7.72%)". DERIVATION: Microsoft publishes no closed form -- "Excel uses an iterative technique to calculate ODDFYIELD. This function uses the Newton method based on the formula used for the function ODDFPRICE" -- so the value here is obtained by root-finding on this batch's own clean-room ODDFPRICE implementation (see data/tests/ODDFPRICE.json for its derivation), solving price(yield) = 84.5 with mpmath at 50 digits. The root is 0.07724554159781..., which is 0.0772 at four places -- Microsoft's published figure. Microsoft's page was re-read live on 2026-08-31 at https://support.microsoft.com/en-us/excel/functions/oddfyield-function (the /en-us/office/<name>-function-<guid> path was returning Microsoft's 'Sorry, the page you're looking for can't be found' body throughout this batch, and the working path serves an 87 KB stub about half the time, so pages were fetched with retries until the payload exceeded 150 KB). EXECUTED RESULT -- NOT IMPLEMENTED, AND NOT SIGNALLED AS SUCH: LibreOffice returns #VALUE! on all four pinned builds (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3), which agree case for case -- for this case, for every other case in this file, and for every argument combination probed while preparing the batch (five bases, three frequencies, settlement before and after the first coupon, dates as serials, as DATE() calls and as text, and a bond whose first period is deliberately regular). Not one input produced a number. The name is RECOGNISED -- the plain spelling parses, while _xlfn.ODDFPRICE, COM.MICROSOFT.ODDFPRICE and ORG.OPENOFFICE.ODDFPRICE are all #NAME? -- so this is not a storage-form artefact, and it is not an .xlsx import artefact either: the same #VALUE! comes back when the formula is parsed natively by LibreOffice's own parser rather than read from OOXML, on a run where ODDLPRICE and PRICE in the same file computed correctly. LibreOffice's source says why, in as many words: scaddins/source/analysis/analysishelper.cxx defines GetOddfyield() and GetOddfprice() as bodies that do nothing but `throw uno::RuntimeException()`, and financial.cxx wraps both call sites in SAL_WNOUNREACHABLE_CODE_PUSH under the comment "Encapsulation violation: We *know* that GetOddfprice() always throws." The argument validation in front of them is real (rate < 0, frequency, date ordering are all checked) but every path that survives it ends in the same exception, which is why the error cases in this file also come back #VALUE! instead of the documented #NUM!. So: the function is listed, documented in LibreOffice's own help, and computes nothing. Its ODDL* siblings, by contrast, compute the documented values exactly.; MISMATCH vs expected: expected 0.0772, got '#VALUE!'
-
=ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),8) on
LibreOffice Calc returned
#VALUE!, but the documented/expected
result is 0.07724554.
Provenance
Four published decimals leave the iteration untested, so the root is asserted at eight places: 0.07724554. Microsoft states the convergence rule loosely -- "The yield is changed through 100 iterations until the estimated price with the given yield is close to the price" -- without defining "close", so this is exactly the kind of case where two conforming implementations can legitimately differ in the last digit or two; eight places is deliberately short of the fifteen a double carries.; MISMATCH vs expected: expected 0.07724554, got '#VALUE!'
-
=ROUND(ODDFYIELD(A2,A3,A4,A5,0.0785,ODDFPRICE(A2,A3,A4,A5,0.0785,0.0625,100,2,1),100,2,1),8) on
LibreOffice Calc returned
#VALUE!, but the documented/expected
result is 0.0625.
Provenance
Microsoft's page says outright that ODDFYIELD inverts ODDFPRICE ("See ODDFPRICE for the formula that ODDFYIELD uses"), so composing the two on one bond must return the yield it started from. This assertion contains NO derived constant -- 0.0625 is an input -- which makes it immune to any disagreement about day counts or quasi-coupon schedules: an engine with an unusual but self-consistent odd-period model still passes, and one whose yield solver does not invert its own price function fails. The bond is ODDFPRICE's documented example (7.85% coupon, basis 1), evaluated entirely inside the engine.; MISMATCH vs expected: expected 0.0625, got '#VALUE!'
-
=ODDFYIELD(A2,A3,A4,A5,A6,0,A8,A9,A10) on
LibreOffice Calc returned
#VALUE!, but the documented/expected
result is #NUM!.
Provenance
Microsoft documents: "If rate < 0 or if pr <= 0, ODDFYIELD returns the #NUM! error value." Note the asymmetry with ODDFPRICE, whose corresponding clause reads "rate < 0 or yld < 0": the price argument is excluded AT zero, the yield argument only BELOW it. Zero is the boundary the <= includes.; MISMATCH vs expected: expected '#NUM!', got '#VALUE!'
-
=ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,5) on
LibreOffice Calc returned
#VALUE!, but the documented/expected
result is #NUM!.
Provenance
Microsoft documents: "If basis < 0 or if basis > 4, ODDFYIELD returns the #NUM! error value."; MISMATCH vs expected: expected '#NUM!', got '#VALUE!'
-
=ODDFYIELD(A5,A3,A4,A2,A6,A7,A8,A9,A10) on
LibreOffice Calc returned
#VALUE!, but the documented/expected
result is #NUM!.
Provenance
Microsoft documents: "The following date condition must be satisfied; otherwise, ODDFYIELD returns the #NUM! error value: maturity > first_coupon > settlement > issue."; MISMATCH vs expected: expected '#NUM!', got '#VALUE!'
Executed test cases
Excel for the web (executed 2026-09-01 via OneDrive recalculation)
These values come from Excel for the web, not from desktop Excel. They are two different implementations of the calculation engine, and this run measured only the web one: the corpus was uploaded to OneDrive as .xlsx, recalculated by Excel for the web on open, and downloaded again for readback. Excel for the web is a rolling service with no pinnable version, so the run is identified by its date. Where a value here disagrees with the Expected column — which is Microsoft’s documentation of the desktop product — we cannot tell you whether the web engine diverges from the desktop one or the documentation is wrong about both, because we do not run desktop Excel.
| Formula | Description | Result | Expected | Verdict |
|---|---|---|---|---|
| =ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),4) | Microsoft's documented worked example, at the precision Microsoft publishes | 0.0772 | 0.0772ProvenanceMicrosoft publishes =ODDFYIELD(A2, A3, A4, A5, A6, A7, A8, A9, A10) = 7.72% for a bond settled 2008-11-11, maturing 2021-03-01, issued 2008-10-15, first coupon 2009-03-01, 5.75% coupon, price 84.50, redemption 100, semiannual, 30/360 basis, and the page's own description spells the same figure as "(0.0772, or 7.72%)". DERIVATION: Microsoft publishes no closed form -- "Excel uses an iterative technique to calculate ODDFYIELD. This function uses the Newton method based on the formula used for the function ODDFPRICE" -- so the value here is obtained by root-finding on this batch's own clean-room ODDFPRICE implementation (see data/tests/ODDFPRICE.json for its derivation), solving price(yield) = 84.5 with mpmath at 50 digits. The root is 0.07724554159781..., which is 0.0772 at four places -- Microsoft's published figure. Microsoft's page was re-read live on 2026-08-31 at https://support.microsoft.com/en-us/excel/functions/oddfyield-function (the /en-us/office/<name>-function-<guid> path was returning Microsoft's 'Sorry, the page you're looking for can't be found' body throughout this batch, and the working path serves an 87 KB stub about half the time, so pages were fetched with retries until the payload exceeded 150 KB). EXECUTED RESULT -- NOT IMPLEMENTED, AND NOT SIGNALLED AS SUCH: LibreOffice returns #VALUE! on all four pinned builds (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3), which agree case for case -- for this case, for every other case in this file, and for every argument combination probed while preparing the batch (five bases, three frequencies, settlement before and after the first coupon, dates as serials, as DATE() calls and as text, and a bond whose first period is deliberately regular). Not one input produced a number. The name is RECOGNISED -- the plain spelling parses, while _xlfn.ODDFPRICE, COM.MICROSOFT.ODDFPRICE and ORG.OPENOFFICE.ODDFPRICE are all #NAME? -- so this is not a storage-form artefact, and it is not an .xlsx import artefact either: the same #VALUE! comes back when the formula is parsed natively by LibreOffice's own parser rather than read from OOXML, on a run where ODDLPRICE and PRICE in the same file computed correctly. LibreOffice's source says why, in as many words: scaddins/source/analysis/analysishelper.cxx defines GetOddfyield() and GetOddfprice() as bodies that do nothing but `throw uno::RuntimeException()`, and financial.cxx wraps both call sites in SAL_WNOUNREACHABLE_CODE_PUSH under the comment "Encapsulation violation: We *know* that GetOddfprice() always throws." The argument validation in front of them is real (rate < 0, frequency, date ordering are all checked) but every path that survives it ends in the same exception, which is why the error cases in this file also come back #VALUE! instead of the documented #NUM!. So: the function is listed, documented in LibreOffice's own help, and computes nothing. Its ODDL* siblings, by contrast, compute the documented values exactly. |
Matched |
| =ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),8) | The same example carried to eight decimal places | 0.07724554 | 0.07724554ProvenanceFour published decimals leave the iteration untested, so the root is asserted at eight places: 0.07724554. Microsoft states the convergence rule loosely -- "The yield is changed through 100 iterations until the estimated price with the given yield is close to the price" -- without defining "close", so this is exactly the kind of case where two conforming implementations can legitimately differ in the last digit or two; eight places is deliberately short of the fifteen a double carries. |
Matched |
| =ROUND(ODDFYIELD(A2,A3,A4,A5,0.0785,ODDFPRICE(A2,A3,A4,A5,0.0785,0.0625,100,2,1),100,2,1),8) | ODDFYIELD fed the price ODDFPRICE computes for a known yield must return that yield | 0.0625 | 0.0625ProvenanceMicrosoft's page says outright that ODDFYIELD inverts ODDFPRICE ("See ODDFPRICE for the formula that ODDFYIELD uses"), so composing the two on one bond must return the yield it started from. This assertion contains NO derived constant -- 0.0625 is an input -- which makes it immune to any disagreement about day counts or quasi-coupon schedules: an engine with an unusual but self-consistent odd-period model still passes, and one whose yield solver does not invert its own price function fails. The bond is ODDFPRICE's documented example (7.85% coupon, basis 1), evaluated entirely inside the engine. |
Matched |
| =ODDFYIELD(A2,A3,A4,A5,A6,0,A8,A9,A10) | A price of zero, which the page excludes | #NUM! | #NUM!ProvenanceMicrosoft documents: "If rate < 0 or if pr <= 0, ODDFYIELD returns the #NUM! error value." Note the asymmetry with ODDFPRICE, whose corresponding clause reads "rate < 0 or yld < 0": the price argument is excluded AT zero, the yield argument only BELOW it. Zero is the boundary the <= includes. |
Matched |
| =ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,5) | A basis of 5, one past the documented range | #NUM! | #NUM!ProvenanceMicrosoft documents: "If basis < 0 or if basis > 4, ODDFYIELD returns the #NUM! error value." |
Matched |
| =ODDFYIELD(A5,A3,A4,A2,A6,A7,A8,A9,A10) | Settlement and first_coupon swapped | #NUM! | #NUM!ProvenanceMicrosoft documents: "The following date condition must be satisfied; otherwise, ODDFYIELD returns the #NUM! error value: maturity > first_coupon > settlement > issue." |
Matched |
Google Sheets (executed 2026-08-31 via Drive import)
Google Sheets is a rolling service with no pinnable version, so this run is identified by its date. The corpus was imported to Drive as .xlsx, recalculated by Sheets, and exported back for readback.
| Formula | Description | Result | Expected | Verdict |
|---|---|---|---|---|
| =ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),4) | Microsoft's documented worked example, at the precision Microsoft publishes | #NAME? | 0.0772ProvenanceMicrosoft publishes =ODDFYIELD(A2, A3, A4, A5, A6, A7, A8, A9, A10) = 7.72% for a bond settled 2008-11-11, maturing 2021-03-01, issued 2008-10-15, first coupon 2009-03-01, 5.75% coupon, price 84.50, redemption 100, semiannual, 30/360 basis, and the page's own description spells the same figure as "(0.0772, or 7.72%)". DERIVATION: Microsoft publishes no closed form -- "Excel uses an iterative technique to calculate ODDFYIELD. This function uses the Newton method based on the formula used for the function ODDFPRICE" -- so the value here is obtained by root-finding on this batch's own clean-room ODDFPRICE implementation (see data/tests/ODDFPRICE.json for its derivation), solving price(yield) = 84.5 with mpmath at 50 digits. The root is 0.07724554159781..., which is 0.0772 at four places -- Microsoft's published figure. Microsoft's page was re-read live on 2026-08-31 at https://support.microsoft.com/en-us/excel/functions/oddfyield-function (the /en-us/office/<name>-function-<guid> path was returning Microsoft's 'Sorry, the page you're looking for can't be found' body throughout this batch, and the working path serves an 87 KB stub about half the time, so pages were fetched with retries until the payload exceeded 150 KB). EXECUTED RESULT -- NOT IMPLEMENTED, AND NOT SIGNALLED AS SUCH: LibreOffice returns #VALUE! on all four pinned builds (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3), which agree case for case -- for this case, for every other case in this file, and for every argument combination probed while preparing the batch (five bases, three frequencies, settlement before and after the first coupon, dates as serials, as DATE() calls and as text, and a bond whose first period is deliberately regular). Not one input produced a number. The name is RECOGNISED -- the plain spelling parses, while _xlfn.ODDFPRICE, COM.MICROSOFT.ODDFPRICE and ORG.OPENOFFICE.ODDFPRICE are all #NAME? -- so this is not a storage-form artefact, and it is not an .xlsx import artefact either: the same #VALUE! comes back when the formula is parsed natively by LibreOffice's own parser rather than read from OOXML, on a run where ODDLPRICE and PRICE in the same file computed correctly. LibreOffice's source says why, in as many words: scaddins/source/analysis/analysishelper.cxx defines GetOddfyield() and GetOddfprice() as bodies that do nothing but `throw uno::RuntimeException()`, and financial.cxx wraps both call sites in SAL_WNOUNREACHABLE_CODE_PUSH under the comment "Encapsulation violation: We *know* that GetOddfprice() always throws." The argument validation in front of them is real (rate < 0, frequency, date ordering are all checked) but every path that survives it ends in the same exception, which is why the error cases in this file also come back #VALUE! instead of the documented #NUM!. So: the function is listed, documented in LibreOffice's own help, and computes nothing. Its ODDL* siblings, by contrast, compute the documented values exactly. |
Mismatch |
| =ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),8) | The same example carried to eight decimal places | #NAME? | 0.07724554ProvenanceFour published decimals leave the iteration untested, so the root is asserted at eight places: 0.07724554. Microsoft states the convergence rule loosely -- "The yield is changed through 100 iterations until the estimated price with the given yield is close to the price" -- without defining "close", so this is exactly the kind of case where two conforming implementations can legitimately differ in the last digit or two; eight places is deliberately short of the fifteen a double carries. |
Mismatch |
| =ROUND(ODDFYIELD(A2,A3,A4,A5,0.0785,ODDFPRICE(A2,A3,A4,A5,0.0785,0.0625,100,2,1),100,2,1),8) | ODDFYIELD fed the price ODDFPRICE computes for a known yield must return that yield | #NAME? | 0.0625ProvenanceMicrosoft's page says outright that ODDFYIELD inverts ODDFPRICE ("See ODDFPRICE for the formula that ODDFYIELD uses"), so composing the two on one bond must return the yield it started from. This assertion contains NO derived constant -- 0.0625 is an input -- which makes it immune to any disagreement about day counts or quasi-coupon schedules: an engine with an unusual but self-consistent odd-period model still passes, and one whose yield solver does not invert its own price function fails. The bond is ODDFPRICE's documented example (7.85% coupon, basis 1), evaluated entirely inside the engine. |
Mismatch |
| =ODDFYIELD(A2,A3,A4,A5,A6,0,A8,A9,A10) | A price of zero, which the page excludes | #NAME? | #NUM!ProvenanceMicrosoft documents: "If rate < 0 or if pr <= 0, ODDFYIELD returns the #NUM! error value." Note the asymmetry with ODDFPRICE, whose corresponding clause reads "rate < 0 or yld < 0": the price argument is excluded AT zero, the yield argument only BELOW it. Zero is the boundary the <= includes. |
Mismatch |
| =ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,5) | A basis of 5, one past the documented range | #NAME? | #NUM!ProvenanceMicrosoft documents: "If basis < 0 or if basis > 4, ODDFYIELD returns the #NUM! error value." |
Mismatch |
| =ODDFYIELD(A5,A3,A4,A2,A6,A7,A8,A9,A10) | Settlement and first_coupon swapped | #NAME? | #NUM!ProvenanceMicrosoft documents: "The following date condition must be satisfied; otherwise, ODDFYIELD returns the #NUM! error value: maturity > first_coupon > settlement > issue." |
Mismatch |
LibreOffice Calc 25.8.7.3 (tested 2026-08-31)
| Formula | Description | Result | Expected | Verdict |
|---|---|---|---|---|
| =ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),4) | Microsoft's documented worked example, at the precision Microsoft publishes | #VALUE! | 0.0772ProvenanceMicrosoft publishes =ODDFYIELD(A2, A3, A4, A5, A6, A7, A8, A9, A10) = 7.72% for a bond settled 2008-11-11, maturing 2021-03-01, issued 2008-10-15, first coupon 2009-03-01, 5.75% coupon, price 84.50, redemption 100, semiannual, 30/360 basis, and the page's own description spells the same figure as "(0.0772, or 7.72%)". DERIVATION: Microsoft publishes no closed form -- "Excel uses an iterative technique to calculate ODDFYIELD. This function uses the Newton method based on the formula used for the function ODDFPRICE" -- so the value here is obtained by root-finding on this batch's own clean-room ODDFPRICE implementation (see data/tests/ODDFPRICE.json for its derivation), solving price(yield) = 84.5 with mpmath at 50 digits. The root is 0.07724554159781..., which is 0.0772 at four places -- Microsoft's published figure. Microsoft's page was re-read live on 2026-08-31 at https://support.microsoft.com/en-us/excel/functions/oddfyield-function (the /en-us/office/<name>-function-<guid> path was returning Microsoft's 'Sorry, the page you're looking for can't be found' body throughout this batch, and the working path serves an 87 KB stub about half the time, so pages were fetched with retries until the payload exceeded 150 KB). EXECUTED RESULT -- NOT IMPLEMENTED, AND NOT SIGNALLED AS SUCH: LibreOffice returns #VALUE! on all four pinned builds (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3), which agree case for case -- for this case, for every other case in this file, and for every argument combination probed while preparing the batch (five bases, three frequencies, settlement before and after the first coupon, dates as serials, as DATE() calls and as text, and a bond whose first period is deliberately regular). Not one input produced a number. The name is RECOGNISED -- the plain spelling parses, while _xlfn.ODDFPRICE, COM.MICROSOFT.ODDFPRICE and ORG.OPENOFFICE.ODDFPRICE are all #NAME? -- so this is not a storage-form artefact, and it is not an .xlsx import artefact either: the same #VALUE! comes back when the formula is parsed natively by LibreOffice's own parser rather than read from OOXML, on a run where ODDLPRICE and PRICE in the same file computed correctly. LibreOffice's source says why, in as many words: scaddins/source/analysis/analysishelper.cxx defines GetOddfyield() and GetOddfprice() as bodies that do nothing but `throw uno::RuntimeException()`, and financial.cxx wraps both call sites in SAL_WNOUNREACHABLE_CODE_PUSH under the comment "Encapsulation violation: We *know* that GetOddfprice() always throws." The argument validation in front of them is real (rate < 0, frequency, date ordering are all checked) but every path that survives it ends in the same exception, which is why the error cases in this file also come back #VALUE! instead of the documented #NUM!. So: the function is listed, documented in LibreOffice's own help, and computes nothing. Its ODDL* siblings, by contrast, compute the documented values exactly. |
Mismatch |
| =ROUND(ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,A10),8) | The same example carried to eight decimal places | #VALUE! | 0.07724554ProvenanceFour published decimals leave the iteration untested, so the root is asserted at eight places: 0.07724554. Microsoft states the convergence rule loosely -- "The yield is changed through 100 iterations until the estimated price with the given yield is close to the price" -- without defining "close", so this is exactly the kind of case where two conforming implementations can legitimately differ in the last digit or two; eight places is deliberately short of the fifteen a double carries. |
Mismatch |
| =ROUND(ODDFYIELD(A2,A3,A4,A5,0.0785,ODDFPRICE(A2,A3,A4,A5,0.0785,0.0625,100,2,1),100,2,1),8) | ODDFYIELD fed the price ODDFPRICE computes for a known yield must return that yield | #VALUE! | 0.0625ProvenanceMicrosoft's page says outright that ODDFYIELD inverts ODDFPRICE ("See ODDFPRICE for the formula that ODDFYIELD uses"), so composing the two on one bond must return the yield it started from. This assertion contains NO derived constant -- 0.0625 is an input -- which makes it immune to any disagreement about day counts or quasi-coupon schedules: an engine with an unusual but self-consistent odd-period model still passes, and one whose yield solver does not invert its own price function fails. The bond is ODDFPRICE's documented example (7.85% coupon, basis 1), evaluated entirely inside the engine. |
Mismatch |
| =ODDFYIELD(A2,A3,A4,A5,A6,0,A8,A9,A10) | A price of zero, which the page excludes | #VALUE! | #NUM!ProvenanceMicrosoft documents: "If rate < 0 or if pr <= 0, ODDFYIELD returns the #NUM! error value." Note the asymmetry with ODDFPRICE, whose corresponding clause reads "rate < 0 or yld < 0": the price argument is excluded AT zero, the yield argument only BELOW it. Zero is the boundary the <= includes. |
Mismatch |
| =ODDFYIELD(A2,A3,A4,A5,A6,A7,A8,A9,5) | A basis of 5, one past the documented range | #VALUE! | #NUM!ProvenanceMicrosoft documents: "If basis < 0 or if basis > 4, ODDFYIELD returns the #NUM! error value." |
Mismatch |
| =ODDFYIELD(A5,A3,A4,A2,A6,A7,A8,A9,A10) | Settlement and first_coupon swapped | #VALUE! | #NUM!ProvenanceMicrosoft documents: "The following date condition must be satisfied; otherwise, ODDFYIELD returns the #NUM! error value: maturity > first_coupon > settlement > issue." |
Mismatch |
Docs & syntax
- Excel (desktop): official documentation
- LibreOffice Calc: official documentation
Where ODDFYIELD behaves differently
- Bond and treasury functions after a migration: what actually breaks
Executed across 26 fixed-income functions and 161 cases: ODDFPRICE and ODDFYIELD are literal stubs in LibreOffice, TBILLPRICE prices a two-year bill, INTRATE's default basis loses a day, and MDURATION is wrong on actual/actual. 83 of 84 documented #NUM! cases arrive as #VALUE!. Google Sheets matched 127 of 161.