# lending.loan-payment
The level (annuity) payment that repays a loan in equal instalments: what a
mortgage, car loan or personal loan quote shows as "monthly payment".
## The formula
With a nominal annual rate split equally between the periods,
r = rate / paymentsPerYear, and n payments:
payment = P × r / (1 − (1 + r)^−n)
That is the textbook present-value-of-an-annuity formula, the same one as a
spreadsheet's PMT. Here it is never evaluated in floating point. The rate is
b basis points, so r = b / D with D = 10000 × paymentsPerYear, and the formula
is exactly the fraction
P × b × (D + b)^n / ( D × ((D + b)^n − D^n) )
Both sides are integers. For a 25-year monthly mortgage (D + b)^n is a
number of over 1,500 digits, far past what `math.rational` holds (its parts
must stay within 2^53 so JavaScript numbers stay exact), so the fraction is
built with arbitrary-size integers: `bigint` in TypeScript, `int` in Python and
`math.big-integer` in Rust. It is then rounded exactly once, with the
`math.round-div` mode you pass. A zero rate is P / n, rounded the same way.
## Rounding
- `half-up` gives the nearest penny, what most quotes show: £100,000 at 5%
over 25 years is £584.59.
- `up` never under-repays: every payment is at most a penny high, and the
final payment (see lending.amortisation-schedule) comes out slightly
smaller.
- `down` or `half-even` are available where a contract says so.
The mode applies to the exact value, so there is no double rounding: a
payment of exactly x.5 pence rounds by the mode's tie rule, anything else to
the nearer penny.
## What it does not do
- The rate is nominal and divided equally (12% a year is 1% a month). It is
not an APR or AER; lending.apr and banking.savings-aer convert.
- Every period is treated as equal. Interest charged daily, or a first period
of odd length, changes the payment slightly; build the schedule with
lending.daily-interest when that matters.
- No fees are added, and the payment is not a regulated APR disclosure.
## Limits
The rate is 0 to 100000 basis points, payments per year 1 to 52, and the term
must hold a whole number of payments (13 months cannot be paid quarterly), at
most 3000 of them. The principal must be positive and, for TypeScript to stay
exact, below 2^51 minor units.
The module also exports `paymentCount` (the argument checks and n) and
`roundWide` (round a large positive fraction with a round-div mode), which
the other lending capabilities reuse.
## Before you rely on this
**Not professional advice.** This capability calculates lending figures from published rules. It is a software component for developers, not financial advice. Rules change and every rate here has an effective date. Check that the dates cover your case. Verify results against the official sources listed above, and have a consumer-credit compliance specialist review how you use it, before anyone relies on the output. Provided "as is" under its licence, without warranty.
**Unreviewed.** This capability's implementations agree in every language and pass its published test vectors, which were worked out from the official sources cited. But no qualified consumer-credit compliance specialist has yet checked those vectors, or confirmed that the capability covers the cases it claims. Treat it as a draft. Do not use it for real people, money or decisions without your own expert review. Once a qualified reviewer signs off, this notice is replaced with their name, qualification and the date. Each new version needs fresh sign-off.
1.0.1 marks it unreviewed. The code and the tests are unchanged.