Financial functions
MIRR
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 | MIRR |
| Bulgarian | MIRR |
| Czech | MIRR |
| Danish | MIA |
| German | MIRR |
| Greek | MIRR |
| English (Australia) | MIRR |
| English (United Kingdom) | MIRR |
| English (United States) | MIRR |
| Spanish | TIRM |
| Estonian | MIRR |
| Finnish | MSISÄINEN |
| French | MIRR |
| Hebrew | MIRR |
| Croatian | MIRR |
| Hungarian | MEGTÉRÜLÉS |
| Indonesian | MIRR |
| Italian | MIRR |
| Japanese | MIRR |
| Korean | MIRR |
| Lithuanian | MIRR |
| Latvian | MIRR |
| Norwegian | MIRR |
| Dutch | GIR |
| Polish | MIRR |
| Portuguese (Brazil) | MIRR |
| Portuguese (Portugal) | MTIR |
| Romanian | MIRR |
| Russian | МВСД |
| Slovak | MIRR |
| Slovenian | MIRR |
| Serbian (Latin) | MIRR |
| Swedish | MODIR |
| Thai | MIRR |
| Turkish | D_İÇ_VERİM_ORANI işlevi |
| Ukrainian | MIRR |
| Vietnamese | MIRR |
| Chinese (Simplified) | MIRR |
| Chinese (Hong Kong) | MIRR |
| Chinese (Traditional) | MIRR |
Names from Microsoft's support site.
What it does
MIRR(values, finance_rate, reinvest_rate)
MIRR(values, finance_rate, reinvest_rate) returns the modified internal rate of return of a
series of periodic cash flows: the constant rate at which the discounted cost of the negative flows
grows into the compounded value of the positive flows over the life of the project.
Let n be the number of periods (one less than the number of cash flows), and split the series:
PV_neg = Σ_{k: CF_k < 0} CF_k / (1 + finance_rate)^k — costs, discounted to time 0
FV_pos = Σ_{k: CF_k > 0} CF_k · (1 + reinvest_rate)^(n−k) — returns, compounded to time n
Then
MIRR = ( −FV_pos / PV_neg )^(1/n) − 1
Read as a sentence: gather every outflow at the start at the rate you actually borrow at, gather every inflow at the end at the rate you actually reinvest at, and ask what single compound rate takes the one into the other. That is a well-posed question with exactly one answer.
Why it exists: the two things it fixes in IRR
MIRR is not a variant of IRR; it is a correction of two specific defects in it.
- The reinvestment assumption.
IRRimplicitly assumes every interim inflow is reinvested atIRRitself. For a project with a 40% internal rate that assumption is heroic.MIRRmakes the reinvestment rate an explicit argument, so the answer says what it assumes. - Multiple roots.
IRRsolves a degree-npolynomial, so a series with several sign changes can have several real answers and the one you get depends onguess.MIRRhas no polynomial and no root-finding at all: it is a singlen-th root of a ratio of two sums, so it is always unique, always exists on the admissible domain, and takes noguessargument. That is the structural difference, and it is the reason to preferMIRRwhenever the cash flows are not conventional.
Special case worth knowing: when finance_rate = reinvest_rate = IRR(values), MIRR returns that
same value. MIRR is a generalization of IRR, not a competitor to it.
Domain and range: the result is real whenever FV_pos > 0 and PV_neg < 0, which the sign
requirement guarantees. It is bounded below by −1 and unbounded above.
Sign convention
The family convention holds: negative values are payments, positive values are income. The split
of the series into two sums is by sign of the cash flow, so miscoding a cost as positive does not
merely change a number — it moves that flow into the other sum and compounds it forward instead of
discounting it back. A sign error here is qualitatively worse than a sign error in FV.
A zero cash flow belongs to neither sum. It still consumes a period.
Arguments
| Argument | Meaning | Default |
|---|---|---|
values | An array or reference containing the cash flows, in the order in which they occur. Required. | — |
finance_rate | The interest rate paid on the money used in the cash flows — the cost of the negative flows. Required. | — |
reinvest_rate | The interest rate received on the cash flows as they are reinvested — applied to the positive flows. Required. | — |
- All three are required. Unlike
IRRthere is no optional argument, because there is nothing to guess. - Order is meaning. Like
IRR,MIRRhas no dates: position in the array is the time index. valuesmust contain at least one positive and at least one negative number, otherwise one of the two sums is empty and the ratio is undefined.- The rates are per period, in the same period as the spacing of
values. nis the number of periods, one less than the count of cash flows — the exponent1/nin the final root uses that count, and it counts every entry the collector kept, including zeros.
Try it
Quirks
Result and edge cases
Returns Number — a periodic rate as a decimal fraction.
- No iteration, no
guess, no non-convergence. Every failure mode is a domain failure. finance_rate = reinvest_rate = IRR(values)reproducesIRR; a useful sanity anchor.reinvest_rate = 0compounds nothing forward: the positive flows are simply summed. Likewisefinance_rate = 0sums the negatives undiscounted. Both are admissible and meaningful.finance_rate = −1orreinvest_rate = −1makes a compounding base of zero; the reference engine rejects a base within a small tolerance of zero as#DIV/0!.- Zero entries consume a period without joining either sum, so padding a series with trailing
zeros lengthens
nand lowers the result. This is not a rounding effect; it changes the exponent. - Empty, missing and error arguments follow the shared call model; see The value universe and Coercion and lifting.
Errors
| Error | Condition |
|---|---|
#DIV/0! | values contains no positive value, or no negative value |
#DIV/0! | Fewer than two cash flows |
#DIV/0! | 1 + finance_rate or 1 + reinvest_rate is (within tolerance) zero |
#NUM! | The result is not representable |
#VALUE! | Non-numeric text in the array or in a rate slot |
| propagated | An error value in any argument surfaces as that error |
#VALUE! | The call is made with any number of arguments other than three |
How to implement
Numerical notes
MIRR is closed form and well conditioned, and that is its main numerical virtue.
No root-finding means no conditioning problem. Everything said on the IRR page
about flat roots, iteration budgets, guess sensitivity and publication rules for ULP plateaus simply
does not apply here. MIRR's answer is a deterministic function of its inputs evaluated in a fixed
number of operations.
Two summations and a fractional power. The accuracy budget is: n divisions accumulating into
PV_neg, n multiplications accumulating into FV_pos, one division, one x^(1/n), one
subtraction of 1.
- The summations are same-sign within each sum — negatives only, and positives only — so there
is no cancellation in the accumulation at all. This is a real structural advantage over
IRR, whose objective function is a mixed-sign sum by construction. - The final subtraction of 1 is the one cancellation site. When
FV_pos/(−PV_neg)is close to 1 — a project that barely breaks even — then-th root is very close to 1 and subtracting 1 loses precision proportionally. The stable form isexpm1(log1p(ratio − 1)/n), or equivalentlyexpm1(ln(ratio)/n), which holds full relative accuracy for a near-zero result. The reference engine at commit473efa3uses the naivepowf(ratio, 1/n) − 1. - The exponent
1/nis inexact for everynthat is not a power of two, introducing a rounding before the power is evaluated.
The Handbook does not claim what Excel does internally.
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.
MIRR · 4 lines · calc-func/src/catalogue/financial.rs on GitHub10 mirr_fn "MIRR" (3, 3) [R "values", V "finance_rate", V "reinvest_rate"] |s, a, sv| {
let values = numbers(s, a, 0, 1, sv, Held::Numbers)?;
tv_out(s, tv::mirr(&values, num(s, a, 1)?, num(s, a, 2)?))
}
mirr · 39 lines · calc-func/src/ported/financial_time_value_family.rs on GitHubpub fn mirr(
cashflows: &[f64],
finance_rate: f64,
reinvest_rate: f64,
) -> Result<f64, FinancialError> {
validate_finite(&[finance_rate, reinvest_rate])?;
validate_finite(cashflows)?;
if cashflows.len() < 2 {
return Err(FinancialError::Div0);
}
let has_positive = cashflows.iter().any(|value| *value > 0.0);
let has_negative = cashflows.iter().any(|value| *value < 0.0);
if !has_positive || !has_negative {
return Err(FinancialError::Div0);
}
if (1.0 + finance_rate).abs() < EPSILON || (1.0 + reinvest_rate).abs() < EPSILON {
return Err(FinancialError::Div0);
}
let periods = (cashflows.len() - 1) as f64;
let mut finance_pv = 0.0;
let mut reinvest_fv = 0.0;
for (idx, cashflow) in cashflows.iter().enumerate() {
let idxf = idx as f64;
if *cashflow < 0.0 {
finance_pv += *cashflow / crt_pow(1.0 + finance_rate, idxf);
} else if *cashflow > 0.0 {
reinvest_fv += *cashflow * crt_pow(1.0 + reinvest_rate, periods - idxf);
}
}
if finance_pv >= 0.0 || reinvest_fv <= 0.0 {
return Err(FinancialError::Div0);
}
let result = crt_pow(-reinvest_fv / finance_pv, 1.0 / periods) - 1.0;
if result.is_finite() {
Ok(result)
} else {
Err(FinancialError::Num)
}
}
Kernels shared with other functions
tv_outcatalogue/financialvalidate_finiteported/financial_time_value_family
Argument and result plumbing
No implementation has been published with a Handbook test suite for this function.
Version differences
No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.
Alternatives
Relationships
- IRR — the unmodified measure.
MIRRdiffers in three ways at once: explicit rates, closed form, unique answer. WhereIRRreturns#NUM!for a series with no sign change,MIRRreturns#DIV/0!for the same series. XIRR— the dated internal rate of return. There is no datedMIRR; irregular cash flows with an explicit reinvestment assumption have to be built by hand fromXNPV.NPV— the two sumsMIRRforms areNPV-shaped, and a hand-builtMIRRis usually written withNPVandFV. The classic single-cell spreadsheet identity isMIRR = (−NPV(reinvest, positives)·(1+reinvest)^n / (NPV(finance, negatives)·(1+finance)))^(1/n) − 1— worth writing out once to see that the function is genuinely closed form.RRI— the compound rate between a present and a future value overnperiods.MIRRisRRI(n, −PV_neg, FV_pos): the two gathered sums and one compound rate between them. IfRRIis available, that identity is the clearest statement of whatMIRRmeans.- FV — the compounding
FV_posperforms. - Confused with:
IRRwith aguess. Theguessargument inIRRselects among genuine answers;MIRRhas one answer and needs no selection.
Named variants
No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents