{"id":"cashflow-payback-period","version":"1.0.0","description":"Payback period of periodic cash flows with linear interpolation, optional discounting and the cumulative path.","supported_operations":["payback period of a project","how long to recover the initial investment","discounted payback period","payback period with fractional years","cumulative cash flow and break-even period","years to pay back an investment","payback period with discounting at a rate","when does cumulative cash flow turn positive"],"unsupported_operations":["net present value or IRR of the flows (use cashflow-npv or cashflow-irr)","payback of dated flows with irregular spacing","break-even units or sales volume analysis","profitability or return ratios such as ROI"],"semantics":["Inputs: cash_flows (array of 2 to 2000 decimal strings; flow k is at the end of period k, flow 0 is at time 0; positive is money received, negative is money paid), discount_rate (optional periodic rate as a decimal fraction, greater than -1 and at most 100; when present the payback is DISCOUNTED, and \"0\" still counts as present), scale (0 to 12, default 2, for cumulative), rate_scale (0 to 12, default 10, for payback_period) and rounding (default half-up).","Adjusted flows: without discount_rate adj_k = cash_flow_k. With discount_rate d, adj_k = cash_flow_k / (1+d)^k (time 0 undiscounted), computed with an absolute error below 1e-33 and rounded half-even to 30 fractional digits (so a discounted flow that is mathematically exact, such as 110/1.1 = 100, is exact). The cumulative sums cum_k = adj_0 + ... + adj_k are exact sums of these values; cumulative[k] is cum_k rounded once to scale (an array of n entries, undiscounted or discounted according to discount_rate).","Payback: let s be the first index with cum_s < 0 (the investment has started). If there is none (the cumulative never goes below 0, so nothing has to be recovered) the result is not_computable (details.reason no_outlay). Otherwise k* is the first index k > s with cum_k >= 0. If k* exists, recovered is true, payback_period_whole is k* (the number of whole periods after which the investment is first recovered) and payback_period = (k* - 1) + (-cum_(k*-1)) / adj_(k*), which assumes the flow of period k* arrives uniformly within the period (linear interpolation); a cumulative exactly 0 at k* gives exactly k*. If k* does not exist, recovered is false and payback_period and payback_period_whole are null: never recovering is a normal result, not an error.","Later outflows after the recovery are ignored (the first recovery is reported). A leading zero or positive flow before the first negative cumulative is allowed (a delayed outlay): periods are still counted from time 0. payback_period is computed as an exact quotient, rounded half-even to 30 digits and then once to rate_scale with the rounding mode; payback_period rounded to rate_scale 0 can therefore be smaller than payback_period_whole.","If any adjusted flow or cumulative sum reaches 1e20 in magnitude the result is not_computable (details.reason overflow; a discount_rate below 0 or amounts near 1e20 can cause it).","More than 2000 cash flows, or a decimal string longer than 64 UTF-8 bytes, is limit_exceeded, checked before parsing. Percent values are not accepted: 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":2000,"max_string_bytes":64},"pricing":{"status":"unpriced","charge_usd":null},"input_schema":{"type":"object","additionalProperties":false,"required":["cash_flows"],"properties":{"cash_flows":{"type":"array","minItems":2,"maxItems":2000,"items":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64}},"discount_rate":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64},"scale":{"type":"integer","minimum":0,"maximum":12},"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":["recovered","payback_period","payback_period_whole","cumulative","discounted"],"properties":{"recovered":{"type":"boolean"},"payback_period":{"type":["string","null"],"pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64},"payback_period_whole":{"type":["integer","null"],"minimum":1,"maximum":4999},"cumulative":{"type":"array","minItems":2,"maxItems":5000,"items":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64}},"discounted":{"type":"boolean"}}},"examples":[{"input":{"cash_flows":["-2000","500","500","5000"]},"output":{"recovered":true,"payback_period":"2.2000000000","payback_period_whole":3,"cumulative":["-2000.00","-1500.00","-1000.00","4000.00"],"discounted":false}},{"input":{"cash_flows":["-1000","500","500","500"],"discount_rate":"0.1"},"output":{"recovered":true,"payback_period":"2.3520000000","payback_period_whole":3,"cumulative":["-1000.00","-545.45","-132.23","243.43"],"discounted":true}}],"execute_url":"/v1/tools/cashflow-payback-period/versions/1.0.0/execute"}