# invest.money-weighted-return
The money-weighted return of an investment: the single annual rate at which
every dated cash flow, discounted to the first date, sums to zero. This is
Excel's `XIRR`:
Σ P_i / (1 + r)^((d_i − d_1) / 365) = 0
"XIRR uses a 365-day year" and needs "at least one positive cash flow and one
negative cash flow". Microsoft, *XIRR function*,
https://support.microsoft.com/en-us/office/xirr-function-de1242ec-6477-445b-b11b-a303ad9adc9d
(read 2026-09-23). Its example (−10,000 on 2008-01-01, 2,750 on 2008-03-01,
4,250 on 2008-10-30, 3,250 on 2009-02-15, 2,750 on 2009-04-01) is 37.34%, and
is a vector here. The same rate is the internal rate of return (IRR) used as
the money-weighted rate of return in the CFA Institute's GIPS standards.
## Signs and dates
Money the investor puts in is negative; money taken out, and the closing
value of the holding on the last date, are positive. Flows may be in any
order and several may share a date; flows on the same date are netted, and a
date whose flows net to zero is dropped. Time is counted from the earliest
remaining date. (Excel wants the first listed date to be the earliest; moving
the reference date only multiplies the equation by a positive constant, so
the root is the same.) Days are actual days, divided by 365 even across a
29 February: a year from 2024-01-01 is 366 days, so +10% over it is 9.97%,
not 10%. Flows must fall within 36,500 days of each other.
## How it is solved
With v = (1 + r)^(−1/365), a per-day discount factor, the equation becomes a
polynomial with whole-day exponents, Σ P_i v^t_i = 0, and is solved by
bisection in `math.fractional-power`'s 18-place fixed point (whole powers
only, the same floors in the same order in every language), about 60 halvings.
- A positive rate means v in (0, 1). At v = 0 the sum is the first flow, at
v = 1 it is the plain total of the flows.
- A negative rate means v > 1, where v^t can overflow, so that side is solved
in u = 1/v in (0, 1), multiplying through by u^T (T the last day), which
does not change the sign: Σ P_i u^(T − t_i). At u = 0 that is the last flow.
The side whose two ends have opposite signs holds the root. If the plain
total is zero the rate is exactly 0. Then r = v^−365 − 1 (or u^365 − 1).
Excel instead runs Newton's method from a guess until the result is accurate
within 0.000001 percent, so its last printed digits can differ from the exact
root: the Microsoft example's exact rate is 0.3733625335..., which this gives
as `0.373362534`.
**Precision.** The rate is first settled to 12 decimal places (the fixed
point's errors are below 10^-13 for any flows within the limits), then rounded
half away from zero to 9 decimal places (`rate`) and to a whole basis point
(`basisPoints`).
## When there is no single answer
When the flows change sign once (pay in, then take out) there is exactly one
rate. When they change sign several times (deposits, withdrawals, more
deposits) the polynomial may have several roots, or none. This returns the
root when exactly one side of r = 0 brackets a change of sign. When both sides
do (two roots at least), or neither does (no root, or an even number of roots
on one side), it refuses with "no single rate of return solves these cash
flows" rather than return whichever root a guess happens to find, as Excel
does. A rate so large that v^365 underflows the fixed point (above roughly
10^5 %) is an error.
## Errors
At least one payment and one receipt after netting; one currency; real ISO
dates; whole minor units.