Financial functions
ODDLYIELD
Matches all 6 recorded answers
Recorded: 6 workbook cells. How we measure this · See the Rust code
Local names in 40 languages
| Language | Name in Excel |
|---|---|
| Arabic | ODDLYIELD |
| Bulgarian | ODDLYIELD |
| Czech | ODDLYIELD |
| Danish | ULIGE.SIDSTE.AFKAST |
| German | ODDLYIELD |
| Greek | ODDLYIELD |
| English (Australia) | ODDLYIELD |
| English (United Kingdom) | ODDLYIELD |
| English (United States) | ODDLYIELD |
| Spanish | RENDTO.PER.IRREGULAR.2 |
| Estonian | ODDLYIELD |
| Finnish | PARITON.VIIM.TUOTTO |
| French | REND.DCOUPON.IRREG |
| Hebrew | ODDLYIELD |
| Croatian | ODDLYIELD |
| Hungarian | ELTÉRŐ.UHOZAM |
| Indonesian | ODDLYIELD |
| Italian | ODDLYIELD |
| Japanese | ODDLYIELD |
| Korean | ODDLYIELD |
| Lithuanian | ODDLYIELD |
| Latvian | ODDLYIELD |
| Norwegian | AVVIKSP.AVKASTNING |
| Dutch | AFW.LT.REND |
| Polish | RENT.OST.OKR |
| Portuguese (Brazil) | ODDLYIELD |
| Portuguese (Portugal) | LUCROÚLTINC |
| Romanian | ODDLYIELD |
| Russian | ДОХОДПОСЛНЕРЕГ |
| Slovak | ODDLYIELD |
| Slovenian | ODDLYIELD |
| Serbian (Latin) | ODDLYIELD |
| Swedish | UDDASAVKASTNING |
| Thai | ODDLYIELD |
| Turkish | TEKSÖDEME işlevi |
| Ukrainian | ODDLYIELD |
| Vietnamese | ODDLYIELD |
| Chinese (Simplified) | ODDLYIELD |
| Chinese (Hong Kong) | ODDLYIELD |
| Chinese (Traditional) | ODDLYIELD |
Names from Microsoft's support site.
What it does
ODDLYIELD(settlement, maturity, last_interest, rate, pr, redemption, frequency, [basis])
ODDLYIELD solves annual yield from price for a security with an irregular last coupon. Its dates are settlement, maturity and last_interest. They are followed by coupon rate, price, redemption, frequency and optional basis.
Try it
=ODDLYIELD(DATE(2027,8,1),DATE(2027,11,1),DATE(2027,4,1),0.06,101.5,100,2,0) gives a yield near zero. The last coupon spans April to November, seven 30/360 months. Its coupon is 3.5 and accrued interest at August settlement is two. At zero yield the clean price is 100+3.5-2=101.5.
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 last_interest < settlement < 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 quasi-coupon periods from last_interest, accumulate normalized issue-to-maturity, accrued and remaining fractions, and solve the final simple-discount equation for yield. The current last-yield helper uses a direct algebraic formula rather than the odd-first root solver. 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.
ODDLYIELD · 4 lines · calc-func/src/catalogue/bonds.rs on GitHub26 oddlyield_fn "ODDLYIELD" (7, 8) [V "settlement", V "maturity", V "last_interest", V "rate", V "pr", V "redemption", V "frequency", V "basis"] |s, a, sv| {
let dates = [date_1900(s, a, 0, sv)?, date_1900(s, a, 1, sv)?, date_1900(s, a, 2, sv)?];
odd_out(s, odd::oddlyield_kernel(dates[0], dates[1], dates[2], num(s, a, 3)?, num(s, a, 4)?, num(s, a, 5)?, num(s, a, 6)?, basis(s, a, 7)?))
}
oddlyield_kernel · 81 lines · calc-func/src/ported/odd_bond_family.rs on GitHubpub fn oddlyield_kernel(
settlement: f64,
maturity: f64,
last_interest: f64,
rate: f64,
pr: f64,
redemption: f64,
frequency: f64,
basis: Option<f64>,
) -> Result<f64, OddBondEvalError> {
validate_positive_inputs(&[
settlement,
maturity,
last_interest,
rate,
pr,
redemption,
frequency,
])?;
if rate < 0.0 || pr < 0.0 || redemption <= 0.0 {
return Err(OddBondEvalError::Domain(WorksheetErrorCode::Num));
}
let settlement = parse_date_serial(settlement)?;
let maturity = parse_date_serial(maturity)?;
let last_interest = parse_date_serial(last_interest)?;
let frequency = parse_frequency(frequency)?;
let basis = parse_basis(basis.unwrap_or(0.0))?;
if !(last_interest < settlement && settlement < maturity) {
return Err(OddBondEvalError::Domain(WorksheetErrorCode::Num));
}
let months_per_coupon = 12 / frequency;
let mut nc = 0i64;
let mut cursor = last_interest;
while cursor < maturity {
cursor = add_months_clamped(cursor, months_per_coupon)
.ok_or(OddBondEvalError::Domain(WorksheetErrorCode::Num))?;
nc += 1;
if nc > 64 {
return Err(OddBondEvalError::Domain(WorksheetErrorCode::Num));
}
}
let mut early_coupon = last_interest;
let mut dcnl = 0.0;
let mut anl = 0.0;
let mut dscnl = 0.0;
for index in 1..=nc {
let late_coupon = add_months_clamped(early_coupon, months_per_coupon)
.ok_or(OddBondEvalError::Domain(WorksheetErrorCode::Num))?;
let nl = day_count_non_negative_with_us_hack(early_coupon, late_coupon, basis)?;
if nl <= 0.0 {
return Err(OddBondEvalError::Domain(WorksheetErrorCode::Num));
}
let dci = if index < nc {
nl
} else {
day_count_non_negative_with_us_hack(early_coupon, maturity, basis)?
};
let a = if late_coupon < settlement {
dci
} else if early_coupon < settlement {
day_count_non_negative(early_coupon, settlement, basis)?
} else {
0.0
};
let start_date = settlement.max(early_coupon);
let end_date = maturity.min(late_coupon);
let dsc = day_count_non_negative(start_date, end_date, basis)?;
early_coupon = late_coupon;
dcnl += dci / nl;
anl += a / nl;
dscnl += dsc / nl;
}
if dscnl <= 0.0 {
return Err(OddBondEvalError::Domain(WorksheetErrorCode::Num));
}
let x = 100.0 * rate / frequency as f64;
let term1 = dcnl * x + redemption;
let term2 = anl * x + pr;
let term3 = frequency as f64 / dscnl;
Ok((term1 - term2) / term2 * term3)
}
Kernels shared with other functions
basiscatalogue/bondsodd_outcatalogue/bondsdate_1900catalogue/financialdays_from_civillocalecivil_from_dayslocaleexcel_serial_from_ymdlocaleymd_from_excel_seriallocaledays_in_monthported/day_count_commonus_30_360ported/day_count_commonparse_basisported/odd_bond_familyparse_frequencyported/odd_bond_familymax_excel_serialported/odd_bond_familyparse_date_serialported/odd_bond_familydays_in_yearported/odd_bond_familydays_in_monthported/odd_bond_familyadd_months_clampedported/odd_bond_familydays360_usported/odd_bond_familydays360_us_bothported/odd_bond_familydays360_euported/odd_bond_familyday_countported/odd_bond_familyday_count_non_negativeported/odd_bond_familyday_count_non_negative_with_us_hackported/odd_bond_familyvalidate_positive_inputsported/odd_bond_familymap_odd_bond_error_to_wsported/odd_bond_family
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
ODDLPRICE prices the same last-coupon schedule at a supplied yield. ODDFYIELD handles an irregular first coupon; YIELD handles regular coupons.
Named variants
No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents