Documentation
¶
Overview ¶
Package finance provides high-precision financial calculations (annuities, loans, NPV/IRR, rate conversions, amortization schedules) built on top of github.com/TimLai666/go-decimal.
All exported functions use the Excel/Google-Sheets sign convention: money received is positive, money paid out is negative. PMT, FV, and PV therefore typically come back with the opposite sign of one another.
Precision and rounding are configurable per call via the optional Options argument; when omitted, results are produced at scale=10 with HalfUp rounding (internal computation always uses extra guard digits).
Index ¶
- Constants
- Variables
- func AccrInt(issue, firstInterest, settlement time.Time, rate, par decimal.Decimal, ...) (decimal.Decimal, error)
- func AnnualFromContinuous(continuous decimal.Decimal, opts ...Options) (decimal.Decimal, error)
- func ContinuousFromAnnual(effective decimal.Decimal, opts ...Options) (decimal.Decimal, error)
- func CumIPMT(rate decimal.Decimal, nper int, pv decimal.Decimal, startPeriod, endPeriod int, ...) (decimal.Decimal, error)
- func CumPPMT(rate decimal.Decimal, nper int, pv decimal.Decimal, startPeriod, endPeriod int, ...) (decimal.Decimal, error)
- func DDB(cost, salvage decimal.Decimal, life, per int, factor decimal.Decimal, ...) (decimal.Decimal, error)
- func Duration(settlement, maturity time.Time, coupon, yld decimal.Decimal, freq int, ...) (decimal.Decimal, error)
- func EffectiveRate(nominal decimal.Decimal, periodsPerYear int, opts ...Options) (decimal.Decimal, error)
- func FV(rate decimal.Decimal, nper int, pmt, pv decimal.Decimal, timing PaymentTiming, ...) (decimal.Decimal, error)
- func FromFloat(f float64) (decimal.Decimal, error)
- func FromInt(n int) decimal.Decimal
- func IPMT(rate decimal.Decimal, per, nper int, pv, fv decimal.Decimal, ...) (decimal.Decimal, error)
- func IRR(cashflows []decimal.Decimal, guess decimal.Decimal, opts ...Options) (decimal.Decimal, error)
- func MDuration(settlement, maturity time.Time, coupon, yld decimal.Decimal, freq int, ...) (decimal.Decimal, error)
- func MIRR(cashflows []decimal.Decimal, financeRate, reinvestRate decimal.Decimal, ...) (decimal.Decimal, error)
- func MustNew(s string) decimal.Decimal
- func NPER(rate, pmt, pv, fv decimal.Decimal, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
- func NPV(rate decimal.Decimal, cashflows []decimal.Decimal, opts ...Options) (decimal.Decimal, error)
- func NPVExcel(rate decimal.Decimal, cashflows []decimal.Decimal, opts ...Options) (decimal.Decimal, error)
- func New(s string) (decimal.Decimal, error)
- func NominalRate(effective decimal.Decimal, periodsPerYear int, opts ...Options) (decimal.Decimal, error)
- func PMT(rate decimal.Decimal, nper int, pv, fv decimal.Decimal, timing PaymentTiming, ...) (decimal.Decimal, error)
- func PPMT(rate decimal.Decimal, per, nper int, pv, fv decimal.Decimal, ...) (decimal.Decimal, error)
- func PV(rate decimal.Decimal, nper int, pmt, fv decimal.Decimal, timing PaymentTiming, ...) (decimal.Decimal, error)
- func Price(settlement, maturity time.Time, rate, yld, redemption decimal.Decimal, ...) (decimal.Decimal, error)
- func RATE(nper int, pmt, pv, fv decimal.Decimal, timing PaymentTiming, ...) (decimal.Decimal, error)
- func SLN(cost, salvage decimal.Decimal, life int, opts ...Options) (decimal.Decimal, error)
- func SYD(cost, salvage decimal.Decimal, life, per int, opts ...Options) (decimal.Decimal, error)
- func ScheduleTable(rate decimal.Decimal, nper int, pv, fv decimal.Decimal, timing PaymentTiming, ...) (insyra.IDataTable, error)
- func TBillEq(settlement, maturity time.Time, discount decimal.Decimal, opts ...Options) (decimal.Decimal, error)
- func TBillPrice(settlement, maturity time.Time, discount decimal.Decimal, opts ...Options) (decimal.Decimal, error)
- func TBillYield(settlement, maturity time.Time, pr decimal.Decimal, opts ...Options) (decimal.Decimal, error)
- func VDB(cost, salvage decimal.Decimal, life int, ...) (decimal.Decimal, error)
- func XIRR(values []decimal.Decimal, dates []time.Time, guess decimal.Decimal, ...) (decimal.Decimal, error)
- func XNPV(rate decimal.Decimal, values []decimal.Decimal, dates []time.Time, ...) (decimal.Decimal, error)
- func Yield(settlement, maturity time.Time, rate, pr, redemption decimal.Decimal, freq int, ...) (decimal.Decimal, error)
- type AmortizationRow
- type DayCountBasis
- type Options
- type PaymentTiming
- type RoundingMode
Constants ¶
const DefaultScale int32 = 10
DefaultScale is the result scale used when Options.Scale == 0.
Variables ¶
var Zero = decimal.NewFromInt64(internalCtx, 0)
Zero is a convenience zero-valued decimal at the package's internal precision. Pass it as fv (or pv) when a TVM call doesn't need that term.
Functions ¶
func AccrInt ¶
func AccrInt(issue, firstInterest, settlement time.Time, rate, par decimal.Decimal, freq int, basis DayCountBasis, calcMethod bool, opts ...Options) (decimal.Decimal, error)
AccrInt returns the accrued interest of a security that pays periodic interest. With calcMethod=true, accrual is computed from issue to settlement; with calcMethod=false, accrual starts at firstInterest (matching Excel's behavior for bonds purchased after the first coupon date but before maturity).
Excel equivalent: ACCRINT(issue, first_interest, settlement, rate, par, frequency, basis, calc_method)
func AnnualFromContinuous ¶
AnnualFromContinuous converts a continuously compounded rate ρ into the equivalent effective annual rate, exp(ρ) - 1.
func ContinuousFromAnnual ¶
ContinuousFromAnnual converts an effective annual rate r into the continuously compounded rate that yields the same growth, ln(1+r).
func CumIPMT ¶
func CumIPMT(rate decimal.Decimal, nper int, pv decimal.Decimal, startPeriod, endPeriod int, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
CumIPMT returns the cumulative interest paid between periods startPeriod and endPeriod (inclusive, 1-indexed).
Excel equivalent: CUMIPMT(rate, nper, pv, start_period, end_period, type)
func CumPPMT ¶
func CumPPMT(rate decimal.Decimal, nper int, pv decimal.Decimal, startPeriod, endPeriod int, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
CumPPMT returns the cumulative principal paid between periods startPeriod and endPeriod (inclusive, 1-indexed).
Excel equivalent: CUMPRINC(rate, nper, pv, start_period, end_period, type)
func DDB ¶
func DDB(cost, salvage decimal.Decimal, life, per int, factor decimal.Decimal, opts ...Options) (decimal.Decimal, error)
DDB returns the depreciation in the per-th period under the double-declining-balance method (or any declining-balance method determined by factor). The rate is factor/life applied to the remaining book value, capped so the asset never depreciates below salvage.
factor=2 is the conventional double-declining choice (Excel's default). Pass finance.MustNew("1.5") for 150%-DB, etc.
Excel equivalent: DDB(cost, salvage, life, period, factor)
func Duration ¶
func Duration(settlement, maturity time.Time, coupon, yld decimal.Decimal, freq int, basis DayCountBasis, opts ...Options) (decimal.Decimal, error)
Duration returns the Macaulay duration of a bond.
D = Σ t_k · PV(cf_k) / Σ PV(cf_k)
where t_k is the time to cashflow k in years from settlement.
Excel equivalent: DURATION(settlement, maturity, coupon, yld, frequency, basis)
func EffectiveRate ¶
func EffectiveRate(nominal decimal.Decimal, periodsPerYear int, opts ...Options) (decimal.Decimal, error)
EffectiveRate converts a nominal annual rate compounded periodsPerYear times per year into the effective annual rate.
effective = (1 + nominal/m)^m - 1
Excel equivalent: EFFECT(nominal_rate, npery)
func FV ¶
func FV(rate decimal.Decimal, nper int, pmt, pv decimal.Decimal, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
FV computes the future value of an annuity given the periodic rate, number of periods, periodic payment, present value, and payment timing.
Excel equivalent: FV(rate, nper, pmt, pv, type)
func FromFloat ¶
FromFloat converts a float64 to a Decimal. Use sparingly: float inputs already carry binary rounding error before they reach the decimal layer.
func IPMT ¶
func IPMT(rate decimal.Decimal, per, nper int, pv, fv decimal.Decimal, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
IPMT returns the interest portion of the per-th payment.
Excel equivalent: IPMT(rate, per, nper, pv, fv, type)
per is 1-indexed. With PaymentBegin (type=1), the first payment has IPMT=0 because no interest has accrued by t=0.
func IRR ¶
func IRR(cashflows []decimal.Decimal, guess decimal.Decimal, opts ...Options) (decimal.Decimal, error)
IRR computes the internal rate of return for a cashflow stream starting at t=0. Uses Newton's method seeded at guess (0.1 if guess is the zero Decimal, matching Excel's default).
Returns an error if the iteration fails to converge — most often because the cashflow stream has no real-valued IRR or because the initial guess is far from any root. Pass a custom guess close to the expected rate to recover.
Excel equivalent: IRR(values, [guess])
func MDuration ¶
func MDuration(settlement, maturity time.Time, coupon, yld decimal.Decimal, freq int, basis DayCountBasis, opts ...Options) (decimal.Decimal, error)
MDuration returns the modified duration of a bond:
MD = Duration / (1 + yld/freq)
Excel equivalent: MDURATION(settlement, maturity, coupon, yld, frequency, basis)
func MIRR ¶
func MIRR(cashflows []decimal.Decimal, financeRate, reinvestRate decimal.Decimal, opts ...Options) (decimal.Decimal, error)
MIRR computes the modified internal rate of return.
Unlike IRR, MIRR distinguishes between the rate at which negative (financing) cashflows are discounted and the rate at which positive (reinvestment) cashflows are compounded:
MIRR = (FV(positive_cf @ reinvestRate) / -PV(negative_cf @ financeRate))^(1/n) - 1
where n is the number of periods spanned (len(cashflows) - 1). Positive cashflows are compounded forward to t=n at reinvestRate; negative cashflows are discounted back to t=0 at financeRate.
Excel equivalent: MIRR(values, finance_rate, reinvest_rate)
func NPER ¶
func NPER(rate, pmt, pv, fv decimal.Decimal, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
NPER computes the number of periods required to satisfy the TVM equation. May return a non-integer value (the last period is then a partial period); round up if you need a whole-period count.
Excel equivalent: NPER(rate, pmt, pv, fv, type)
func NPV ¶
func NPV(rate decimal.Decimal, cashflows []decimal.Decimal, opts ...Options) (decimal.Decimal, error)
NPV returns the net present value of a stream of cashflows where cashflows[0] is the cashflow at t=0, cashflows[1] at t=1, and so on.
NPV = Σ cashflows[i] / (1+rate)^i
This convention (t=0 first) matches numpy_financial.npv and is the natural input for IRR. It differs from Excel's NPV, which assumes the first value is at t=1; see NPVExcel for that variant.
func NPVExcel ¶
func NPVExcel(rate decimal.Decimal, cashflows []decimal.Decimal, opts ...Options) (decimal.Decimal, error)
NPVExcel matches Excel's NPV(rate, value1, value2, ...): the first cashflow is treated as occurring at t=1 (not t=0). Provided for users porting spreadsheets verbatim.
func New ¶
New parses s as a decimal at the package's internal precision (28 digits). Use this to build inputs for finance functions from human-readable strings.
rate := finance.MustNew("0.00375")
pv := finance.MustNew("250000")
func NominalRate ¶
func NominalRate(effective decimal.Decimal, periodsPerYear int, opts ...Options) (decimal.Decimal, error)
NominalRate converts an effective annual rate into the equivalent nominal annual rate that, when compounded periodsPerYear times per year, yields the same effective annual rate.
nominal = m * ((1 + effective)^(1/m) - 1)
Excel equivalent: NOMINAL(effect_rate, npery)
func PMT ¶
func PMT(rate decimal.Decimal, nper int, pv, fv decimal.Decimal, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
PMT computes the periodic payment of an annuity given an interest rate per period, total number of periods, present value, future value, and payment timing. Result follows Excel's sign convention: PMT comes back with the opposite sign of (PV + FV).
rate := finance.MustNew("0.005") // 0.5% / month
pv := finance.MustNew("100000") // borrow 100,000
pmt, _ := finance.PMT(rate, 360, pv, finance.Zero, finance.PaymentEnd)
// pmt ≈ -599.5505... (you pay ~599.55 per month)
Excel equivalent: PMT(rate, nper, pv, fv, type)
func PPMT ¶
func PPMT(rate decimal.Decimal, per, nper int, pv, fv decimal.Decimal, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
PPMT returns the principal portion of the per-th payment. By definition PMT = IPMT + PPMT for every period, so PPMT is computed as PMT - IPMT in the same units.
Excel equivalent: PPMT(rate, per, nper, pv, fv, type)
func PV ¶
func PV(rate decimal.Decimal, nper int, pmt, fv decimal.Decimal, timing PaymentTiming, opts ...Options) (decimal.Decimal, error)
PV computes the present value of an annuity (or loan) given the periodic rate, number of periods, periodic payment, future value, and payment timing.
Excel equivalent: PV(rate, nper, pmt, fv, type)
func Price ¶
func Price(settlement, maturity time.Time, rate, yld, redemption decimal.Decimal, freq int, basis DayCountBasis, opts ...Options) (decimal.Decimal, error)
Price returns the bond's price per $100 face value given its annual coupon rate, yield, redemption value, frequency, and day-count basis.
Excel equivalent: PRICE(settlement, maturity, rate, yld, redemption, frequency, basis)
func RATE ¶
func RATE(nper int, pmt, pv, fv decimal.Decimal, timing PaymentTiming, guess decimal.Decimal, opts ...Options) (decimal.Decimal, error)
RATE solves for the periodic interest rate that satisfies the TVM equation, using Newton's method seeded at 10% (Excel's default guess). Returns an error if the iteration fails to converge.
Excel equivalent: RATE(nper, pmt, pv, fv, type, [guess])
Pass an initial guess via guess. When guess is omitted, 0.1 is used.
func SLN ¶
SLN returns the straight-line depreciation per period:
SLN = (cost - salvage) / life
Excel equivalent: SLN(cost, salvage, life)
func SYD ¶
SYD returns the depreciation in the per-th period under the sum-of-years-digits method:
SYD = (cost - salvage) · (life - per + 1) / (life · (life + 1) / 2)
Excel equivalent: SYD(cost, salvage, life, per)
func ScheduleTable ¶
func ScheduleTable(rate decimal.Decimal, nper int, pv, fv decimal.Decimal, timing PaymentTiming, opts ...Options) (insyra.IDataTable, error)
ScheduleTable returns the amortization schedule as an insyra DataTable with columns: Period, Payment, Interest, Principal, Balance. Numeric columns are stored as decimal.Decimal values so the table preserves the precision of the source calculation; convert via .String() if you need a textual export.
func TBillEq ¶
func TBillEq(settlement, maturity time.Time, discount decimal.Decimal, opts ...Options) (decimal.Decimal, error)
TBillEq returns the bond-equivalent yield of a Treasury bill.
TBILLEQ = 365 · discount / (360 - discount · DSM)
where DSM is the number of calendar days from settlement to maturity. Returns an error if maturity ≤ settlement or DSM > 365.
Excel equivalent: TBILLEQ(settlement, maturity, discount)
func TBillPrice ¶
func TBillPrice(settlement, maturity time.Time, discount decimal.Decimal, opts ...Options) (decimal.Decimal, error)
TBillPrice returns the price per $100 face value of a Treasury bill at the given discount rate.
TBILLPRICE = 100 · (1 - discount · DSM / 360)
Excel equivalent: TBILLPRICE(settlement, maturity, discount)
func TBillYield ¶
func TBillYield(settlement, maturity time.Time, pr decimal.Decimal, opts ...Options) (decimal.Decimal, error)
TBillYield returns the yield of a Treasury bill given its price per $100 face value.
TBILLYIELD = ((100 - pr) / pr) · (360 / DSM)
Excel equivalent: TBILLYIELD(settlement, maturity, pr)
func VDB ¶
func VDB(cost, salvage decimal.Decimal, life int, startPeriod, endPeriod, factor decimal.Decimal, noSwitch bool, opts ...Options) (decimal.Decimal, error)
VDB returns the cumulative depreciation between startPeriod and endPeriod under the variable declining-balance method.
startPeriod and endPeriod are real numbers in [0, life]; partial periods are pro-rated linearly within whatever depreciation method applies in that period. With noSwitch=false (Excel's default), the method automatically switches to straight-line for the remaining life as soon as straight-line would yield more depreciation than declining balance — which is what most US tax schedules require.
Excel equivalent: VDB(cost, salvage, life, start_period, end_period, factor, no_switch)
func XIRR ¶
func XIRR(values []decimal.Decimal, dates []time.Time, guess decimal.Decimal, opts ...Options) (decimal.Decimal, error)
XIRR returns the rate that drives XNPV to zero. Uses Newton's method seeded at guess (or 0.1 if guess is the zero Decimal).
Excel equivalent: XIRR(values, dates, [guess])
func XNPV ¶
func XNPV(rate decimal.Decimal, values []decimal.Decimal, dates []time.Time, opts ...Options) (decimal.Decimal, error)
XNPV returns the net present value of a stream of cashflows that occur on arbitrary dates. dates[0] is treated as the reference (t=0) and every other cashflow is discounted by (dates[i] - dates[0]) / 365 years, matching Excel's convention.
XNPV = Σ values[i] / (1 + rate)^((dates[i] - dates[0]) / 365)
Excel equivalent: XNPV(rate, values, dates)
func Yield ¶
func Yield(settlement, maturity time.Time, rate, pr, redemption decimal.Decimal, freq int, basis DayCountBasis, guess decimal.Decimal, opts ...Options) (decimal.Decimal, error)
Yield solves for the bond yield that reproduces the given price per $100 face. Uses Newton's method with a finite-difference derivative seeded at the provided guess (or 0.05 if guess is the zero Decimal).
Excel equivalent: YIELD(settlement, maturity, rate, pr, redemption, frequency, basis)
Types ¶
type AmortizationRow ¶
type AmortizationRow struct {
Period int // 1-indexed period number
Payment decimal.Decimal // total payment in this period (constant)
Interest decimal.Decimal // interest portion of the payment
Principal decimal.Decimal // principal portion of the payment
Balance decimal.Decimal // remaining balance after this payment
}
AmortizationRow is one row in an amortization schedule. Values are kept as decimal.Decimal so callers don't lose precision when reading back individual entries.
func AmortizationSchedule ¶
func AmortizationSchedule(rate decimal.Decimal, nper int, pv, fv decimal.Decimal, timing PaymentTiming, opts ...Options) ([]AmortizationRow, error)
AmortizationSchedule returns the full per-period amortization schedule of a level-payment loan. Use ScheduleTable for an insyra.IDataTable representation suitable for printing or export.
type DayCountBasis ¶
type DayCountBasis uint8
DayCountBasis selects how day counts and year lengths are computed in bond and ACCRINT-style functions. Values match Excel's "basis" parameter exactly.
const ( // Basis30_360US is the US (NASD) 30/360 convention. Excel basis = 0. Basis30_360US DayCountBasis = 0 // BasisActualActual uses calendar days for both numerator and a // year length derived from the years actually spanned by the // period (ISDA actual/actual). Excel basis = 1. BasisActualActual DayCountBasis = 1 // BasisActual360 uses calendar days over a 360-day year — common // for money-market instruments. Excel basis = 2. BasisActual360 DayCountBasis = 2 // BasisActual365 uses calendar days over a fixed 365-day year. // Excel basis = 3. BasisActual365 DayCountBasis = 3 // Basis30_360EU is the European 30/360 convention. Excel basis = 4. Basis30_360EU DayCountBasis = 4 )
type Options ¶
type Options struct {
// Scale is the number of decimal places kept in the result.
// When 0, DefaultScale (10) is used.
Scale int32
// Mode is the rounding mode applied to the result. When empty,
// RoundHalfUp is used. Available values: RoundHalfUp, RoundHalfEven,
// RoundHalfDown, RoundUp, RoundDown, RoundCeiling, RoundFloor,
// Round05Up, RoundUnnecessary.
Mode RoundingMode
}
Options controls precision and rounding of finance results. Zero-value Options selects the high-precision defaults: Scale=10 and RoundHalfUp. Scale and Mode resolve independently — leaving either at its zero value (0 / "") keeps that field's default while letting the other be customized.
type PaymentTiming ¶
type PaymentTiming uint8
PaymentTiming indicates whether an annuity payment occurs at the end of each period (ordinary annuity, Excel's type=0) or at the beginning (annuity due, Excel's type=1).
const ( // PaymentEnd places each payment at the end of its period. // Equivalent to Excel's type=0. This is the default. PaymentEnd PaymentTiming = 0 // PaymentBegin places each payment at the start of its period. // Equivalent to Excel's type=1. PaymentBegin PaymentTiming = 1 )
type RoundingMode ¶
type RoundingMode string
RoundingMode is a string-typed selector for the rounding strategy applied to finance results. A string enum is used (rather than the underlying decimal.RoundingMode uint8) so that the empty string is unambiguously "use default" — there is no zero-value collision with any real mode.
const ( // RoundHalfUp is the everyday 四捨五入 rule: half values move away // from zero. 1.235 → 1.24, -1.235 → -1.24. This is the default. RoundHalfUp RoundingMode = "half-up" // RoundHalfEven is banker's rounding (IEEE 754 / Python decimal // default): half values pick the neighbor whose last digit is // even, eliminating HalfUp's systematic upward bias on long sums. // 1.225 → 1.22, 1.235 → 1.24. RoundHalfEven RoundingMode = "half-even" // RoundHalfDown is "round half toward zero": half values stay put // rather than stepping away. 1.235 → 1.23, -1.235 → -1.23. RoundHalfDown RoundingMode = "half-down" // RoundUp rounds away from zero on any non-zero residue. // 1.231 → 1.24, -1.231 → -1.24. RoundUp RoundingMode = "up" // RoundDown truncates toward zero (the absolute value never grows). // 1.235 → 1.23, -1.235 → -1.23. RoundDown RoundingMode = "down" // RoundCeiling rounds toward +∞ on any non-zero residue. // 1.231 → 1.24, -1.231 → -1.23. RoundCeiling RoundingMode = "ceiling" // RoundFloor rounds toward -∞ on any non-zero residue. // 1.231 → 1.23, -1.231 → -1.24. RoundFloor RoundingMode = "floor" // Round05Up implements Python's ROUND_05UP rule: after truncating // toward zero, if the kept last digit is 0 or 5 then any non-zero // residue causes a step away from zero; otherwise the residue is // dropped. Round05Up RoundingMode = "05up" // RoundUnnecessary asserts that no rounding will be required. If // an operation under this mode has to discard a non-zero residue, // it panics with decimal.ErrRoundingNecessary. RoundUnnecessary RoundingMode = "unnecessary" )