{"id":"cashflow-xnpv","version":"1.0.0","description":"NPV of dated cash flows with the Excel XNPV 365-day exponent and an explicit valuation date.","supported_operations":["XNPV of dated cash flows","net present value with irregular dates","Excel XNPV function equivalent","discount payments made on specific dates","present value of cash flows on different days","NPV at a valuation date of dated payments","XNPV with actual days over 365","value of a dated payment schedule at a 9 percent rate"],"unsupported_operations":["equally spaced flows without dates (use cashflow-npv)","solving the rate that makes XNPV zero (use cashflow-xirr)","ACT/ACT or 30/360 day-count exponents instead of actual days over 365","business-day adjustment of payment dates"],"semantics":["Inputs: rate (annual effective rate as a decimal fraction, greater than -1 and at most 100), cash_flows (1 to 2000 objects {date, amount}: date an ISO calendar date YYYY-MM-DD from 1900-01-01 to 2200-12-31, amount a decimal string with |amount| <= 1e12, positive received and negative paid), valuation_date (optional ISO date in the same range; default the date of the first listed flow), scale (0 to 12, default 2) and rounding (default half-up). Dates may repeat and need not be sorted.","XNPV = sum over the flows of amount_i / (1+rate)^((d_i - d_v)/365), where d_i - d_v is the exact number of calendar days from the valuation date to the flow date (negative when the flow is earlier) and 365 is used for every year including leap years (Excel XNPV). Note that the exponent uses actual days over 365, not period indices and not ACT/ACT.","Anchor rule: without valuation_date the anchor d_v is the date of the FIRST LISTED flow (not the earliest date) and a flow dated before it is invalid_input (details.reason date_before_first), which matches Excel's #NUM!. With valuation_date given there is no such restriction: flows before it are compounded forward (exponent positive), flows after it are discounted.","Evaluation is on binary64 floats with the pinned fdlibm port: amount_i = Number(decimal string); w_i = ((d_i - d_v) / 365) * log1p(rate) (an IEEE division of the integer day count by 365, then a multiplication); term_i = amount_i * exp(-w_i); the terms are added in listed order starting from 0. Never Math.exp, Math.log or Math.pow. If any term or the sum is not finite (floating-point overflow, for example a compounding of decades at a rate near 100 or -0.99) the result is not_computable (details.reason overflow).","The result is converted from its exact binary64 value and rounded once to scale with the rounding mode. Accuracy is about 1e-12 relative to the sum of |term_i|; for amounts near 1e12 the cents digit is therefore not guaranteed. A result that rounds to zero prints without a minus sign. valuation_date in the output is the anchor actually used; flows is the number of cash flows.","More than 2000 cash flows, or any string longer than 64 UTF-8 bytes, is limit_exceeded, checked before parsing. Percent values are not accepted: rate \"0.09\" means 9 percent per year.","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":["rate","cash_flows"],"properties":{"rate":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64},"cash_flows":{"type":"array","minItems":1,"maxItems":2000,"items":{"type":"object","additionalProperties":false,"required":["date","amount"],"properties":{"date":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}$","maxLength":10},"amount":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64}}}},"valuation_date":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}$","maxLength":10},"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":["xnpv","valuation_date","flows"],"properties":{"xnpv":{"type":"string","pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","maxLength":64},"valuation_date":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}$","maxLength":10},"flows":{"type":"integer","minimum":1,"maximum":2000}}},"examples":[{"input":{"rate":"0.09","cash_flows":[{"date":"2008-01-01","amount":"-10000"},{"date":"2008-03-01","amount":"2750"},{"date":"2008-10-30","amount":"4250"},{"date":"2009-02-15","amount":"3250"},{"date":"2009-04-01","amount":"2750"}]},"output":{"xnpv":"2086.65","valuation_date":"2008-01-01","flows":5}},{"input":{"rate":"0.08","cash_flows":[{"date":"2020-01-01","amount":"-500"},{"date":"2021-01-01","amount":"300"},{"date":"2022-01-01","amount":"400"}],"valuation_date":"2020-07-01","scale":4},"output":{"xnpv":"125.2997","valuation_date":"2020-07-01","flows":3}}],"execute_url":"/v1/tools/cashflow-xnpv/versions/1.0.0/execute"}