# invest.bond-yield
The current yield and the yield to maturity of a fixed-coupon bond that
redeems at 100, from its clean price, with the accrued interest and dirty
price they are worked from. It follows Excel's `YIELD(settlement, maturity,
rate, pr, 100, frequency, basis)`: Microsoft, *YIELD function*,
https://support.microsoft.com/en-us/office/yield-function-f5f5ca43-c4bd-434f-8bd2-ed3c9727a4fe
(read 2026-09-23). Its example (settlement 15 Feb 2008, maturity 15 Nov 2016,
5.75%, price 95.04287, semi-annual, basis 0) is 6.5%, and is a vector here;
the exact root is 0.0650000069.
## The calculation
Coupon dates are stepped back from maturity in whole periods of 12 /
frequency months (each one `k` periods from maturity, never one from the
last, so the 31st does not decay to the 28th). When maturity is the last day
of its month, every coupon date is the last day of its month, as Excel's
coupon functions treat it: a bond maturing 30 June pays on 31 December.
- A: days from the previous coupon to settlement; E: days in the coupon
period; DSC = E − A, days from settlement to the next coupon.
- `30-360` (Excel basis 0): A by 30/360 bond basis (`dates.day-count-fraction`,
ISDA 4.16(f)), E = 360 / frequency.
- `act-act` (Excel basis 1, and the ICMA actual/actual of gilts): actual
days, E the actual length of the period containing settlement.
- Accrued interest = coupon / frequency × A / E per 100; dirty = clean +
accrued.
**More than one coupon left**: the yield y solves
clean + accrued = Σ_(k=1..N) (c/f) / (1 + y/f)^(k−1+DSC/E) + 100 / (1 + y/f)^(N−1+DSC/E)
Excel uses Newton's method; here, with z = (1 + y/f)^(−1/E), a per-day
factor, every power is whole (DSC + E(k−1) days), and z is found by bisection
in `math.fractional-power`'s 18-place fixed point, the same floors in the same
order in every language. Then y = f × (z^−E − 1). Yields down to −50% a
coupon period are covered; a price above that is refused.
**One coupon period or less left** (N = 1), Excel's formula, computed exactly:
y = ((100 + c/f) − (clean + accrued)) / (clean + accrued) × (f × E / DSR)
with DSR, days from settlement to redemption, equal to DSC.
**Current yield** = annual coupon / clean price.
Rounding: the yield is settled to 12 decimal places, then rounded half away
from zero to 9 places (`yieldToMaturity`) and to a basis point; current yield
to a basis point half away from zero; accrued interest to 6 places, half up.
## Limits and what it does not do
- Redemption is 100. Price is a decimal string per 100, at most 6 places.
- Only `30-360` and `act-act`. Excel's basis 0 is the US (NASD) 30/360, which
treats the last day of February as the 30th; bond basis here does not, so
the two differ when a coupon date or settlement is at the end of February.
Where that makes settlement count as on or after the next coupon (e.g. a
28 February coupon and settlement on 30 August), it is refused: use
`act-act`.
- No ex-dividend periods (gilts trade ex-dividend 7 business days before a
coupon, with negative accrued interest), no odd first or last coupons, no
business-day adjustment, no call dates. Coupons, not settlement, are what
the caller must line up with the real bond.
- Settlement must be before maturity and within 100 years of it; frequency 1,
2 or 4; coupon 0 to 100000 basis points.
1.0.1 fixes Python accepting a trailing newline in cleanPrice; adds tests.
## Before you rely on this
**Not professional advice.** This capability calculates investment 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 tax adviser 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 tax adviser 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.2 marks it unreviewed. The code and the tests are unchanged.