{"id":"cashflow-irr","version":"1.0.0","description":"IRR of equally spaced cash flows with every root reported, the chosen root named and no-solution cases signalled.","supported_operations":["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"],"unsupported_operations":["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"],"semantics":["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."],"limits":{"max_items":1000,"max_string_bytes":64,"max_iterations_per_root":200},"pricing":{"status":"unpriced","charge_usd":null},"input_schema":{"type":"object","additionalProperties":false,"required":["cash_flows"],"properties":{"cash_flows":{"type":"array","minItems":2,"maxItems":1000,"items":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64}},"guess":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64},"rate_scale":{"type":"integer","minimum":0,"maximum":12},"rounding":{"type":"string","enum":["half-up","half-even","half-down","up","down","ceiling","floor"]}}},"output_schema":{"type":"object","additionalProperties":false,"required":["irr","roots","sign_changes","multiple_roots_possible","method"],"properties":{"irr":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64},"roots":{"type":"array","minItems":1,"maxItems":48,"items":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64}},"sign_changes":{"type":"integer","minimum":1,"maximum":4999},"multiple_roots_possible":{"type":"boolean"},"method":{"type":"string","enum":["brent"]}}},"examples":[{"input":{"cash_flows":["-70000","12000","15000","18000","21000","26000"],"rate_scale":4},"output":{"irr":"0.0866","roots":["0.0866"],"sign_changes":1,"multiple_roots_possible":false,"method":"brent"}},{"input":{"cash_flows":["-100","230","-132"],"guess":"0.25","rate_scale":8},"output":{"irr":"0.20000000","roots":["0.10000000","0.20000000"],"sign_changes":2,"multiple_roots_possible":true,"method":"brent"}}],"execute_url":"/v1/tools/cashflow-irr/versions/1.0.0/execute"}