Time-value-of-money scalars: fv/5, pv/5, pmt/5, nper/5, and rate/6.
Each solves the standard annuity equation for one unknown:
pv·(1+r)^n + pmt·(1 + r·type)·((1+r)^n − 1)/r + fv = 0type is 0 for payments at the end of each period (ordinary annuity) or 1
for the beginning (annuity due). The sign convention follows spreadsheets:
money you receive is positive, money you pay out is negative.
Summary
Functions
Works out the future value of an investment: what it grows to after nper
periods, starting from a present value of pv, with a fixed payment of pmt
each period, all compounding at rate.
Same as fv/5, but hands back the value on its own and raises ArgumentError if the calculation fails.
Works out how many periods it takes for payments of pmt to pay off a present
value pv (reaching future value fv) at rate.
Same as nper/5, but hands back the value on its own and raises ArgumentError if the calculation fails.
Works out the level payment per period needed to pay off a present value pv
(and arrive at a future value fv) over nper periods at rate.
Same as pmt/5, but hands back the value on its own and raises ArgumentError if the calculation fails.
Works out the present value of an investment: what a future stream is worth
today. The stream is pmt paid each period for nper periods plus a lump sum
fv at the end, all discounted back at rate.
Same as pv/5, but hands back the value on its own and raises ArgumentError if the calculation fails.
Works out the interest rate per period of an annuity described by nper
payments of pmt, a present value pv, and a future value fv. nper has to
be a whole number of periods.
Same as rate/6, but hands back the rate on its own and raises ArgumentError if the calculation fails.
Types
Functions
Works out the future value of an investment: what it grows to after nper
periods, starting from a present value of pv, with a fixed payment of pmt
each period, all compounding at rate.
Use this to answer "if I put this much in now and add this much every period,
what will I have at the end?". As with the rest of the time-value-of-money
functions, type chooses when each payment happens — 0 for the end of the
period (an ordinary annuity) or 1 for the beginning (an annuity due) — and
the sign convention follows spreadsheets, so money you receive is positive and
money you pay out is negative.
iex> {:ok, value} = Finance.TVM.fv(0.05, 10, -100, -1000)
iex> Float.round(value, 2)
2886.68
Same as fv/5, but hands back the value on its own and raises ArgumentError if the calculation fails.
Works out how many periods it takes for payments of pmt to pay off a present
value pv (reaching future value fv) at rate.
This is the "how long until it's paid off?" question. When the numbers don't
describe a situation that ever resolves, it returns {:error, :undefined}.
iex> {:ok, periods} = Finance.TVM.nper(0.05, -100, 1000)
iex> Float.round(periods, 2)
14.21
Same as nper/5, but hands back the value on its own and raises ArgumentError if the calculation fails.
Works out the level payment per period needed to pay off a present value pv
(and arrive at a future value fv) over nper periods at rate.
This is the loan-payment question: given an amount borrowed today, what fixed
installment clears it over the term? The same type and sign conventions
apply, so a loan you take out is a positive pv and the payment comes back
negative.
iex> {:ok, payment} = Finance.TVM.pmt(0.10, 10, 1000)
iex> Float.round(payment, 2)
-162.75
Same as pmt/5, but hands back the value on its own and raises ArgumentError if the calculation fails.
Works out the present value of an investment: what a future stream is worth
today. The stream is pmt paid each period for nper periods plus a lump sum
fv at the end, all discounted back at rate.
It answers the mirror image of fv/5's question — "how much would I need to
put in now to fund these future payments?". The same type and sign
conventions apply.
iex> {:ok, value} = Finance.TVM.pv(0.05, 10, -100, -1000)
iex> Float.round(value, 2)
1386.09
Same as pv/5, but hands back the value on its own and raises ArgumentError if the calculation fails.
@spec rate(number(), number(), number(), number(), 0 | 1, [option()]) :: {:ok, rate()} | {:error, error()}
Works out the interest rate per period of an annuity described by nper
payments of pmt, a present value pv, and a future value fv. nper has to
be a whole number of periods.
There is no closed form for the rate, so this reuses the same numerical solver
as Finance.CashFlow.irr/1 and takes the same options. If it can't pin down a
rate, it returns {:error, :did_not_converge}.
iex> Finance.TVM.rate(10, -100, 1000)
{:ok, 0.0}
Same as rate/6, but hands back the rate on its own and raises ArgumentError if the calculation fails.