# Cashflow irr

`cashflow-irr` · version 1.0.0 · Financial calculations · free, no key needed

IRR of equally spaced cash flows with every root reported, the chosen root named and no-solution cases signalled.

**Use when you need to: internal rate of return of cash flows · IRR calculator for a series of payments · Excel IRR function equivalent.**

## Decide before calling

Read the [versioned contract](/v1/tools/cashflow-irr/versions/1.0.0) and the supported scope below. Reuse `cashflow-irr@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `cashflow-irr@1.0.0` for internal rate of return of cash flows. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- internal rate of return of cash flows
- IRR calculator for a series of payments
- Excel IRR function equivalent
- what return does this investment earn per period
- does this cash flow stream have multiple IRRs
- find the rate where NPV is zero
- break-even discount rate of a project
- IRR with a guess

## Not supported

- dated cash flows with a 365-day year (use cashflow-xirr)
- modified IRR with separate finance and reinvestment rates (use cashflow-mirr)
- the NPV value at a given rate (use cashflow-npv)
- roots below -0.99 or above 1000 per period

## Behavior

- Inputs: cash_flows (array of 2 to 1000 decimal strings in time order; the first flow is at time 0 and consecutive flows are exactly one period apart; positive is money received, negative is money paid; each flow must satisfy |x| <= 1e12, otherwise invalid_input), guess (decimal periodic rate from -0.99 to 1000, default "0.1"), rate_scale (0 to 12, default 10) and rounding (default half-up). Rates are per period, not per year.
- The IRR is a rate r > -1 at which f(r) = sum over k = 0 .. n-1 of cash_flow_k * (1+r)^(-k) equals 0. Because a stream can have several roots, the tool reports every root it can find and returns in irr the one nearest to guess (compared on the binary64 values before rounding; a tie goes to the smaller root). This is the same equation as Excel IRR; Excel returns one root chosen by Newton iteration from the guess, this tool returns all roots found and states which one it chose.
- sign_changes is the number of sign changes in the flow sequence ignoring zero flows (Descartes' rule of signs: it bounds the number of positive roots of the polynomial in 1/(1+r), so more than one sign change means several roots may exist); multiple_roots_possible is sign_changes > 1. If sign_changes is 0 (all flows zero, or all of one sign) the result is not_computable with details.reason no_sign_change.
- Root finding is on binary64 floats: each flow is Number(decimal string) (nearest double, ties to even), and f(r) = the sum, in ascending k, of cash_flow_k * exp(-k * log1p(r)) (the k = 0 term is exactly cash_flow_0) with exp and log1p from the pinned fdlibm 5.3 port, never Math.exp, Math.log or Math.pow. f is evaluated on the fixed periodic-rate grid [-0.99, -0.95, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.25, -0.2, -0.15, -0.1, -0.075, -0.05, -0.025, -0.01, 0, 0.005, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.125, 0.15, 0.175, 0.2, 0.25, 0.3, 0.4, 0.5, 0.75, 1, 1.5, 2, 3, 5, 10, 20, 50, 100, 1000]. A grid point where f is not finite (a floating-point overflow) skips its two adjacent intervals. A grid point where f is exactly 0 is a root. Every interval whose end values have opposite (non-zero) signs is refined by Brent's method (Brent 1973, netlib zeroin; tolerance 1e-14, at most 200 iterations). Roots closer than 1e-12 are merged; roots lists them ascending.
- not_computable also covers: no sign change of f on the grid, so no root between -0.99 and 1000 (details.reason no_root_in_range; an IRR below -0.99 or above 1000 is not searched); a Brent run that does not converge in 200 iterations (no_convergence); a non-finite f value inside Brent's iteration (non_finite_function). Two roots inside a single grid interval can be missed; this limitation is part of the contract.
- Each root is converted from its exact binary64 value and rounded once to rate_scale with the rounding mode. Accuracy of a root is about 1e-12 absolute, so digits beyond rate_scale 10 are not guaranteed; use rate_scale 10 or lower for reproducible output. irr equals one element of roots (after rounding). method is always the string brent.
- More than 1000 cash flows, or any string longer than 64 UTF-8 bytes, is limit_exceeded, checked before parsing. Percent values are not accepted: a rate is a decimal fraction, and the output irr 0.1 means 10 percent per period.
- Every rounded output is rounded exactly once from the unrounded value using the rounding mode: half-up (ties away from zero, the default), half-even, half-down (ties toward zero), up (away from zero), down (toward zero), ceiling, floor. Amount outputs print exactly scale fractional digits and rate-like outputs exactly rate_scale fractional digits; a result that rounds to zero prints without a minus sign (never '-0.00').
- Decimal string fields (amounts, rates) must match ^-?(0|[1-9][0-9]*)(\.[0-9]+)?$ with at most 20 integer digits and at most 20 fractional digits; a JSON number, exponent form, leading plus, surrounding spaces, percent sign, missing integer part or trailing dot is invalid_input. Rates are decimal fractions (0.065 means 6.5 percent; "6.5" means 650 percent). A decimal string longer than 64 UTF-8 bytes is limit_exceeded, checked before parsing.
- Disclaimer: arithmetic calculation only; not financial, tax, legal, or investment advice.

## Input

- `cash_flows` (array of string, required): min items 2; max items 1000; each max length 64; each pattern `^-?(0|[1-9][0-9]*)(\.[0-9]+)?$`
- `guess` (string, optional): max length 64; pattern `^-?(0|[1-9][0-9]*)(\.[0-9]+)?$`
- `rate_scale` (integer, optional): min 0; max 12
- `rounding` (one of "half-up", "half-even", "half-down", "up", "down", "ceiling", "floor", optional)

## Output

- `irr` (string, required): max length 64; pattern `^-?(0|[1-9][0-9]*)(\.[0-9]+)?$`
- `roots` (array of string, required): min items 1; max items 48; each max length 64; each pattern `^-?(0|[1-9][0-9]*)(\.[0-9]+)?$`
- `sign_changes` (integer, required): min 1; max 4999
- `multiple_roots_possible` (boolean, required)
- `method` (one of "brent", required)

## Limits

- max items: 1000
- max string bytes: 64
- max iterations per root: 200

## Example

Request input:

```json
{
  "cash_flows": [
    "-70000",
    "12000",
    "15000",
    "18000",
    "21000",
    "26000"
  ],
  "rate_scale": 4
}
```

Response:

```json
{
  "result": {
    "irr": "0.0866",
    "roots": [
      "0.0866"
    ],
    "sign_changes": 1,
    "multiple_roots_possible": false,
    "method": "brent"
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "cashflow-irr",
  "version": "1.0.0",
  "input": {
    "cash_flows": [
      "-70000",
      "12000",
      "15000",
      "18000",
      "21000",
      "26000"
    ],
    "rate_scale": 4
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/cashflow-irr/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"cash_flows":["-70000","12000","15000","18000","21000","26000"],"rate_scale":4}'
```

The machine-readable contract is at [/v1/tools/cashflow-irr/versions/1.0.0](/v1/tools/cashflow-irr/versions/1.0.0).

### CLI

```sh
node cli.mjs run cashflow-irr 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [Cashflow npv](/tools/cashflow-npv): NPV of equally spaced cash flows, time-0 or Excel time-1, with inflow PV, outflow PV and profitability index.
- [Cashflow mirr](/tools/cashflow-mirr): MIRR of periodic cash flows from a finance rate and a reinvestment rate, with compounded and discounted totals.
- [Cashflow payback period](/tools/cashflow-payback-period): Payback period of periodic cash flows with linear interpolation, optional discounting and the cumulative path.
- [Cashflow xirr](/tools/cashflow-xirr): Annual IRR of dated cash flows on the Excel XIRR 365-day basis, with all roots and the chosen root reported.
- [Cashflow xnpv](/tools/cashflow-xnpv): NPV of dated cash flows with the Excel XNPV 365-day exponent and an explicit valuation date.
- [Bond price from yield](/tools/bond-price-from-yield): Clean price, dirty price and accrued interest per 100 of a fixed-coupon bond from its yield (Excel PRICE, SIA).
