# Cashflow xnpv

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

NPV of dated cash flows with the Excel XNPV 365-day exponent and an explicit valuation date.

**Use when you need to: XNPV of dated cash flows · net present value with irregular dates · Excel XNPV function equivalent.**

## Decide before calling

Read the [versioned contract](/v1/tools/cashflow-xnpv/versions/1.0.0) and the supported scope below. Reuse `cashflow-xnpv@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-xnpv@1.0.0` for XNPV of dated 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

- 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

## Not supported

- 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

## Behavior

- 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.

## Input

- `rate` (string, required): max length 64; pattern `^-?(0|[1-9][0-9]*)(\.[0-9]+)?$`
- `cash_flows` (array of object, required): min items 1; max items 2000
- `valuation_date` (string, optional): max length 10; pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}$`
- `scale` (integer, optional): min 0; max 12
- `rounding` (one of "half-up", "half-even", "half-down", "up", "down", "ceiling", "floor", optional)

## Output

- `xnpv` (string, required): max length 64; pattern `^-?(0|[1-9][0-9]*)(\.[0-9]+)?$`
- `valuation_date` (string, required): max length 10; pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}$`
- `flows` (integer, required): min 1; max 2000

## Limits

- max items: 2000
- max string bytes: 64

## Example

Request input:

```json
{
  "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"
    }
  ]
}
```

Response:

```json
{
  "result": {
    "xnpv": "2086.65",
    "valuation_date": "2008-01-01",
    "flows": 5
  }
}
```

## How to call it

### MCP

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

```json
{
  "id": "cashflow-xnpv",
  "version": "1.0.0",
  "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"
      }
    ]
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/cashflow-xnpv/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"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"}]}'
```

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

### CLI

```sh
node cli.mjs run cashflow-xnpv 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 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 mirr](/tools/cashflow-mirr): MIRR of periodic cash flows from a finance rate and a reinvestment rate, with compounded and discounted totals.
- [Cashflow irr](/tools/cashflow-irr): IRR of equally spaced cash flows with every root reported, the chosen root named and no-solution cases signalled.
- [Bond cashflow schedule](/tools/bond-cashflow-schedule): Coupon dates, coupons remaining, accrued days and accrued interest for a regular fixed-coupon bond (Excel COUP* rules).
- [Interest accrual compute](/tools/interest-accrual-compute): Simple or compound (periodic or continuous) interest over a term in years or a dated span with a day-count basis.
