{
  "category": "Financial functions",
  "display_name": "MIRR",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.MIRR",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 6 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 6 recorded answers",
    "workbook_corpus": {
      "cells": 6,
      "matched": 6
    }
  },
  "implementations": [
    {
      "commit": "9e1884369a678158dd82d3d74188daf986995e87",
      "flavour": "excel-compatibility-candidate",
      "language": "Rust",
      "name": "CalcFunc",
      "own_code": [
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/financial.rs#L201-L204",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/financial_time_value_family.rs#L1054-L1092"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/financial::tv_out",
        "ported/financial_time_value_family::validate_finite"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/financial.rs#L201-L204",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 6 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.MIRR.json",
  "name": "MIRR",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n\n- **[IRR](FUNC.IRR.md)** — the unmodified measure. `MIRR` differs in three ways at once: explicit\n  rates, closed form, unique answer. Where `IRR` returns `#NUM!` for a series with no sign change,\n  `MIRR` returns `#DIV/0!` for the same series.\n- **`XIRR`** — the dated internal rate of return. There is **no dated `MIRR`**; irregular cash flows\n  with an explicit reinvestment assumption have to be built by hand from `XNPV`.\n- **`NPV`** — the two sums `MIRR` forms are `NPV`-shaped, and a hand-built `MIRR` is usually written\n  with `NPV` and `FV`. The classic single-cell spreadsheet identity is\n  `MIRR = (−NPV(reinvest, positives)·(1+reinvest)^n / (NPV(finance, negatives)·(1+finance)))^(1/n) − 1`\n  — worth writing out once to see that the function is genuinely closed form.\n- **`RRI`** — the compound rate between a present and a future value over `n` periods. `MIRR` **is**\n  `RRI(n, −PV_neg, FV_pos)`: the two gathered sums and one compound rate between them. If `RRI` is\n  available, that identity is the clearest statement of what `MIRR` means.\n- **[FV](FUNC.FV.md)** — the compounding `FV_pos` performs.\n- **Confused with**: `IRR` with a `guess`. The `guess` argument in `IRR` selects among genuine\n  answers; `MIRR` has one answer and needs no selection.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`MIRR` is closed form and well conditioned, and that is its main numerical virtue.\n\n**No root-finding means no conditioning problem.** Everything said on the [IRR](FUNC.IRR.md) page\nabout flat roots, iteration budgets, guess sensitivity and publication rules for ULP plateaus simply\ndoes not apply here. `MIRR`'s answer is a deterministic function of its inputs evaluated in a fixed\nnumber of operations.\n\n**Two summations and a fractional power.** The accuracy budget is: `n` divisions accumulating into\n`PV_neg`, `n` multiplications accumulating into `FV_pos`, one division, one `x^(1/n)`, one\nsubtraction of 1.\n\n- The **summations** are same-sign within each sum — negatives only, and positives only — so there\n  is **no cancellation in the accumulation at all**. This is a real structural advantage over `IRR`,\n  whose objective function is a mixed-sign sum by construction.\n- The **final subtraction of 1** is the one cancellation site. When `FV_pos/(−PV_neg)` is close to 1\n  — a project that barely breaks even — the `n`-th root is very close to 1 and subtracting 1 loses\n  precision proportionally. The stable form is `expm1(log1p(ratio − 1)/n)`, or equivalently\n  `expm1(ln(ratio)/n)`, which holds full relative accuracy for a near-zero result. The reference\n  engine at commit `473efa3` uses the naive `powf(ratio, 1/n) − 1`.\n- The **exponent `1/n`** is inexact for every `n` that is not a power of two, introducing a rounding\n  before the power is evaluated.\n\nThe Handbook does not claim what Excel does internally.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number` — a periodic rate as a decimal fraction.\n\n- **No iteration, no `guess`, no non-convergence.** Every failure mode is a domain failure.\n- **`finance_rate = reinvest_rate = IRR(values)`** reproduces `IRR`; a useful sanity anchor.\n- **`reinvest_rate = 0`** compounds nothing forward: the positive flows are simply summed. Likewise\n  `finance_rate = 0` sums the negatives undiscounted. Both are admissible and meaningful.\n- **`finance_rate = −1` or `reinvest_rate = −1`** makes a compounding base of zero; the reference\n  engine rejects a base within a small tolerance of zero as `#DIV/0!`.\n- **Zero entries consume a period** without joining either sum, so padding a series with trailing\n  zeros lengthens `n` and lowers the result. This is not a rounding effect; it changes the exponent.\n- Empty, missing and error arguments follow the shared call model; see\n  [The value universe](../model/01-value-universe.md) and\n  [Coercion and lifting](../model/02-coercion-and-lifting.md).\n\n\n\n### Errors\n\n\n| Error | Condition |\n|---|---|\n| `#DIV/0!` | `values` contains no positive value, or no negative value |\n| `#DIV/0!` | Fewer than two cash flows |\n| `#DIV/0!` | `1 + finance_rate` or `1 + reinvest_rate` is (within tolerance) zero |\n| `#NUM!` | The result is not representable |\n| `#VALUE!` | Non-numeric text in the array or in a rate slot |\n| propagated | An error value in any argument surfaces as that error |\n| `#VALUE!` | The call is made with any number of arguments other than three |\n\n",
    "sources": "- Microsoft, \"MIRR function\" —\n  <https://support.microsoft.com/en-us/office/mirr-function-b020f038-7492-4fb4-93c1-35c345b53524>\n  (syntax, the three argument descriptions, the ordering requirement on `values`, the requirement\n  for at least one positive and one negative value, and the `#DIV/0!` condition).\n- Handbook, [IRR](FUNC.IRR.md) — the unmodified measure, its multiple-root behaviour and its\n  differing array-collection rule.\n- Handbook, [The value universe](../model/01-value-universe.md) and\n  [Coercion and lifting](../model/02-coercion-and-lifting.md).\n- Handbook projections `data/functions/FUNC.MIRR.json` and `data/presence/FUNC.MIRR.json`.\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`MIRR(values, finance_rate, reinvest_rate)` returns the **modified internal rate of return** of a\nseries of periodic cash flows: the constant rate at which the discounted cost of the negative flows\ngrows into the compounded value of the positive flows over the life of the project.\n\nLet `n` be the number of periods (one less than the number of cash flows), and split the series:\n\n    PV_neg  =  Σ_{k: CF_k < 0}  CF_k / (1 + finance_rate)^k          — costs, discounted to time 0\n    FV_pos  =  Σ_{k: CF_k > 0}  CF_k · (1 + reinvest_rate)^(n−k)     — returns, compounded to time n\n\nThen\n\n    MIRR  =  ( −FV_pos / PV_neg )^(1/n)  −  1\n\nRead as a sentence: gather every outflow at the start at the rate you actually borrow at, gather\nevery inflow at the end at the rate you actually reinvest at, and ask what single compound rate\ntakes the one into the other. That is a well-posed question with exactly one answer.\n\n### Why it exists: the two things it fixes in IRR\n\n`MIRR` is not a variant of [IRR](FUNC.IRR.md); it is a correction of two specific defects in it.\n\n1. **The reinvestment assumption.** `IRR` implicitly assumes every interim inflow is reinvested at\n   `IRR` itself. For a project with a 40% internal rate that assumption is heroic. `MIRR` makes the\n   reinvestment rate an explicit argument, so the answer says what it assumes.\n2. **Multiple roots.** `IRR` solves a degree-`n` polynomial, so a series with several sign changes\n   can have several real answers and the one you get depends on `guess`. `MIRR` has **no polynomial\n   and no root-finding at all**: it is a single `n`-th root of a ratio of two sums, so **it is always\n   unique, always exists on the admissible domain, and takes no `guess` argument**. That is the\n   structural difference, and it is the reason to prefer `MIRR` whenever the cash flows are not\n   conventional.\n\nSpecial case worth knowing: when `finance_rate = reinvest_rate = IRR(values)`, `MIRR` returns that\nsame value. `MIRR` is a generalization of `IRR`, not a competitor to it.\n\nDomain and range: the result is real whenever `FV_pos > 0` and `PV_neg < 0`, which the sign\nrequirement guarantees. It is bounded below by `−1` and unbounded above.\n\n### Sign convention\n\nThe family convention holds: **negative values are payments, positive values are income**. The split\nof the series into two sums is *by sign of the cash flow*, so miscoding a cost as positive does not\nmerely change a number — it moves that flow into the other sum and compounds it forward instead of\ndiscounting it back. A sign error here is qualitatively worse than a sign error in `FV`.\n\nA zero cash flow belongs to neither sum. It still consumes a period.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `values` | An array or reference containing the cash flows, **in the order in which they occur**. Required. | — |\n| `finance_rate` | The interest rate paid on the money used in the cash flows — the cost of the negative flows. Required. | — |\n| `reinvest_rate` | The interest rate received on the cash flows as they are reinvested — applied to the positive flows. Required. | — |\n\n- **All three are required.** Unlike `IRR` there is no optional argument, because there is nothing to\n  guess.\n- **Order is meaning.** Like `IRR`, `MIRR` has no dates: position in the array is the time index.\n- **`values` must contain at least one positive and at least one negative number**, otherwise one of\n  the two sums is empty and the ratio is undefined.\n- **The rates are per period**, in the same period as the spacing of `values`.\n- **`n` is the number of *periods*, one less than the count of cash flows** — the exponent `1/n` in\n  the final root uses that count, and it counts every entry the collector kept, including zeros.\n\n\n"
  },
  "signature": {
    "display": "MIRR(values, finance_rate, reinvest_rate)",
    "parameters": [
      {
        "description": null,
        "name": "values",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "finance_rate",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "reinvest_rate",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 3,
        "min": 3
      },
      "category": "Financial functions",
      "classification": {
        "arg_preparation_profile": "RefsVisibleInAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "None",
        "host_interaction_class": "None",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Internal rate of return with separate finance and reinvestment rates",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the internal rate of return where positive and negative cash flows are financed at different rates",
        "microsoft_url": "https://support.microsoft.com/en-us/office/mirr-function-b020f038-7492-4fb4-93c1-35c345b53524"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "MIRR"
        },
        {
          "locale": "bg-BG",
          "name": "MIRR"
        },
        {
          "locale": "cs-CZ",
          "name": "MIRR"
        },
        {
          "locale": "da-DK",
          "name": "MIA"
        },
        {
          "locale": "de-DE",
          "name": "MIRR"
        },
        {
          "locale": "el-GR",
          "name": "MIRR"
        },
        {
          "locale": "en-AU",
          "name": "MIRR"
        },
        {
          "locale": "en-GB",
          "name": "MIRR"
        },
        {
          "locale": "en-US",
          "name": "MIRR"
        },
        {
          "locale": "es-ES",
          "name": "TIRM"
        },
        {
          "locale": "et-EE",
          "name": "MIRR"
        },
        {
          "locale": "fi-FI",
          "name": "MSISÄINEN"
        },
        {
          "locale": "fr-FR",
          "name": "MIRR"
        },
        {
          "locale": "he-IL",
          "name": "MIRR"
        },
        {
          "locale": "hr-HR",
          "name": "MIRR"
        },
        {
          "locale": "hu-HU",
          "name": "MEGTÉRÜLÉS"
        },
        {
          "locale": "id-ID",
          "name": "MIRR"
        },
        {
          "locale": "it-IT",
          "name": "MIRR"
        },
        {
          "locale": "ja-JP",
          "name": "MIRR"
        },
        {
          "locale": "ko-KR",
          "name": "MIRR"
        },
        {
          "locale": "lt-LT",
          "name": "MIRR"
        },
        {
          "locale": "lv-LV",
          "name": "MIRR"
        },
        {
          "locale": "nb-NO",
          "name": "MIRR"
        },
        {
          "locale": "nl-NL",
          "name": "GIR"
        },
        {
          "locale": "pl-PL",
          "name": "MIRR"
        },
        {
          "locale": "pt-BR",
          "name": "MIRR"
        },
        {
          "locale": "pt-PT",
          "name": "MTIR"
        },
        {
          "locale": "ro-RO",
          "name": "MIRR"
        },
        {
          "locale": "ru-RU",
          "name": "МВСД"
        },
        {
          "locale": "sk-SK",
          "name": "MIRR"
        },
        {
          "locale": "sl-SI",
          "name": "MIRR"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "MIRR"
        },
        {
          "locale": "sv-SE",
          "name": "MODIR"
        },
        {
          "locale": "th-TH",
          "name": "MIRR"
        },
        {
          "locale": "tr-TR",
          "name": "D_İÇ_VERİM_ORANI işlevi"
        },
        {
          "locale": "uk-UA",
          "name": "MIRR"
        },
        {
          "locale": "vi-VN",
          "name": "MIRR"
        },
        {
          "locale": "zh-CN",
          "name": "MIRR"
        },
        {
          "locale": "zh-HK",
          "name": "MIRR"
        },
        {
          "locale": "zh-TW",
          "name": "MIRR"
        }
      ],
      "signature": {
        "display": "MIRR(values, finance_rate, reinvest_rate)",
        "parameters": [
          {
            "description": null,
            "name": "values",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "finance_rate",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "reinvest_rate",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "MIRR",
      "version_marker": null,
      "xlcall": {
        "code": "61",
        "symbol": "xlfMirr"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/mirr-function-b020f038-7492-4fb4-93c1-35c345b53524"
  },
  "try_it": {
    "formula": "=MIRR({-100;60;60},0.05,0.1)"
  },
  "url": "https://handbook.dnacalc.com/functions/MIRR.html",
  "variants": [],
  "versions": []
}