Financial functions

ODDFYIELD

Known larger differences on 44 of 92 recorded answers

Of 92 recorded answers (92 workbook cells), 44 do not match: 30 differ by more than 16 ULP, 14 differ in kind or value. How we measure this · See the Rust code

Local names in 40 languages
LanguageName in Excel
ArabicODDFYIELD
BulgarianODDFYIELD
CzechODDFYIELD
DanishULIGE.FØRSTE.AFKAST
GermanODDFYIELD
GreekODDFYIELD
English (Australia)ODDFYIELD
English (United Kingdom)ODDFYIELD
English (United States)ODDFYIELD
SpanishRENDTO.PER.IRREGULAR.1
EstonianODDFYIELD
FinnishPARITON.ENS.TUOTTO
FrenchREND.PCOUPON.IRREG
HebrewODDFYIELD
CroatianODDFYIELD
HungarianELTÉRŐ.EHOZAM
IndonesianODDFYIELD
ItalianODDFYIELD
JapaneseODDFYIELD
KoreanODDFYIELD
LithuanianODDFYIELD
LatvianODDFYIELD
NorwegianAVVIKFP.AVKASTNING
DutchAFW.ET.REND
PolishRENT.PIERW.OKR
Portuguese (Brazil)ODDFYIELD
Portuguese (Portugal)LUCROPRIMINC
RomanianODDFYIELD
RussianДОХОДПЕРВНЕРЕГ
SlovakODDFYIELD
SlovenianODDFYIELD
Serbian (Latin)ODDFYIELD
SwedishUDDAFAVKASTNING
ThaiODDFYIELD
TurkishTEKYÖDEME işlevi
UkrainianODDFYIELD
VietnameseODDFYIELD
Chinese (Simplified)ODDFYIELD
Chinese (Hong Kong)ODDFYIELD
Chinese (Traditional)ODDFYIELD

Names from Microsoft's support site.

What it does

ODDFYIELD(settlement, maturity, issue, first_coupon, rate, pr, redemption, frequency, [basis])

ODDFYIELD solves annual yield from price for a security with an irregular first coupon. Its dates are settlement, maturity, issue and first_coupon. They are followed by coupon rate, price, redemption, frequency and optional basis.

Try it

Input cells (optional)

Example: {"B2": 3, "B3": 4}. A1 holds the formula. Other cells need values before a formula can read them.

Enter a formula, then calculate.

Runs locally in your browser with OneCalc. Its answer may differ from Excel. Use English function names and commas between arguments.

=ODDFYIELD(DATE(2027,2,1),DATE(2027,10,1),DATE(2027,1,1),DATE(2027,4,1),0.06,104,100,2,0) gives a yield near zero. The first coupon spans January to April, a short half-year coupon. Under 30/360 its payment is 1.5; the regular maturity coupon is three; accrued interest at February settlement is 0.5. At zero yield the clean price is 100+1.5+3-0.5=104.

Quirks

Basis defaults to zero: 0 US 30/360, 1 actual/actual, 2 actual/360, 3 actual/365, 4 European 30/360. Dates and selectors are truncated under their documented rules. Use DATE values rather than locale-dependent date text. The required date order is issue < settlement < first_coupon < maturity. Frequency is one, two or four. Negative coupon rate, invalid selectors and invalid amount/domain cases produce errors. These schedules cannot be reduced to PRICE by changing one date.

How to implement

Build the odd-first pricing function over a quasi-coupon calendar, then bracket a yield that reprices the target clean price. The current helper uses bisection, while Microsoft’s page describes a Newton method. Their stopping and boundary results are separate compatibility questions. The worked zero-yield example isolates the coupon and accrual arithmetic from discount powers. Calendar seams, long/short-period branches and residual numerical differences remain open where the recorded reports say so. The family combines a credited Apache-licensed ExcelFinancialFunctions translation in its odd-first kernel and calendar helpers with project-owned kernels and changes guided by recorded Excel answers.

Rust code

Show the CalcFunc source of this function

Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.

ODDFYIELD · 7 lines · calc-func/src/catalogue/bonds.rs on GitHub
24 oddfyield_fn "ODDFYIELD" (8, 9) [V "settlement", V "maturity", V "issue", V "first_coupon", V "rate", V "pr", V "redemption", V "frequency", V "basis"] |s, a, sv| {
    let dates = [yield_date(s, a, 0, sv)?, yield_date(s, a, 1, sv)?, yield_date(s, a, 2, sv)?, yield_date(s, a, 3, sv)?];
    let (rate, price, redemption, frequency) = (required_num(s, a, 4)?, required_num(s, a, 5)?, required_num(s, a, 6)?, required_num(s, a, 7)?);
    // ODDFYIELD keeps frequency before basis, unlike YIELD.
    let basis = if a.len() > 8 { Some(num_without_logical(s, a, 8)?) } else { None };
    odd_out(s, odd::oddfyield_kernel(dates[0], dates[1], dates[2], dates[3], rate, price, redemption, frequency, basis))
}
solve_yield_bisection · 51 lines · calc-func/src/ported/odd_bond_family.rs on GitHub
fn solve_yield_bisection(
    target_price: f64,
    price_at_yield: impl Fn(f64) -> Result<f64, OddBondEvalError>,
) -> Result<f64, OddBondEvalError> {
    if target_price <= 0.0 || !target_price.is_finite() {
        return Err(OddBondEvalError::Domain(WorksheetErrorCode::Num));
    }
    let low = 0.0;
    let price_low = price_at_yield(low)?;
    if target_price > price_low {
        return Err(OddBondEvalError::Domain(WorksheetErrorCode::Num));
    }
    let mut hi = 0.1;
    let mut price_hi = price_at_yield(hi)?;
    for _ in 0..32 {
        if price_hi <= target_price {
            break;
        }
        hi *= 2.0;
        price_hi = price_at_yield(hi)?;
    }
    if price_hi > target_price {
        return Err(OddBondEvalError::Domain(WorksheetErrorCode::Num));
    }

    // Bisection to adjacent binary64 bounds (full convergence, dc-ifc: Excel's ODDFYIELD
    // converges past the former 1e-12 price tolerance), then the bound with the smaller residual.
    let mut lo = low;
    let mut hi_mut = hi;
    for _ in 0..2200 {
        let mid = (lo + hi_mut) / 2.0;
        if mid <= lo || mid >= hi_mut {
            break;
        }
        let price_mid = price_at_yield(mid)?;
        if price_mid == target_price {
            return Ok(mid);
        }
        if price_mid > target_price {
            lo = mid;
        } else {
            hi_mut = mid;
        }
    }
    let residual = |y: f64| price_at_yield(y).map(|p| (p - target_price).abs());
    Ok(match (residual(lo), residual(hi_mut)) {
        (Ok(a), Ok(b)) if a < b => lo,
        (Ok(_), Err(_)) => lo,
        _ => hi_mut,
    })
}
oddfyield_kernel · 25 lines · calc-func/src/ported/odd_bond_family.rs on GitHub
pub fn oddfyield_kernel(
    settlement: f64,
    maturity: f64,
    issue: f64,
    first_coupon: f64,
    rate: f64,
    pr: f64,
    redemption: f64,
    frequency: f64,
    basis: Option<f64>,
) -> Result<f64, OddBondEvalError> {
    solve_yield_bisection(pr, |y| {
        oddfprice_kernel(
            settlement,
            maturity,
            issue,
            first_coupon,
            rate,
            y,
            redemption,
            frequency,
            basis,
        )
    })
}

Kernels shared with other functions

Argument and result plumbing

No implementation has been published with a Handbook test suite for this function.

Version differences

No same-input comparison between named Excel builds is recorded for this function here. The documented behaviour below is not a measurement of every Excel release.

Alternatives

ODDFPRICE prices the same first-coupon schedule at a supplied yield. ODDLYIELD handles an irregular final coupon; YIELD handles regular coupons.

Named variants

No named variants are recorded yet.

Suggest a correction or contribute an implementation · For agents