@pyverret/ratejs 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -15
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -8,6 +8,24 @@ Lightweight, dependency-free TypeScript financial math library providing pure ca
|
|
|
8
8
|
npm i @pyverret/ratejs
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Validate Before Push
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm run validate
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Automated Releases
|
|
18
|
+
|
|
19
|
+
Releases are managed by `semantic-release` on pushes to `main`.
|
|
20
|
+
|
|
21
|
+
Required GitHub secrets:
|
|
22
|
+
- `NPM_TOKEN`: npm automation token with publish access.
|
|
23
|
+
|
|
24
|
+
Behavior:
|
|
25
|
+
- Conventional Commits drive version bumps (`fix` = patch, `feat` = minor, `feat!` or `BREAKING CHANGE` = major).
|
|
26
|
+
- Release workflow runs `npm run validate` before publishing.
|
|
27
|
+
- Git tags use format `vX.Y.Z`.
|
|
28
|
+
|
|
11
29
|
## Live Demo
|
|
12
30
|
|
|
13
31
|
- GitHub Pages URL: `https://pyverret.github.io/ratejs/`
|
|
@@ -44,16 +62,19 @@ const payment = pmt({
|
|
|
44
62
|
ratePerPeriod: 0.06 / 12,
|
|
45
63
|
periods: 360,
|
|
46
64
|
presentValue: 250000,
|
|
47
|
-
futureValue: 0,
|
|
48
|
-
timing: "end",
|
|
65
|
+
futureValue: 0, // optional
|
|
66
|
+
timing: "end", // optional
|
|
49
67
|
});
|
|
50
68
|
|
|
51
69
|
const impliedRate = rate({
|
|
52
70
|
periods: 360,
|
|
53
71
|
payment,
|
|
54
72
|
presentValue: 250000,
|
|
55
|
-
futureValue: 0,
|
|
56
|
-
timing: "end",
|
|
73
|
+
futureValue: 0, // optional
|
|
74
|
+
timing: "end", // optional
|
|
75
|
+
guess: 0.1, // optional
|
|
76
|
+
maxIterations: 100, // optional
|
|
77
|
+
tolerance: 1e-10, // optional
|
|
57
78
|
lowerBound: -0.99, // optional
|
|
58
79
|
upperBound: 10, // optional
|
|
59
80
|
});
|
|
@@ -89,11 +110,11 @@ presentValue({ futureValue: 5000, rate: 0.06, timesPerYear: 12, years: 5 });
|
|
|
89
110
|
```ts
|
|
90
111
|
investmentGrowth({
|
|
91
112
|
initial: 1000,
|
|
92
|
-
contributionPerPeriod: 100,
|
|
113
|
+
contributionPerPeriod: 100, // optional
|
|
93
114
|
rate: 0.06,
|
|
94
115
|
timesPerYear: 12,
|
|
95
116
|
years: 2,
|
|
96
|
-
contributionTiming: "end", //
|
|
117
|
+
contributionTiming: "end", // optional ("end" | "begin")
|
|
97
118
|
});
|
|
98
119
|
```
|
|
99
120
|
|
|
@@ -112,7 +133,8 @@ periodsToReachGoal({
|
|
|
112
133
|
rate: 0.06,
|
|
113
134
|
timesPerYear: 12,
|
|
114
135
|
contributionPerPeriod: 0, // optional
|
|
115
|
-
contributionTiming: "end",
|
|
136
|
+
contributionTiming: "end", // optional
|
|
137
|
+
maxPeriods: 100000, // optional
|
|
116
138
|
});
|
|
117
139
|
```
|
|
118
140
|
|
|
@@ -120,6 +142,7 @@ Edge cases:
|
|
|
120
142
|
- Returns `Infinity` when the goal is unreachable.
|
|
121
143
|
- Throws `RangeError` when `rate / timesPerYear <= -1`.
|
|
122
144
|
- Throws `RangeError` when `maxPeriods` is exceeded for contribution-based iteration.
|
|
145
|
+
- Throws `RangeError` when `contributionTiming` is not `"end"` or `"begin"`.
|
|
123
146
|
|
|
124
147
|
- **`rateToReachGoal`** - Rate per period required to reach a target future value in a given number of periods.
|
|
125
148
|
|
|
@@ -128,8 +151,10 @@ rateToReachGoal({
|
|
|
128
151
|
principal: 1000,
|
|
129
152
|
targetFutureValue: 1500,
|
|
130
153
|
periods: 24,
|
|
131
|
-
contributionPerPeriod: 0,
|
|
132
|
-
contributionTiming: "end",
|
|
154
|
+
contributionPerPeriod: 0, // optional
|
|
155
|
+
contributionTiming: "end", // optional
|
|
156
|
+
maxIterations: 100, // optional
|
|
157
|
+
tolerance: 1e-10, // optional
|
|
133
158
|
lowerBound: -0.99, // optional
|
|
134
159
|
upperBound: 10, // optional
|
|
135
160
|
});
|
|
@@ -137,6 +162,7 @@ rateToReachGoal({
|
|
|
137
162
|
|
|
138
163
|
Edge cases:
|
|
139
164
|
- Throws `RangeError` when no root is found within search bounds.
|
|
165
|
+
- Throws `RangeError` when `contributionTiming` is not `"end"` or `"begin"`.
|
|
140
166
|
|
|
141
167
|
- **`ruleOf72`** - Approximate years to double a lump sum at a given annual rate. Optional `constant: 69` for rule of 69.
|
|
142
168
|
|
|
@@ -158,8 +184,8 @@ cagr({ startValue: 1000, endValue: 2000, years: 10 });
|
|
|
158
184
|
```ts
|
|
159
185
|
irr({
|
|
160
186
|
cashFlows: [-1000, 300, 400, 500],
|
|
161
|
-
guess: 0.1,
|
|
162
|
-
maxIterations: 100,
|
|
187
|
+
guess: 0.1, // optional
|
|
188
|
+
maxIterations: 100, // optional
|
|
163
189
|
lowerBound: -0.99, // optional
|
|
164
190
|
upperBound: 10, // optional
|
|
165
191
|
});
|
|
@@ -204,7 +230,7 @@ presentValueOfAnnuity({
|
|
|
204
230
|
paymentPerPeriod: 100,
|
|
205
231
|
ratePerPeriod: 0.01,
|
|
206
232
|
periods: 36,
|
|
207
|
-
timing: "end",
|
|
233
|
+
timing: "end", // optional
|
|
208
234
|
});
|
|
209
235
|
```
|
|
210
236
|
|
|
@@ -215,7 +241,7 @@ paymentFromPresentValue({
|
|
|
215
241
|
presentValue: 100000,
|
|
216
242
|
ratePerPeriod: 0.005,
|
|
217
243
|
periods: 360,
|
|
218
|
-
timing: "end",
|
|
244
|
+
timing: "end", // optional
|
|
219
245
|
});
|
|
220
246
|
```
|
|
221
247
|
|
|
@@ -243,7 +269,7 @@ amortizationSchedule({
|
|
|
243
269
|
annualRate: 0.06,
|
|
244
270
|
paymentsPerYear: 12,
|
|
245
271
|
years: 30,
|
|
246
|
-
extraPaymentPerPeriod: 50,
|
|
272
|
+
extraPaymentPerPeriod: 50, // optional
|
|
247
273
|
});
|
|
248
274
|
```
|
|
249
275
|
|
|
@@ -280,7 +306,7 @@ Edge cases:
|
|
|
280
306
|
|
|
281
307
|
```ts
|
|
282
308
|
roundToCurrency({ value: 2.125 }); // 2.13
|
|
283
|
-
roundToCurrency({ value: 2.125, decimals: 2, mode: "half-even" });
|
|
309
|
+
roundToCurrency({ value: 2.125, decimals: 2, mode: "half-even" }); // decimals/mode optional
|
|
284
310
|
```
|
|
285
311
|
|
|
286
312
|
## Design
|
package/dist/index.cjs
CHANGED
|
@@ -301,6 +301,11 @@ function paymentFromPresentValue(params) {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
// src/interest/periodsToReachGoal.ts
|
|
304
|
+
function assertContributionTiming(value, name) {
|
|
305
|
+
if (value !== "end" && value !== "begin") {
|
|
306
|
+
throw new RangeError(`${name} must be "end" or "begin"`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
304
309
|
function periodsToReachGoal(params) {
|
|
305
310
|
const {
|
|
306
311
|
principal,
|
|
@@ -317,6 +322,7 @@ function periodsToReachGoal(params) {
|
|
|
317
322
|
assertPositive(timesPerYear, "timesPerYear");
|
|
318
323
|
assertNonNegative(contributionPerPeriod, "contributionPerPeriod");
|
|
319
324
|
assertPositive(maxPeriods, "maxPeriods");
|
|
325
|
+
assertContributionTiming(contributionTiming, "contributionTiming");
|
|
320
326
|
if (targetFutureValue <= principal) return 0;
|
|
321
327
|
const r = rate2 / timesPerYear;
|
|
322
328
|
if (r <= -1) {
|
|
@@ -372,6 +378,11 @@ function presentValueOfAnnuity(params) {
|
|
|
372
378
|
}
|
|
373
379
|
|
|
374
380
|
// src/interest/rateToReachGoal.ts
|
|
381
|
+
function assertContributionTiming2(value, name) {
|
|
382
|
+
if (value !== "end" && value !== "begin") {
|
|
383
|
+
throw new RangeError(`${name} must be "end" or "begin"`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
375
386
|
function rateToReachGoal(params) {
|
|
376
387
|
const {
|
|
377
388
|
principal,
|
|
@@ -392,13 +403,13 @@ function rateToReachGoal(params) {
|
|
|
392
403
|
assertFiniteNumber(upperBound, "upperBound");
|
|
393
404
|
assertFiniteNumber(maxIterations, "maxIterations");
|
|
394
405
|
assertFiniteNumber(tolerance, "tolerance");
|
|
406
|
+
assertContributionTiming2(contributionTiming, "contributionTiming");
|
|
395
407
|
if (lowerBound <= -1) throw new RangeError("lowerBound must be > -1");
|
|
396
408
|
if (upperBound <= lowerBound) throw new RangeError("upperBound must be greater than lowerBound");
|
|
397
409
|
if (!Number.isInteger(maxIterations) || maxIterations <= 0) {
|
|
398
410
|
throw new RangeError("maxIterations must be a positive integer");
|
|
399
411
|
}
|
|
400
412
|
if (tolerance <= 0) throw new RangeError("tolerance must be > 0");
|
|
401
|
-
if (periods === 0) return 0;
|
|
402
413
|
if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;
|
|
403
414
|
if (contributionPerPeriod === 0) {
|
|
404
415
|
if (targetFutureValue <= principal) return 0;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/assertions.ts","../src/interest/cagr.ts","../src/interest/compound.ts","../src/interest/effectiveAnnualRate.ts","../src/interest/futureValue.ts","../src/interest/inflationAdjustedAmount.ts","../src/interest/investmentGrowth.ts","../src/utils/solvers.ts","../src/interest/irr.ts","../src/interest/npv.ts","../src/interest/paymentFromPresentValue.ts","../src/interest/periodsToReachGoal.ts","../src/interest/presentValue.ts","../src/interest/presentValueOfAnnuity.ts","../src/interest/rateToReachGoal.ts","../src/interest/realReturn.ts","../src/interest/ruleOf72.ts","../src/interest/tvom.ts","../src/loans/loanPayment.ts","../src/loans/amortizationSchedule.ts","../src/loans/payoffPeriodWithExtra.ts","../src/loans/remainingBalance.ts","../src/utils/roundToCurrency.ts"],"names":["rate","presentValue","futureValue","pmt","fv","pv","findBracket"],"mappings":"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","file":"index.cjs","sourcesContent":["export function assertFiniteNumber(value: number, name: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be a finite number`);\n }\n}\n\nexport function assertNonNegative(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value < 0) {\n throw new RangeError(`${name} must be >= 0`);\n }\n}\n\nexport function assertPositive(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be > 0`);\n }\n}\n","import { assertPositive } from \"../utils/assertions.js\";\n\nexport type CagrParams = {\n startValue: number;\n endValue: number;\n years: number;\n};\n\n/**\n * Compound annual growth rate (CAGR) between start and end value over the given years.\n * CAGR = (endValue/startValue)^(1/years) - 1\n */\nexport function cagr(params: CagrParams): number {\n const { startValue, endValue, years } = params;\n assertPositive(startValue, \"startValue\");\n assertPositive(years, \"years\");\n if (endValue <= 0) return -1;\n return (endValue / startValue) ** (1 / years) - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type CompoundParams = {\n principal: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Computes compound growth using nominal annual `rate` compounded `timesPerYear`.\n * Returns the final amount (principal + interest).\n */\nexport function compound(params: CompoundParams): number {\n const { principal, rate, timesPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return principal;\n\n const n = timesPerYear;\n const t = years;\n return principal * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type EffectiveAnnualRateParams = {\n nominalRate: number;\n timesPerYear: number;\n};\n\n/**\n * Converts a nominal annual rate to effective annual rate (EAR).\n * EAR = (1 + nominalRate/timesPerYear)^timesPerYear - 1\n */\nexport function effectiveAnnualRate(params: EffectiveAnnualRateParams): number {\n const { nominalRate, timesPerYear } = params;\n assertFiniteNumber(nominalRate, \"nominalRate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n\n const r = nominalRate / timesPerYear;\n return (1 + r) ** timesPerYear - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type FutureValueParams = {\n presentValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Future value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function futureValue(params: FutureValueParams): number {\n const { presentValue, rate, timesPerYear, years } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return presentValue;\n\n const n = timesPerYear;\n const t = years;\n return presentValue * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertNonNegative } from \"../utils/assertions.js\";\n\nexport type InflationAdjustedAmountParams = {\n amount: number;\n annualInflationRate: number;\n years: number;\n direction: \"toPast\" | \"toFuture\";\n};\n\n/**\n * Purchasing power across time. toPast: amount/(1+rate)^years. toFuture: amount*(1+rate)^years.\n */\nexport function inflationAdjustedAmount(params: InflationAdjustedAmountParams): number {\n const { amount, annualInflationRate, years, direction } = params;\n assertFiniteNumber(amount, \"amount\");\n assertFiniteNumber(annualInflationRate, \"annualInflationRate\");\n assertNonNegative(years, \"years\");\n const factor = (1 + annualInflationRate) ** years;\n return direction === \"toPast\" ? amount / factor : amount * factor;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type InvestmentGrowthParams = {\n initial: number;\n contributionPerPeriod?: number;\n rate: number;\n timesPerYear: number;\n years: number;\n contributionTiming?: \"end\" | \"begin\";\n};\n\nexport type InvestmentGrowthResult = {\n futureValue: number;\n totalContributions: number;\n totalInterest: number;\n};\n\n/**\n * Future value of an investment with optional periodic contributions.\n *\n * - `rate` is nominal annual rate (e.g. 0.05 for 5%)\n * - contributions occur each compounding period (`timesPerYear`)\n */\nexport function investmentGrowth(params: InvestmentGrowthParams): InvestmentGrowthResult {\n const {\n initial,\n contributionPerPeriod = 0,\n rate,\n timesPerYear,\n years,\n contributionTiming = \"end\",\n } = params;\n\n assertNonNegative(initial, \"initial\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n const periods = Math.round(timesPerYear * years);\n if (periods === 0) {\n return {\n futureValue: initial,\n totalContributions: 0,\n totalInterest: 0,\n };\n }\n\n const r = rate / timesPerYear;\n\n // Lump sum growth\n const fvInitial = rate === 0 ? initial : initial * (1 + r) ** periods;\n\n // Annuity future value (ordinary vs due)\n let fvContrib = 0;\n if (contributionPerPeriod !== 0) {\n if (rate === 0) {\n fvContrib = contributionPerPeriod * periods;\n } else {\n const ordinary = contributionPerPeriod * (((1 + r) ** periods - 1) / r);\n fvContrib = contributionTiming === \"begin\" ? ordinary * (1 + r) : ordinary;\n }\n }\n\n const futureValue = fvInitial + fvContrib;\n const totalContributions = contributionPerPeriod * periods;\n const totalInterest = futureValue - initial - totalContributions;\n\n return { futureValue, totalContributions, totalInterest };\n}\n","export type NewtonRaphsonParams = {\n initialGuess: number;\n fn: (x: number) => number;\n derivative: (x: number) => number;\n tolerance?: number;\n maxIterations?: number;\n min?: number;\n max?: number;\n};\n\nexport function newtonRaphson(params: NewtonRaphsonParams): number | undefined {\n const {\n initialGuess,\n fn,\n derivative,\n tolerance = 1e-10,\n maxIterations = 100,\n min = Number.NEGATIVE_INFINITY,\n max = Number.POSITIVE_INFINITY,\n } = params;\n\n let x = initialGuess;\n for (let i = 0; i < maxIterations; i++) {\n const value = fn(x);\n if (!Number.isFinite(value)) return undefined;\n if (Math.abs(value) <= tolerance) return x;\n\n const slope = derivative(x);\n if (!Number.isFinite(slope) || Math.abs(slope) < 1e-14) return undefined;\n\n x -= value / slope;\n if (x < min) x = min;\n if (x > max) x = max;\n }\n\n return undefined;\n}\n\nexport type BisectionParams = {\n fn: (x: number) => number;\n lower: number;\n upper: number;\n tolerance?: number;\n maxIterations?: number;\n};\n\nexport function bisection(params: BisectionParams): number | undefined {\n const { fn, lower, upper, tolerance = 1e-10, maxIterations = 200 } = params;\n let a = lower;\n let b = upper;\n let fa = fn(a);\n let fb = fn(b);\n\n if (!Number.isFinite(fa) || !Number.isFinite(fb) || fa * fb > 0) return undefined;\n if (Math.abs(fa) <= tolerance) return a;\n if (Math.abs(fb) <= tolerance) return b;\n\n for (let i = 0; i < maxIterations; i++) {\n const c = (a + b) / 2;\n const fc = fn(c);\n if (!Number.isFinite(fc)) return undefined;\n if (Math.abs(fc) <= tolerance || Math.abs(b - a) <= tolerance) return c;\n\n if (fa * fc < 0) {\n b = c;\n fb = fc;\n } else {\n a = c;\n fa = fc;\n }\n }\n\n return (a + b) / 2;\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type IrrParams = {\n cashFlows: number[];\n guess?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\nfunction npvAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n\nfunction npvDerivativeAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 1; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum -= (t * cf) / (1 + rate) ** (t + 1);\n }\n return sum;\n}\n\nfunction hasPositiveAndNegative(cashFlows: number[]): boolean {\n let hasPositive = false;\n let hasNegative = false;\n for (const cf of cashFlows) {\n if (cf > 0) hasPositive = true;\n if (cf < 0) hasNegative = true;\n if (hasPositive && hasNegative) return true;\n }\n return false;\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n\nexport function irr(params: IrrParams): number {\n const {\n cashFlows,\n guess = 0.1,\n maxIterations = 100,\n lowerBound = -0.99,\n upperBound = 10,\n } = params;\n if (cashFlows.length === 0) {\n throw new RangeError(\"cashFlows must contain at least one value\");\n }\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n if (maxIterations <= 0 || !Number.isInteger(maxIterations)) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (lowerBound <= -1) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n\n for (const cf of cashFlows) assertFiniteNumber(cf, \"cashFlows[]\");\n if (!hasPositiveAndNegative(cashFlows)) {\n throw new RangeError(\"cashFlows must include at least one positive and one negative value\");\n }\n\n const fn = (rate: number) => npvAt(rate, cashFlows);\n const derivative = (rate: number) => npvDerivativeAt(rate, cashFlows);\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance: 1e-10,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"IRR did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance: 1e-10,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"IRR did not converge\");\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type NpvParams = {\n rate: number;\n cashFlows: number[];\n};\n\n/**\n * Net present value at a discount `rate`.\n * cashFlows[0] is the period-0 cash flow.\n */\nexport function npv(params: NpvParams): number {\n const { rate, cashFlows } = params;\n assertFiniteNumber(rate, \"rate\");\n if (rate <= -1) throw new RangeError(\"rate must be > -1\");\n if (cashFlows.length === 0) return 0;\n\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf === undefined) continue;\n assertFiniteNumber(cf, `cashFlows[${t}]`);\n sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PaymentFromPresentValueParams = {\n presentValue: number;\n ratePerPeriod: number;\n periods: number;\n /** Payment at start of each period (annuity due). Default end (ordinary). */\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Periodic payment required to pay off a present value (e.g. loan) over periods.\n * PMT = PV * r / (1 - (1+r)^-n). For due: divide by (1+r).\n */\nexport function paymentFromPresentValue(params: PaymentFromPresentValueParams): number {\n const { presentValue, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertNonNegative(periods, \"periods\");\n\n if (presentValue === 0 || periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pmt = presentValue / periods;\n return timing === \"begin\" ? pmt / (1 + ratePerPeriod) : pmt;\n }\n let pmt = (ratePerPeriod * presentValue) / (1 - (1 + ratePerPeriod) ** -periods);\n if (timing === \"begin\") pmt /= 1 + ratePerPeriod;\n return pmt;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PeriodsToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n rate: number;\n timesPerYear: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n maxPeriods?: number;\n};\n\n/**\n * Number of compounding periods until future value reaches the goal.\n * With no contributions: closed form. With contributions: iterative.\n */\nexport function periodsToReachGoal(params: PeriodsToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n rate,\n timesPerYear,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n maxPeriods = 100000,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertFiniteNumber(rate, \"rate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(maxPeriods, \"maxPeriods\");\n\n if (targetFutureValue <= principal) return 0;\n\n const r = rate / timesPerYear;\n if (r <= -1) {\n throw new RangeError(\"rate / timesPerYear must be > -1\");\n }\n\n if (contributionPerPeriod === 0) {\n if (principal === 0) return Number.POSITIVE_INFINITY;\n if (rate === 0) return targetFutureValue <= principal ? 0 : Number.POSITIVE_INFINITY;\n if (r < 0) return Number.POSITIVE_INFINITY;\n const n = Math.log(targetFutureValue / principal) / Math.log(1 + r);\n return Number.isFinite(n) && n >= 0 ? Math.ceil(n) : Number.POSITIVE_INFINITY;\n }\n\n if (rate === 0) {\n const needed = targetFutureValue - principal;\n if (needed <= 0) return 0;\n return Math.ceil(needed / contributionPerPeriod);\n }\n\n // With contributions: iterate until FV >= target\n let fv = principal;\n let periods = 0;\n while (fv < targetFutureValue && periods < maxPeriods) {\n if (contributionTiming === \"begin\") fv += contributionPerPeriod;\n fv = fv * (1 + r) + (contributionTiming === \"end\" ? contributionPerPeriod : 0);\n periods++;\n }\n if (fv >= targetFutureValue) return periods;\n throw new RangeError(\"maxPeriods exceeded before reaching target\");\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PresentValueParams = {\n futureValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Present value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function presentValue(params: PresentValueParams): number {\n const { futureValue: fv, rate, timesPerYear, years } = params;\n assertNonNegative(fv, \"futureValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return fv;\n\n const n = timesPerYear;\n const t = years;\n return fv / (1 + rate / n) ** (n * t);\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PresentValueOfAnnuityParams = {\n paymentPerPeriod: number;\n ratePerPeriod: number;\n periods: number;\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Present value of an annuity. PV = PMT * (1 - (1+r)^-n) / r. Due: multiply by (1+r).\n */\nexport function presentValueOfAnnuity(params: PresentValueOfAnnuityParams): number {\n const { paymentPerPeriod, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(paymentPerPeriod, \"paymentPerPeriod\");\n assertNonNegative(periods, \"periods\");\n\n if (periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pv = paymentPerPeriod * periods;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n }\n const pv = (paymentPerPeriod * (1 - (1 + ratePerPeriod) ** -periods)) / ratePerPeriod;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type RateToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n periods: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n lowerBound?: number;\n upperBound?: number;\n maxIterations?: number;\n tolerance?: number;\n};\n\n/**\n * Rate per period required to reach target future value in given periods.\n * Uses Newton-Raphson when contributions are present; closed form for lump sum.\n */\nexport function rateToReachGoal(params: RateToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n periods,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n lowerBound = -0.99,\n upperBound = 10,\n maxIterations = 100,\n tolerance = 1e-10,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertPositive(periods, \"periods\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(tolerance, \"tolerance\");\n if (lowerBound <= -1) throw new RangeError(\"lowerBound must be > -1\");\n if (upperBound <= lowerBound) throw new RangeError(\"upperBound must be greater than lowerBound\");\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (tolerance <= 0) throw new RangeError(\"tolerance must be > 0\");\n\n if (periods === 0) return 0;\n if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;\n\n if (contributionPerPeriod === 0) {\n if (targetFutureValue <= principal) return 0;\n if (principal === 0) {\n throw new RangeError(\n \"rateToReachGoal is undefined when principal is 0 and contributions are 0\",\n );\n }\n return (targetFutureValue / principal) ** (1 / periods) - 1;\n }\n\n const dueFactor = contributionTiming === \"begin\" ? 1 : 0;\n const fn = (r: number) => {\n const onePlusR = 1 + r;\n const onePlusRN = onePlusR ** periods;\n const fvLump = principal * onePlusRN;\n const annuityBase = r === 0 ? periods : (onePlusRN - 1) / r;\n const fvAnnuity = contributionPerPeriod * annuityBase * (1 + dueFactor * r);\n return fvLump + fvAnnuity - targetFutureValue;\n };\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-6 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const initialGuess =\n (targetFutureValue / (principal + contributionPerPeriod * periods)) ** (1 / periods) - 1;\n\n const newton = newtonRaphson({\n initialGuess: Number.isFinite(initialGuess) ? Math.max(initialGuess, lowerBound) : 0.01,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"rateToReachGoal did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n throw new RangeError(\"rateToReachGoal did not converge\");\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type RealReturnParams = { nominalReturn: number; inflationRate: number };\n\nexport function realReturn(params: RealReturnParams): number {\n const { nominalReturn, inflationRate } = params;\n assertFiniteNumber(nominalReturn, \"nominalReturn\");\n assertFiniteNumber(inflationRate, \"inflationRate\");\n if (inflationRate <= -1) return NaN;\n return (1 + nominalReturn) / (1 + inflationRate) - 1;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type RuleOf72Params = {\n rate: number;\n /** Use 69 for continuous-ish approximation (e.g. daily compounding). Default 72. */\n constant?: 72 | 69;\n};\n\n/**\n * Approximate years to double a lump sum at the given annual rate.\n * rate is decimal (e.g. 0.07 for 7%). Uses rule of 72 by default, or 69 if specified.\n */\nexport function ruleOf72(params: RuleOf72Params): number {\n const { rate, constant = 72 } = params;\n assertFiniteNumber(rate, \"rate\");\n assertPositive(rate, \"rate\");\n return constant / 100 / rate;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\ntype PaymentTiming = \"end\" | \"begin\";\n\nfunction assertTiming(value: PaymentTiming, name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\nfunction annuityDueFactor(ratePerPeriod: number, timing: PaymentTiming): number {\n return timing === \"begin\" ? 1 + ratePerPeriod : 1;\n}\n\nfunction futureValueFromCashFlows(\n ratePerPeriod: number,\n periods: number,\n payment: number,\n presentValue: number,\n timing: PaymentTiming,\n): number {\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n if (ratePerPeriod === 0) return -(presentValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) return Number.NaN;\n const paymentFv =\n payment * ((growth - 1) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n return -(presentValue * growth + paymentFv);\n}\n\nexport type FvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n presentValue: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel FV equivalent.\n */\nexport function fv(params: FvParams): number {\n const { ratePerPeriod, periods, payment = 0, presentValue, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertTiming(timing, \"timing\");\n\n const value = futureValueFromCashFlows(ratePerPeriod, periods, payment, presentValue, timing);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PV equivalent.\n */\nexport function pv(params: PvParams): number {\n const { ratePerPeriod, periods, payment = 0, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(futureValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const paymentPv =\n ((payment * (1 - 1 / growth)) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n const value = -futureValue / growth - paymentPv;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PmtParams = {\n ratePerPeriod: number;\n periods: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PMT equivalent.\n */\nexport function pmt(params: PmtParams): number {\n const { ratePerPeriod, periods, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(presentValue + futureValue) / periods;\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const numerator = -(futureValue + presentValue * growth) * ratePerPeriod;\n const denominator = (growth - 1) * annuityDueFactor(ratePerPeriod, timing);\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type NperParams = {\n ratePerPeriod: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel NPER equivalent.\n */\nexport function nper(params: NperParams): number {\n const { ratePerPeriod, payment, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) {\n const linear = -(presentValue + futureValue) / payment;\n return Number.isFinite(linear) && linear >= 0 ? linear : Number.NaN;\n }\n\n const adjustedPayment = payment * annuityDueFactor(ratePerPeriod, timing);\n const numerator = adjustedPayment - futureValue * ratePerPeriod;\n const denominator = adjustedPayment + presentValue * ratePerPeriod;\n if (numerator === 0 || denominator === 0) return Number.NaN;\n const ratio = numerator / denominator;\n if (ratio <= 0) return Number.NaN;\n\n const periods = Math.log(ratio) / Math.log(1 + ratePerPeriod);\n return Number.isFinite(periods) ? periods : Number.NaN;\n}\n\nexport type RateParams = {\n periods: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n guess?: number;\n tolerance?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\n/**\n * Excel RATE equivalent.\n */\nexport function rate(params: RateParams): number {\n const {\n periods,\n payment,\n presentValue,\n futureValue = 0,\n timing = \"end\",\n guess = 0.1,\n tolerance = 1e-10,\n maxIterations = 100,\n lowerBound = -0.999999999,\n upperBound = 10,\n } = params;\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(lowerBound)) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n\n const fn = (r: number) =>\n futureValueFromCashFlows(r, periods, payment, presentValue, timing) - futureValue;\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-5 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findRateBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"RATE did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"RATE did not converge\");\n}\n\nfunction ratePerPeriodIsInvalidForDomain(ratePerPeriod: number): boolean {\n return ratePerPeriod <= -1;\n}\n\nfunction findRateBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevValue !== undefined && prevX !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type LoanPaymentParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n};\n\n/**\n * Fixed periodic payment for an amortizing loan.\n *\n * - `annualRate` is nominal annual rate (e.g. 0.06 for 6%)\n * - payment returned is per period (`paymentsPerYear`)\n */\nexport function loanPayment(params: LoanPaymentParams): number {\n const { principal, annualRate, paymentsPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0) return 0;\n\n const r = annualRate / paymentsPerYear;\n if (r <= -1) {\n throw new RangeError(\"annualRate / paymentsPerYear must be > -1\");\n }\n if (r === 0) return principal / n;\n\n const value = (r * principal) / (1 - (1 + r) ** -n);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type AmortizationScheduleParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n extraPaymentPerPeriod?: number;\n};\n\nexport type AmortizationRow = {\n period: number;\n payment: number;\n principalPayment: number;\n interestPayment: number;\n balance: number;\n};\n\nexport type AmortizationScheduleResult = {\n paymentPerPeriod: number;\n schedule: AmortizationRow[];\n totalPaid: number;\n totalInterest: number;\n};\n\nexport function amortizationSchedule(\n params: AmortizationScheduleParams,\n): AmortizationScheduleResult {\n const { principal, annualRate, paymentsPerYear, years, extraPaymentPerPeriod = 0 } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n const scheduledN = Math.round(paymentsPerYear * years);\n if (scheduledN === 0 || principal === 0) {\n return { paymentPerPeriod: 0, schedule: [], totalPaid: 0, totalInterest: 0 };\n }\n\n const basePayment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n\n const schedule: AmortizationRow[] = [];\n let balance = principal;\n let totalPaid = 0;\n let totalInterest = 0;\n\n for (let period = 1; period <= scheduledN && balance > 0; period++) {\n const interestPayment = r === 0 ? 0 : balance * r;\n let payment = basePayment + extraPaymentPerPeriod;\n let principalPayment = payment - interestPayment;\n\n if (principalPayment > balance) {\n principalPayment = balance;\n payment = principalPayment + interestPayment;\n }\n\n balance = balance - principalPayment;\n if (Math.abs(balance) < 1e-12) balance = 0;\n\n totalPaid += payment;\n totalInterest += interestPayment;\n\n schedule.push({\n period,\n payment,\n principalPayment,\n interestPayment,\n balance,\n });\n }\n\n return {\n paymentPerPeriod: basePayment,\n schedule,\n totalPaid,\n totalInterest,\n };\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PayoffPeriodWithExtraParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n basePaymentPerPeriod: number;\n extraPaymentPerPeriod: number;\n};\n\n/**\n * Number of periods until the loan is paid off with the given base + extra payment.\n */\nexport function payoffPeriodWithExtra(params: PayoffPeriodWithExtraParams): number {\n const { principal, annualRate, paymentsPerYear, basePaymentPerPeriod, extraPaymentPerPeriod } =\n params;\n\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(basePaymentPerPeriod, \"basePaymentPerPeriod\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n if (principal <= 0) return 0;\n const payment = basePaymentPerPeriod + extraPaymentPerPeriod;\n if (payment <= 0) return Number.POSITIVE_INFINITY;\n\n const r = annualRate / paymentsPerYear;\n let balance = principal;\n let period = 0;\n\n while (balance > 1e-12 && period < 100000) {\n const interest = r > 0 ? balance * r : 0;\n if (payment <= interest) return Number.POSITIVE_INFINITY;\n const principalPaid = Math.min(payment - interest, balance);\n balance -= principalPaid;\n period++;\n }\n return balance <= 1e-12 ? period : Number.POSITIVE_INFINITY;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type RemainingBalanceParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n afterPeriodNumber: number;\n};\n\n/**\n * Remaining balance after a given number of payments on an amortizing loan.\n */\nexport function remainingBalance(params: RemainingBalanceParams): number {\n const { principal, annualRate, paymentsPerYear, years, afterPeriodNumber } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(afterPeriodNumber, \"afterPeriodNumber\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0 || afterPeriodNumber >= n) return 0;\n if (afterPeriodNumber <= 0) return principal;\n\n const payment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n const k = afterPeriodNumber;\n\n if (r === 0) return Math.max(0, principal - payment * k);\n const balance = principal * (1 + r) ** k - payment * (((1 + r) ** k - 1) / r);\n return Math.max(0, balance);\n}\n","import { assertFiniteNumber } from \"./assertions.js\";\n\nexport type RoundToCurrencyParams = {\n value: number;\n /** Decimal places. Default 2. */\n decimals?: number;\n /** 'half-up': 0.5 rounds up. 'half-even': banker's rounding. Default 'half-up'. */\n mode?: \"half-up\" | \"half-even\";\n};\n\n/**\n * Rounds a number to currency (default 2 decimals). half-up: 2.125 -> 2.13. half-even: 2.125 -> 2.12.\n */\nexport function roundToCurrency(params: RoundToCurrencyParams): number {\n const { value, decimals = 2, mode = \"half-up\" } = params;\n assertFiniteNumber(value, \"value\");\n const d = Math.max(0, Math.floor(decimals));\n const factor = 10 ** d;\n if (mode === \"half-even\") {\n const scaled = value * factor;\n const sign = scaled < 0 ? -1 : 1;\n const absScaled = Math.abs(scaled);\n const floorAbs = Math.floor(absScaled);\n const fraction = absScaled - floorAbs;\n const epsilon = 1e-12;\n if (Math.abs(fraction - 0.5) <= epsilon) {\n const nearestEven = floorAbs % 2 === 0 ? floorAbs : floorAbs + 1;\n return (sign * nearestEven) / factor;\n }\n return Math.round(scaled) / factor;\n }\n return Math.round(value * factor) / factor;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/assertions.ts","../src/interest/cagr.ts","../src/interest/compound.ts","../src/interest/effectiveAnnualRate.ts","../src/interest/futureValue.ts","../src/interest/inflationAdjustedAmount.ts","../src/interest/investmentGrowth.ts","../src/utils/solvers.ts","../src/interest/irr.ts","../src/interest/npv.ts","../src/interest/paymentFromPresentValue.ts","../src/interest/periodsToReachGoal.ts","../src/interest/presentValue.ts","../src/interest/presentValueOfAnnuity.ts","../src/interest/rateToReachGoal.ts","../src/interest/realReturn.ts","../src/interest/ruleOf72.ts","../src/interest/tvom.ts","../src/loans/loanPayment.ts","../src/loans/amortizationSchedule.ts","../src/loans/payoffPeriodWithExtra.ts","../src/loans/remainingBalance.ts","../src/utils/roundToCurrency.ts"],"names":["rate","presentValue","futureValue","pmt","fv","pv","assertContributionTiming","findBracket"],"mappings":"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","file":"index.cjs","sourcesContent":["export function assertFiniteNumber(value: number, name: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be a finite number`);\n }\n}\n\nexport function assertNonNegative(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value < 0) {\n throw new RangeError(`${name} must be >= 0`);\n }\n}\n\nexport function assertPositive(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be > 0`);\n }\n}\n","import { assertPositive } from \"../utils/assertions.js\";\n\nexport type CagrParams = {\n startValue: number;\n endValue: number;\n years: number;\n};\n\n/**\n * Compound annual growth rate (CAGR) between start and end value over the given years.\n * CAGR = (endValue/startValue)^(1/years) - 1\n */\nexport function cagr(params: CagrParams): number {\n const { startValue, endValue, years } = params;\n assertPositive(startValue, \"startValue\");\n assertPositive(years, \"years\");\n if (endValue <= 0) return -1;\n return (endValue / startValue) ** (1 / years) - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type CompoundParams = {\n principal: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Computes compound growth using nominal annual `rate` compounded `timesPerYear`.\n * Returns the final amount (principal + interest).\n */\nexport function compound(params: CompoundParams): number {\n const { principal, rate, timesPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return principal;\n\n const n = timesPerYear;\n const t = years;\n return principal * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type EffectiveAnnualRateParams = {\n nominalRate: number;\n timesPerYear: number;\n};\n\n/**\n * Converts a nominal annual rate to effective annual rate (EAR).\n * EAR = (1 + nominalRate/timesPerYear)^timesPerYear - 1\n */\nexport function effectiveAnnualRate(params: EffectiveAnnualRateParams): number {\n const { nominalRate, timesPerYear } = params;\n assertFiniteNumber(nominalRate, \"nominalRate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n\n const r = nominalRate / timesPerYear;\n return (1 + r) ** timesPerYear - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type FutureValueParams = {\n presentValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Future value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function futureValue(params: FutureValueParams): number {\n const { presentValue, rate, timesPerYear, years } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return presentValue;\n\n const n = timesPerYear;\n const t = years;\n return presentValue * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertNonNegative } from \"../utils/assertions.js\";\n\nexport type InflationAdjustedAmountParams = {\n amount: number;\n annualInflationRate: number;\n years: number;\n direction: \"toPast\" | \"toFuture\";\n};\n\n/**\n * Purchasing power across time. toPast: amount/(1+rate)^years. toFuture: amount*(1+rate)^years.\n */\nexport function inflationAdjustedAmount(params: InflationAdjustedAmountParams): number {\n const { amount, annualInflationRate, years, direction } = params;\n assertFiniteNumber(amount, \"amount\");\n assertFiniteNumber(annualInflationRate, \"annualInflationRate\");\n assertNonNegative(years, \"years\");\n const factor = (1 + annualInflationRate) ** years;\n return direction === \"toPast\" ? amount / factor : amount * factor;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type InvestmentGrowthParams = {\n initial: number;\n contributionPerPeriod?: number;\n rate: number;\n timesPerYear: number;\n years: number;\n contributionTiming?: \"end\" | \"begin\";\n};\n\nexport type InvestmentGrowthResult = {\n futureValue: number;\n totalContributions: number;\n totalInterest: number;\n};\n\n/**\n * Future value of an investment with optional periodic contributions.\n *\n * - `rate` is nominal annual rate (e.g. 0.05 for 5%)\n * - contributions occur each compounding period (`timesPerYear`)\n */\nexport function investmentGrowth(params: InvestmentGrowthParams): InvestmentGrowthResult {\n const {\n initial,\n contributionPerPeriod = 0,\n rate,\n timesPerYear,\n years,\n contributionTiming = \"end\",\n } = params;\n\n assertNonNegative(initial, \"initial\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n const periods = Math.round(timesPerYear * years);\n if (periods === 0) {\n return {\n futureValue: initial,\n totalContributions: 0,\n totalInterest: 0,\n };\n }\n\n const r = rate / timesPerYear;\n\n // Lump sum growth\n const fvInitial = rate === 0 ? initial : initial * (1 + r) ** periods;\n\n // Annuity future value (ordinary vs due)\n let fvContrib = 0;\n if (contributionPerPeriod !== 0) {\n if (rate === 0) {\n fvContrib = contributionPerPeriod * periods;\n } else {\n const ordinary = contributionPerPeriod * (((1 + r) ** periods - 1) / r);\n fvContrib = contributionTiming === \"begin\" ? ordinary * (1 + r) : ordinary;\n }\n }\n\n const futureValue = fvInitial + fvContrib;\n const totalContributions = contributionPerPeriod * periods;\n const totalInterest = futureValue - initial - totalContributions;\n\n return { futureValue, totalContributions, totalInterest };\n}\n","export type NewtonRaphsonParams = {\n initialGuess: number;\n fn: (x: number) => number;\n derivative: (x: number) => number;\n tolerance?: number;\n maxIterations?: number;\n min?: number;\n max?: number;\n};\n\nexport function newtonRaphson(params: NewtonRaphsonParams): number | undefined {\n const {\n initialGuess,\n fn,\n derivative,\n tolerance = 1e-10,\n maxIterations = 100,\n min = Number.NEGATIVE_INFINITY,\n max = Number.POSITIVE_INFINITY,\n } = params;\n\n let x = initialGuess;\n for (let i = 0; i < maxIterations; i++) {\n const value = fn(x);\n if (!Number.isFinite(value)) return undefined;\n if (Math.abs(value) <= tolerance) return x;\n\n const slope = derivative(x);\n if (!Number.isFinite(slope) || Math.abs(slope) < 1e-14) return undefined;\n\n x -= value / slope;\n if (x < min) x = min;\n if (x > max) x = max;\n }\n\n return undefined;\n}\n\nexport type BisectionParams = {\n fn: (x: number) => number;\n lower: number;\n upper: number;\n tolerance?: number;\n maxIterations?: number;\n};\n\nexport function bisection(params: BisectionParams): number | undefined {\n const { fn, lower, upper, tolerance = 1e-10, maxIterations = 200 } = params;\n let a = lower;\n let b = upper;\n let fa = fn(a);\n let fb = fn(b);\n\n if (!Number.isFinite(fa) || !Number.isFinite(fb) || fa * fb > 0) return undefined;\n if (Math.abs(fa) <= tolerance) return a;\n if (Math.abs(fb) <= tolerance) return b;\n\n for (let i = 0; i < maxIterations; i++) {\n const c = (a + b) / 2;\n const fc = fn(c);\n if (!Number.isFinite(fc)) return undefined;\n if (Math.abs(fc) <= tolerance || Math.abs(b - a) <= tolerance) return c;\n\n if (fa * fc < 0) {\n b = c;\n fb = fc;\n } else {\n a = c;\n fa = fc;\n }\n }\n\n return (a + b) / 2;\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type IrrParams = {\n cashFlows: number[];\n guess?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\nfunction npvAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n\nfunction npvDerivativeAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 1; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum -= (t * cf) / (1 + rate) ** (t + 1);\n }\n return sum;\n}\n\nfunction hasPositiveAndNegative(cashFlows: number[]): boolean {\n let hasPositive = false;\n let hasNegative = false;\n for (const cf of cashFlows) {\n if (cf > 0) hasPositive = true;\n if (cf < 0) hasNegative = true;\n if (hasPositive && hasNegative) return true;\n }\n return false;\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n\nexport function irr(params: IrrParams): number {\n const {\n cashFlows,\n guess = 0.1,\n maxIterations = 100,\n lowerBound = -0.99,\n upperBound = 10,\n } = params;\n if (cashFlows.length === 0) {\n throw new RangeError(\"cashFlows must contain at least one value\");\n }\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n if (maxIterations <= 0 || !Number.isInteger(maxIterations)) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (lowerBound <= -1) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n\n for (const cf of cashFlows) assertFiniteNumber(cf, \"cashFlows[]\");\n if (!hasPositiveAndNegative(cashFlows)) {\n throw new RangeError(\"cashFlows must include at least one positive and one negative value\");\n }\n\n const fn = (rate: number) => npvAt(rate, cashFlows);\n const derivative = (rate: number) => npvDerivativeAt(rate, cashFlows);\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance: 1e-10,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"IRR did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance: 1e-10,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"IRR did not converge\");\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type NpvParams = {\n rate: number;\n cashFlows: number[];\n};\n\n/**\n * Net present value at a discount `rate`.\n * cashFlows[0] is the period-0 cash flow.\n */\nexport function npv(params: NpvParams): number {\n const { rate, cashFlows } = params;\n assertFiniteNumber(rate, \"rate\");\n if (rate <= -1) throw new RangeError(\"rate must be > -1\");\n if (cashFlows.length === 0) return 0;\n\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf === undefined) continue;\n assertFiniteNumber(cf, `cashFlows[${t}]`);\n sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PaymentFromPresentValueParams = {\n presentValue: number;\n ratePerPeriod: number;\n periods: number;\n /** Payment at start of each period (annuity due). Default end (ordinary). */\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Periodic payment required to pay off a present value (e.g. loan) over periods.\n * PMT = PV * r / (1 - (1+r)^-n). For due: divide by (1+r).\n */\nexport function paymentFromPresentValue(params: PaymentFromPresentValueParams): number {\n const { presentValue, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertNonNegative(periods, \"periods\");\n\n if (presentValue === 0 || periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pmt = presentValue / periods;\n return timing === \"begin\" ? pmt / (1 + ratePerPeriod) : pmt;\n }\n let pmt = (ratePerPeriod * presentValue) / (1 - (1 + ratePerPeriod) ** -periods);\n if (timing === \"begin\") pmt /= 1 + ratePerPeriod;\n return pmt;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PeriodsToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n rate: number;\n timesPerYear: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n maxPeriods?: number;\n};\n\nfunction assertContributionTiming(value: \"end\" | \"begin\", name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\n/**\n * Number of compounding periods until future value reaches the goal.\n * With no contributions: closed form. With contributions: iterative.\n */\nexport function periodsToReachGoal(params: PeriodsToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n rate,\n timesPerYear,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n maxPeriods = 100000,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertFiniteNumber(rate, \"rate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(maxPeriods, \"maxPeriods\");\n assertContributionTiming(contributionTiming, \"contributionTiming\");\n\n if (targetFutureValue <= principal) return 0;\n\n const r = rate / timesPerYear;\n if (r <= -1) {\n throw new RangeError(\"rate / timesPerYear must be > -1\");\n }\n\n if (contributionPerPeriod === 0) {\n if (principal === 0) return Number.POSITIVE_INFINITY;\n if (rate === 0) return targetFutureValue <= principal ? 0 : Number.POSITIVE_INFINITY;\n if (r < 0) return Number.POSITIVE_INFINITY;\n const n = Math.log(targetFutureValue / principal) / Math.log(1 + r);\n return Number.isFinite(n) && n >= 0 ? Math.ceil(n) : Number.POSITIVE_INFINITY;\n }\n\n if (rate === 0) {\n const needed = targetFutureValue - principal;\n if (needed <= 0) return 0;\n return Math.ceil(needed / contributionPerPeriod);\n }\n\n // With contributions: iterate until FV >= target\n let fv = principal;\n let periods = 0;\n while (fv < targetFutureValue && periods < maxPeriods) {\n if (contributionTiming === \"begin\") fv += contributionPerPeriod;\n fv = fv * (1 + r) + (contributionTiming === \"end\" ? contributionPerPeriod : 0);\n periods++;\n }\n if (fv >= targetFutureValue) return periods;\n throw new RangeError(\"maxPeriods exceeded before reaching target\");\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PresentValueParams = {\n futureValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Present value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function presentValue(params: PresentValueParams): number {\n const { futureValue: fv, rate, timesPerYear, years } = params;\n assertNonNegative(fv, \"futureValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return fv;\n\n const n = timesPerYear;\n const t = years;\n return fv / (1 + rate / n) ** (n * t);\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PresentValueOfAnnuityParams = {\n paymentPerPeriod: number;\n ratePerPeriod: number;\n periods: number;\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Present value of an annuity. PV = PMT * (1 - (1+r)^-n) / r. Due: multiply by (1+r).\n */\nexport function presentValueOfAnnuity(params: PresentValueOfAnnuityParams): number {\n const { paymentPerPeriod, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(paymentPerPeriod, \"paymentPerPeriod\");\n assertNonNegative(periods, \"periods\");\n\n if (periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pv = paymentPerPeriod * periods;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n }\n const pv = (paymentPerPeriod * (1 - (1 + ratePerPeriod) ** -periods)) / ratePerPeriod;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type RateToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n periods: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n lowerBound?: number;\n upperBound?: number;\n maxIterations?: number;\n tolerance?: number;\n};\n\nfunction assertContributionTiming(value: \"end\" | \"begin\", name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\n/**\n * Rate per period required to reach target future value in given periods.\n * Uses Newton-Raphson when contributions are present; closed form for lump sum.\n */\nexport function rateToReachGoal(params: RateToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n periods,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n lowerBound = -0.99,\n upperBound = 10,\n maxIterations = 100,\n tolerance = 1e-10,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertPositive(periods, \"periods\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(tolerance, \"tolerance\");\n assertContributionTiming(contributionTiming, \"contributionTiming\");\n if (lowerBound <= -1) throw new RangeError(\"lowerBound must be > -1\");\n if (upperBound <= lowerBound) throw new RangeError(\"upperBound must be greater than lowerBound\");\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (tolerance <= 0) throw new RangeError(\"tolerance must be > 0\");\n\n if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;\n\n if (contributionPerPeriod === 0) {\n if (targetFutureValue <= principal) return 0;\n if (principal === 0) {\n throw new RangeError(\n \"rateToReachGoal is undefined when principal is 0 and contributions are 0\",\n );\n }\n return (targetFutureValue / principal) ** (1 / periods) - 1;\n }\n\n const dueFactor = contributionTiming === \"begin\" ? 1 : 0;\n const fn = (r: number) => {\n const onePlusR = 1 + r;\n const onePlusRN = onePlusR ** periods;\n const fvLump = principal * onePlusRN;\n const annuityBase = r === 0 ? periods : (onePlusRN - 1) / r;\n const fvAnnuity = contributionPerPeriod * annuityBase * (1 + dueFactor * r);\n return fvLump + fvAnnuity - targetFutureValue;\n };\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-6 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const initialGuess =\n (targetFutureValue / (principal + contributionPerPeriod * periods)) ** (1 / periods) - 1;\n\n const newton = newtonRaphson({\n initialGuess: Number.isFinite(initialGuess) ? Math.max(initialGuess, lowerBound) : 0.01,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"rateToReachGoal did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n throw new RangeError(\"rateToReachGoal did not converge\");\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type RealReturnParams = { nominalReturn: number; inflationRate: number };\n\nexport function realReturn(params: RealReturnParams): number {\n const { nominalReturn, inflationRate } = params;\n assertFiniteNumber(nominalReturn, \"nominalReturn\");\n assertFiniteNumber(inflationRate, \"inflationRate\");\n if (inflationRate <= -1) return NaN;\n return (1 + nominalReturn) / (1 + inflationRate) - 1;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type RuleOf72Params = {\n rate: number;\n /** Use 69 for continuous-ish approximation (e.g. daily compounding). Default 72. */\n constant?: 72 | 69;\n};\n\n/**\n * Approximate years to double a lump sum at the given annual rate.\n * rate is decimal (e.g. 0.07 for 7%). Uses rule of 72 by default, or 69 if specified.\n */\nexport function ruleOf72(params: RuleOf72Params): number {\n const { rate, constant = 72 } = params;\n assertFiniteNumber(rate, \"rate\");\n assertPositive(rate, \"rate\");\n return constant / 100 / rate;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\ntype PaymentTiming = \"end\" | \"begin\";\n\nfunction assertTiming(value: PaymentTiming, name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\nfunction annuityDueFactor(ratePerPeriod: number, timing: PaymentTiming): number {\n return timing === \"begin\" ? 1 + ratePerPeriod : 1;\n}\n\nfunction futureValueFromCashFlows(\n ratePerPeriod: number,\n periods: number,\n payment: number,\n presentValue: number,\n timing: PaymentTiming,\n): number {\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n if (ratePerPeriod === 0) return -(presentValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) return Number.NaN;\n const paymentFv =\n payment * ((growth - 1) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n return -(presentValue * growth + paymentFv);\n}\n\nexport type FvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n presentValue: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel FV equivalent.\n */\nexport function fv(params: FvParams): number {\n const { ratePerPeriod, periods, payment = 0, presentValue, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertTiming(timing, \"timing\");\n\n const value = futureValueFromCashFlows(ratePerPeriod, periods, payment, presentValue, timing);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PV equivalent.\n */\nexport function pv(params: PvParams): number {\n const { ratePerPeriod, periods, payment = 0, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(futureValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const paymentPv =\n ((payment * (1 - 1 / growth)) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n const value = -futureValue / growth - paymentPv;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PmtParams = {\n ratePerPeriod: number;\n periods: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PMT equivalent.\n */\nexport function pmt(params: PmtParams): number {\n const { ratePerPeriod, periods, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(presentValue + futureValue) / periods;\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const numerator = -(futureValue + presentValue * growth) * ratePerPeriod;\n const denominator = (growth - 1) * annuityDueFactor(ratePerPeriod, timing);\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type NperParams = {\n ratePerPeriod: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel NPER equivalent.\n */\nexport function nper(params: NperParams): number {\n const { ratePerPeriod, payment, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) {\n const linear = -(presentValue + futureValue) / payment;\n return Number.isFinite(linear) && linear >= 0 ? linear : Number.NaN;\n }\n\n const adjustedPayment = payment * annuityDueFactor(ratePerPeriod, timing);\n const numerator = adjustedPayment - futureValue * ratePerPeriod;\n const denominator = adjustedPayment + presentValue * ratePerPeriod;\n if (numerator === 0 || denominator === 0) return Number.NaN;\n const ratio = numerator / denominator;\n if (ratio <= 0) return Number.NaN;\n\n const periods = Math.log(ratio) / Math.log(1 + ratePerPeriod);\n return Number.isFinite(periods) ? periods : Number.NaN;\n}\n\nexport type RateParams = {\n periods: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n guess?: number;\n tolerance?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\n/**\n * Excel RATE equivalent.\n */\nexport function rate(params: RateParams): number {\n const {\n periods,\n payment,\n presentValue,\n futureValue = 0,\n timing = \"end\",\n guess = 0.1,\n tolerance = 1e-10,\n maxIterations = 100,\n lowerBound = -0.999999999,\n upperBound = 10,\n } = params;\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(lowerBound)) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n\n const fn = (r: number) =>\n futureValueFromCashFlows(r, periods, payment, presentValue, timing) - futureValue;\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-5 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findRateBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"RATE did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"RATE did not converge\");\n}\n\nfunction ratePerPeriodIsInvalidForDomain(ratePerPeriod: number): boolean {\n return ratePerPeriod <= -1;\n}\n\nfunction findRateBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevValue !== undefined && prevX !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type LoanPaymentParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n};\n\n/**\n * Fixed periodic payment for an amortizing loan.\n *\n * - `annualRate` is nominal annual rate (e.g. 0.06 for 6%)\n * - payment returned is per period (`paymentsPerYear`)\n */\nexport function loanPayment(params: LoanPaymentParams): number {\n const { principal, annualRate, paymentsPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0) return 0;\n\n const r = annualRate / paymentsPerYear;\n if (r <= -1) {\n throw new RangeError(\"annualRate / paymentsPerYear must be > -1\");\n }\n if (r === 0) return principal / n;\n\n const value = (r * principal) / (1 - (1 + r) ** -n);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type AmortizationScheduleParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n extraPaymentPerPeriod?: number;\n};\n\nexport type AmortizationRow = {\n period: number;\n payment: number;\n principalPayment: number;\n interestPayment: number;\n balance: number;\n};\n\nexport type AmortizationScheduleResult = {\n paymentPerPeriod: number;\n schedule: AmortizationRow[];\n totalPaid: number;\n totalInterest: number;\n};\n\nexport function amortizationSchedule(\n params: AmortizationScheduleParams,\n): AmortizationScheduleResult {\n const { principal, annualRate, paymentsPerYear, years, extraPaymentPerPeriod = 0 } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n const scheduledN = Math.round(paymentsPerYear * years);\n if (scheduledN === 0 || principal === 0) {\n return { paymentPerPeriod: 0, schedule: [], totalPaid: 0, totalInterest: 0 };\n }\n\n const basePayment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n\n const schedule: AmortizationRow[] = [];\n let balance = principal;\n let totalPaid = 0;\n let totalInterest = 0;\n\n for (let period = 1; period <= scheduledN && balance > 0; period++) {\n const interestPayment = r === 0 ? 0 : balance * r;\n let payment = basePayment + extraPaymentPerPeriod;\n let principalPayment = payment - interestPayment;\n\n if (principalPayment > balance) {\n principalPayment = balance;\n payment = principalPayment + interestPayment;\n }\n\n balance = balance - principalPayment;\n if (Math.abs(balance) < 1e-12) balance = 0;\n\n totalPaid += payment;\n totalInterest += interestPayment;\n\n schedule.push({\n period,\n payment,\n principalPayment,\n interestPayment,\n balance,\n });\n }\n\n return {\n paymentPerPeriod: basePayment,\n schedule,\n totalPaid,\n totalInterest,\n };\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PayoffPeriodWithExtraParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n basePaymentPerPeriod: number;\n extraPaymentPerPeriod: number;\n};\n\n/**\n * Number of periods until the loan is paid off with the given base + extra payment.\n */\nexport function payoffPeriodWithExtra(params: PayoffPeriodWithExtraParams): number {\n const { principal, annualRate, paymentsPerYear, basePaymentPerPeriod, extraPaymentPerPeriod } =\n params;\n\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(basePaymentPerPeriod, \"basePaymentPerPeriod\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n if (principal <= 0) return 0;\n const payment = basePaymentPerPeriod + extraPaymentPerPeriod;\n if (payment <= 0) return Number.POSITIVE_INFINITY;\n\n const r = annualRate / paymentsPerYear;\n let balance = principal;\n let period = 0;\n\n while (balance > 1e-12 && period < 100000) {\n const interest = r > 0 ? balance * r : 0;\n if (payment <= interest) return Number.POSITIVE_INFINITY;\n const principalPaid = Math.min(payment - interest, balance);\n balance -= principalPaid;\n period++;\n }\n return balance <= 1e-12 ? period : Number.POSITIVE_INFINITY;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type RemainingBalanceParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n afterPeriodNumber: number;\n};\n\n/**\n * Remaining balance after a given number of payments on an amortizing loan.\n */\nexport function remainingBalance(params: RemainingBalanceParams): number {\n const { principal, annualRate, paymentsPerYear, years, afterPeriodNumber } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(afterPeriodNumber, \"afterPeriodNumber\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0 || afterPeriodNumber >= n) return 0;\n if (afterPeriodNumber <= 0) return principal;\n\n const payment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n const k = afterPeriodNumber;\n\n if (r === 0) return Math.max(0, principal - payment * k);\n const balance = principal * (1 + r) ** k - payment * (((1 + r) ** k - 1) / r);\n return Math.max(0, balance);\n}\n","import { assertFiniteNumber } from \"./assertions.js\";\n\nexport type RoundToCurrencyParams = {\n value: number;\n /** Decimal places. Default 2. */\n decimals?: number;\n /** 'half-up': 0.5 rounds up. 'half-even': banker's rounding. Default 'half-up'. */\n mode?: \"half-up\" | \"half-even\";\n};\n\n/**\n * Rounds a number to currency (default 2 decimals). half-up: 2.125 -> 2.13. half-even: 2.125 -> 2.12.\n */\nexport function roundToCurrency(params: RoundToCurrencyParams): number {\n const { value, decimals = 2, mode = \"half-up\" } = params;\n assertFiniteNumber(value, \"value\");\n const d = Math.max(0, Math.floor(decimals));\n const factor = 10 ** d;\n if (mode === \"half-even\") {\n const scaled = value * factor;\n const sign = scaled < 0 ? -1 : 1;\n const absScaled = Math.abs(scaled);\n const floorAbs = Math.floor(absScaled);\n const fraction = absScaled - floorAbs;\n const epsilon = 1e-12;\n if (Math.abs(fraction - 0.5) <= epsilon) {\n const nearestEven = floorAbs % 2 === 0 ? floorAbs : floorAbs + 1;\n return (sign * nearestEven) / factor;\n }\n return Math.round(scaled) / factor;\n }\n return Math.round(value * factor) / factor;\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -299,6 +299,11 @@ function paymentFromPresentValue(params) {
|
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
// src/interest/periodsToReachGoal.ts
|
|
302
|
+
function assertContributionTiming(value, name) {
|
|
303
|
+
if (value !== "end" && value !== "begin") {
|
|
304
|
+
throw new RangeError(`${name} must be "end" or "begin"`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
302
307
|
function periodsToReachGoal(params) {
|
|
303
308
|
const {
|
|
304
309
|
principal,
|
|
@@ -315,6 +320,7 @@ function periodsToReachGoal(params) {
|
|
|
315
320
|
assertPositive(timesPerYear, "timesPerYear");
|
|
316
321
|
assertNonNegative(contributionPerPeriod, "contributionPerPeriod");
|
|
317
322
|
assertPositive(maxPeriods, "maxPeriods");
|
|
323
|
+
assertContributionTiming(contributionTiming, "contributionTiming");
|
|
318
324
|
if (targetFutureValue <= principal) return 0;
|
|
319
325
|
const r = rate2 / timesPerYear;
|
|
320
326
|
if (r <= -1) {
|
|
@@ -370,6 +376,11 @@ function presentValueOfAnnuity(params) {
|
|
|
370
376
|
}
|
|
371
377
|
|
|
372
378
|
// src/interest/rateToReachGoal.ts
|
|
379
|
+
function assertContributionTiming2(value, name) {
|
|
380
|
+
if (value !== "end" && value !== "begin") {
|
|
381
|
+
throw new RangeError(`${name} must be "end" or "begin"`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
373
384
|
function rateToReachGoal(params) {
|
|
374
385
|
const {
|
|
375
386
|
principal,
|
|
@@ -390,13 +401,13 @@ function rateToReachGoal(params) {
|
|
|
390
401
|
assertFiniteNumber(upperBound, "upperBound");
|
|
391
402
|
assertFiniteNumber(maxIterations, "maxIterations");
|
|
392
403
|
assertFiniteNumber(tolerance, "tolerance");
|
|
404
|
+
assertContributionTiming2(contributionTiming, "contributionTiming");
|
|
393
405
|
if (lowerBound <= -1) throw new RangeError("lowerBound must be > -1");
|
|
394
406
|
if (upperBound <= lowerBound) throw new RangeError("upperBound must be greater than lowerBound");
|
|
395
407
|
if (!Number.isInteger(maxIterations) || maxIterations <= 0) {
|
|
396
408
|
throw new RangeError("maxIterations must be a positive integer");
|
|
397
409
|
}
|
|
398
410
|
if (tolerance <= 0) throw new RangeError("tolerance must be > 0");
|
|
399
|
-
if (periods === 0) return 0;
|
|
400
411
|
if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;
|
|
401
412
|
if (contributionPerPeriod === 0) {
|
|
402
413
|
if (targetFutureValue <= principal) return 0;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/assertions.ts","../src/interest/cagr.ts","../src/interest/compound.ts","../src/interest/effectiveAnnualRate.ts","../src/interest/futureValue.ts","../src/interest/inflationAdjustedAmount.ts","../src/interest/investmentGrowth.ts","../src/utils/solvers.ts","../src/interest/irr.ts","../src/interest/npv.ts","../src/interest/paymentFromPresentValue.ts","../src/interest/periodsToReachGoal.ts","../src/interest/presentValue.ts","../src/interest/presentValueOfAnnuity.ts","../src/interest/rateToReachGoal.ts","../src/interest/realReturn.ts","../src/interest/ruleOf72.ts","../src/interest/tvom.ts","../src/loans/loanPayment.ts","../src/loans/amortizationSchedule.ts","../src/loans/payoffPeriodWithExtra.ts","../src/loans/remainingBalance.ts","../src/utils/roundToCurrency.ts"],"names":["rate","presentValue","futureValue","pmt","fv","pv","findBracket"],"mappings":"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","file":"index.js","sourcesContent":["export function assertFiniteNumber(value: number, name: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be a finite number`);\n }\n}\n\nexport function assertNonNegative(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value < 0) {\n throw new RangeError(`${name} must be >= 0`);\n }\n}\n\nexport function assertPositive(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be > 0`);\n }\n}\n","import { assertPositive } from \"../utils/assertions.js\";\n\nexport type CagrParams = {\n startValue: number;\n endValue: number;\n years: number;\n};\n\n/**\n * Compound annual growth rate (CAGR) between start and end value over the given years.\n * CAGR = (endValue/startValue)^(1/years) - 1\n */\nexport function cagr(params: CagrParams): number {\n const { startValue, endValue, years } = params;\n assertPositive(startValue, \"startValue\");\n assertPositive(years, \"years\");\n if (endValue <= 0) return -1;\n return (endValue / startValue) ** (1 / years) - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type CompoundParams = {\n principal: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Computes compound growth using nominal annual `rate` compounded `timesPerYear`.\n * Returns the final amount (principal + interest).\n */\nexport function compound(params: CompoundParams): number {\n const { principal, rate, timesPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return principal;\n\n const n = timesPerYear;\n const t = years;\n return principal * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type EffectiveAnnualRateParams = {\n nominalRate: number;\n timesPerYear: number;\n};\n\n/**\n * Converts a nominal annual rate to effective annual rate (EAR).\n * EAR = (1 + nominalRate/timesPerYear)^timesPerYear - 1\n */\nexport function effectiveAnnualRate(params: EffectiveAnnualRateParams): number {\n const { nominalRate, timesPerYear } = params;\n assertFiniteNumber(nominalRate, \"nominalRate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n\n const r = nominalRate / timesPerYear;\n return (1 + r) ** timesPerYear - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type FutureValueParams = {\n presentValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Future value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function futureValue(params: FutureValueParams): number {\n const { presentValue, rate, timesPerYear, years } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return presentValue;\n\n const n = timesPerYear;\n const t = years;\n return presentValue * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertNonNegative } from \"../utils/assertions.js\";\n\nexport type InflationAdjustedAmountParams = {\n amount: number;\n annualInflationRate: number;\n years: number;\n direction: \"toPast\" | \"toFuture\";\n};\n\n/**\n * Purchasing power across time. toPast: amount/(1+rate)^years. toFuture: amount*(1+rate)^years.\n */\nexport function inflationAdjustedAmount(params: InflationAdjustedAmountParams): number {\n const { amount, annualInflationRate, years, direction } = params;\n assertFiniteNumber(amount, \"amount\");\n assertFiniteNumber(annualInflationRate, \"annualInflationRate\");\n assertNonNegative(years, \"years\");\n const factor = (1 + annualInflationRate) ** years;\n return direction === \"toPast\" ? amount / factor : amount * factor;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type InvestmentGrowthParams = {\n initial: number;\n contributionPerPeriod?: number;\n rate: number;\n timesPerYear: number;\n years: number;\n contributionTiming?: \"end\" | \"begin\";\n};\n\nexport type InvestmentGrowthResult = {\n futureValue: number;\n totalContributions: number;\n totalInterest: number;\n};\n\n/**\n * Future value of an investment with optional periodic contributions.\n *\n * - `rate` is nominal annual rate (e.g. 0.05 for 5%)\n * - contributions occur each compounding period (`timesPerYear`)\n */\nexport function investmentGrowth(params: InvestmentGrowthParams): InvestmentGrowthResult {\n const {\n initial,\n contributionPerPeriod = 0,\n rate,\n timesPerYear,\n years,\n contributionTiming = \"end\",\n } = params;\n\n assertNonNegative(initial, \"initial\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n const periods = Math.round(timesPerYear * years);\n if (periods === 0) {\n return {\n futureValue: initial,\n totalContributions: 0,\n totalInterest: 0,\n };\n }\n\n const r = rate / timesPerYear;\n\n // Lump sum growth\n const fvInitial = rate === 0 ? initial : initial * (1 + r) ** periods;\n\n // Annuity future value (ordinary vs due)\n let fvContrib = 0;\n if (contributionPerPeriod !== 0) {\n if (rate === 0) {\n fvContrib = contributionPerPeriod * periods;\n } else {\n const ordinary = contributionPerPeriod * (((1 + r) ** periods - 1) / r);\n fvContrib = contributionTiming === \"begin\" ? ordinary * (1 + r) : ordinary;\n }\n }\n\n const futureValue = fvInitial + fvContrib;\n const totalContributions = contributionPerPeriod * periods;\n const totalInterest = futureValue - initial - totalContributions;\n\n return { futureValue, totalContributions, totalInterest };\n}\n","export type NewtonRaphsonParams = {\n initialGuess: number;\n fn: (x: number) => number;\n derivative: (x: number) => number;\n tolerance?: number;\n maxIterations?: number;\n min?: number;\n max?: number;\n};\n\nexport function newtonRaphson(params: NewtonRaphsonParams): number | undefined {\n const {\n initialGuess,\n fn,\n derivative,\n tolerance = 1e-10,\n maxIterations = 100,\n min = Number.NEGATIVE_INFINITY,\n max = Number.POSITIVE_INFINITY,\n } = params;\n\n let x = initialGuess;\n for (let i = 0; i < maxIterations; i++) {\n const value = fn(x);\n if (!Number.isFinite(value)) return undefined;\n if (Math.abs(value) <= tolerance) return x;\n\n const slope = derivative(x);\n if (!Number.isFinite(slope) || Math.abs(slope) < 1e-14) return undefined;\n\n x -= value / slope;\n if (x < min) x = min;\n if (x > max) x = max;\n }\n\n return undefined;\n}\n\nexport type BisectionParams = {\n fn: (x: number) => number;\n lower: number;\n upper: number;\n tolerance?: number;\n maxIterations?: number;\n};\n\nexport function bisection(params: BisectionParams): number | undefined {\n const { fn, lower, upper, tolerance = 1e-10, maxIterations = 200 } = params;\n let a = lower;\n let b = upper;\n let fa = fn(a);\n let fb = fn(b);\n\n if (!Number.isFinite(fa) || !Number.isFinite(fb) || fa * fb > 0) return undefined;\n if (Math.abs(fa) <= tolerance) return a;\n if (Math.abs(fb) <= tolerance) return b;\n\n for (let i = 0; i < maxIterations; i++) {\n const c = (a + b) / 2;\n const fc = fn(c);\n if (!Number.isFinite(fc)) return undefined;\n if (Math.abs(fc) <= tolerance || Math.abs(b - a) <= tolerance) return c;\n\n if (fa * fc < 0) {\n b = c;\n fb = fc;\n } else {\n a = c;\n fa = fc;\n }\n }\n\n return (a + b) / 2;\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type IrrParams = {\n cashFlows: number[];\n guess?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\nfunction npvAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n\nfunction npvDerivativeAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 1; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum -= (t * cf) / (1 + rate) ** (t + 1);\n }\n return sum;\n}\n\nfunction hasPositiveAndNegative(cashFlows: number[]): boolean {\n let hasPositive = false;\n let hasNegative = false;\n for (const cf of cashFlows) {\n if (cf > 0) hasPositive = true;\n if (cf < 0) hasNegative = true;\n if (hasPositive && hasNegative) return true;\n }\n return false;\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n\nexport function irr(params: IrrParams): number {\n const {\n cashFlows,\n guess = 0.1,\n maxIterations = 100,\n lowerBound = -0.99,\n upperBound = 10,\n } = params;\n if (cashFlows.length === 0) {\n throw new RangeError(\"cashFlows must contain at least one value\");\n }\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n if (maxIterations <= 0 || !Number.isInteger(maxIterations)) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (lowerBound <= -1) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n\n for (const cf of cashFlows) assertFiniteNumber(cf, \"cashFlows[]\");\n if (!hasPositiveAndNegative(cashFlows)) {\n throw new RangeError(\"cashFlows must include at least one positive and one negative value\");\n }\n\n const fn = (rate: number) => npvAt(rate, cashFlows);\n const derivative = (rate: number) => npvDerivativeAt(rate, cashFlows);\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance: 1e-10,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"IRR did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance: 1e-10,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"IRR did not converge\");\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type NpvParams = {\n rate: number;\n cashFlows: number[];\n};\n\n/**\n * Net present value at a discount `rate`.\n * cashFlows[0] is the period-0 cash flow.\n */\nexport function npv(params: NpvParams): number {\n const { rate, cashFlows } = params;\n assertFiniteNumber(rate, \"rate\");\n if (rate <= -1) throw new RangeError(\"rate must be > -1\");\n if (cashFlows.length === 0) return 0;\n\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf === undefined) continue;\n assertFiniteNumber(cf, `cashFlows[${t}]`);\n sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PaymentFromPresentValueParams = {\n presentValue: number;\n ratePerPeriod: number;\n periods: number;\n /** Payment at start of each period (annuity due). Default end (ordinary). */\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Periodic payment required to pay off a present value (e.g. loan) over periods.\n * PMT = PV * r / (1 - (1+r)^-n). For due: divide by (1+r).\n */\nexport function paymentFromPresentValue(params: PaymentFromPresentValueParams): number {\n const { presentValue, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertNonNegative(periods, \"periods\");\n\n if (presentValue === 0 || periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pmt = presentValue / periods;\n return timing === \"begin\" ? pmt / (1 + ratePerPeriod) : pmt;\n }\n let pmt = (ratePerPeriod * presentValue) / (1 - (1 + ratePerPeriod) ** -periods);\n if (timing === \"begin\") pmt /= 1 + ratePerPeriod;\n return pmt;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PeriodsToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n rate: number;\n timesPerYear: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n maxPeriods?: number;\n};\n\n/**\n * Number of compounding periods until future value reaches the goal.\n * With no contributions: closed form. With contributions: iterative.\n */\nexport function periodsToReachGoal(params: PeriodsToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n rate,\n timesPerYear,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n maxPeriods = 100000,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertFiniteNumber(rate, \"rate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(maxPeriods, \"maxPeriods\");\n\n if (targetFutureValue <= principal) return 0;\n\n const r = rate / timesPerYear;\n if (r <= -1) {\n throw new RangeError(\"rate / timesPerYear must be > -1\");\n }\n\n if (contributionPerPeriod === 0) {\n if (principal === 0) return Number.POSITIVE_INFINITY;\n if (rate === 0) return targetFutureValue <= principal ? 0 : Number.POSITIVE_INFINITY;\n if (r < 0) return Number.POSITIVE_INFINITY;\n const n = Math.log(targetFutureValue / principal) / Math.log(1 + r);\n return Number.isFinite(n) && n >= 0 ? Math.ceil(n) : Number.POSITIVE_INFINITY;\n }\n\n if (rate === 0) {\n const needed = targetFutureValue - principal;\n if (needed <= 0) return 0;\n return Math.ceil(needed / contributionPerPeriod);\n }\n\n // With contributions: iterate until FV >= target\n let fv = principal;\n let periods = 0;\n while (fv < targetFutureValue && periods < maxPeriods) {\n if (contributionTiming === \"begin\") fv += contributionPerPeriod;\n fv = fv * (1 + r) + (contributionTiming === \"end\" ? contributionPerPeriod : 0);\n periods++;\n }\n if (fv >= targetFutureValue) return periods;\n throw new RangeError(\"maxPeriods exceeded before reaching target\");\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PresentValueParams = {\n futureValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Present value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function presentValue(params: PresentValueParams): number {\n const { futureValue: fv, rate, timesPerYear, years } = params;\n assertNonNegative(fv, \"futureValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return fv;\n\n const n = timesPerYear;\n const t = years;\n return fv / (1 + rate / n) ** (n * t);\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PresentValueOfAnnuityParams = {\n paymentPerPeriod: number;\n ratePerPeriod: number;\n periods: number;\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Present value of an annuity. PV = PMT * (1 - (1+r)^-n) / r. Due: multiply by (1+r).\n */\nexport function presentValueOfAnnuity(params: PresentValueOfAnnuityParams): number {\n const { paymentPerPeriod, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(paymentPerPeriod, \"paymentPerPeriod\");\n assertNonNegative(periods, \"periods\");\n\n if (periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pv = paymentPerPeriod * periods;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n }\n const pv = (paymentPerPeriod * (1 - (1 + ratePerPeriod) ** -periods)) / ratePerPeriod;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type RateToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n periods: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n lowerBound?: number;\n upperBound?: number;\n maxIterations?: number;\n tolerance?: number;\n};\n\n/**\n * Rate per period required to reach target future value in given periods.\n * Uses Newton-Raphson when contributions are present; closed form for lump sum.\n */\nexport function rateToReachGoal(params: RateToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n periods,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n lowerBound = -0.99,\n upperBound = 10,\n maxIterations = 100,\n tolerance = 1e-10,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertPositive(periods, \"periods\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(tolerance, \"tolerance\");\n if (lowerBound <= -1) throw new RangeError(\"lowerBound must be > -1\");\n if (upperBound <= lowerBound) throw new RangeError(\"upperBound must be greater than lowerBound\");\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (tolerance <= 0) throw new RangeError(\"tolerance must be > 0\");\n\n if (periods === 0) return 0;\n if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;\n\n if (contributionPerPeriod === 0) {\n if (targetFutureValue <= principal) return 0;\n if (principal === 0) {\n throw new RangeError(\n \"rateToReachGoal is undefined when principal is 0 and contributions are 0\",\n );\n }\n return (targetFutureValue / principal) ** (1 / periods) - 1;\n }\n\n const dueFactor = contributionTiming === \"begin\" ? 1 : 0;\n const fn = (r: number) => {\n const onePlusR = 1 + r;\n const onePlusRN = onePlusR ** periods;\n const fvLump = principal * onePlusRN;\n const annuityBase = r === 0 ? periods : (onePlusRN - 1) / r;\n const fvAnnuity = contributionPerPeriod * annuityBase * (1 + dueFactor * r);\n return fvLump + fvAnnuity - targetFutureValue;\n };\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-6 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const initialGuess =\n (targetFutureValue / (principal + contributionPerPeriod * periods)) ** (1 / periods) - 1;\n\n const newton = newtonRaphson({\n initialGuess: Number.isFinite(initialGuess) ? Math.max(initialGuess, lowerBound) : 0.01,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"rateToReachGoal did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n throw new RangeError(\"rateToReachGoal did not converge\");\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type RealReturnParams = { nominalReturn: number; inflationRate: number };\n\nexport function realReturn(params: RealReturnParams): number {\n const { nominalReturn, inflationRate } = params;\n assertFiniteNumber(nominalReturn, \"nominalReturn\");\n assertFiniteNumber(inflationRate, \"inflationRate\");\n if (inflationRate <= -1) return NaN;\n return (1 + nominalReturn) / (1 + inflationRate) - 1;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type RuleOf72Params = {\n rate: number;\n /** Use 69 for continuous-ish approximation (e.g. daily compounding). Default 72. */\n constant?: 72 | 69;\n};\n\n/**\n * Approximate years to double a lump sum at the given annual rate.\n * rate is decimal (e.g. 0.07 for 7%). Uses rule of 72 by default, or 69 if specified.\n */\nexport function ruleOf72(params: RuleOf72Params): number {\n const { rate, constant = 72 } = params;\n assertFiniteNumber(rate, \"rate\");\n assertPositive(rate, \"rate\");\n return constant / 100 / rate;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\ntype PaymentTiming = \"end\" | \"begin\";\n\nfunction assertTiming(value: PaymentTiming, name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\nfunction annuityDueFactor(ratePerPeriod: number, timing: PaymentTiming): number {\n return timing === \"begin\" ? 1 + ratePerPeriod : 1;\n}\n\nfunction futureValueFromCashFlows(\n ratePerPeriod: number,\n periods: number,\n payment: number,\n presentValue: number,\n timing: PaymentTiming,\n): number {\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n if (ratePerPeriod === 0) return -(presentValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) return Number.NaN;\n const paymentFv =\n payment * ((growth - 1) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n return -(presentValue * growth + paymentFv);\n}\n\nexport type FvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n presentValue: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel FV equivalent.\n */\nexport function fv(params: FvParams): number {\n const { ratePerPeriod, periods, payment = 0, presentValue, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertTiming(timing, \"timing\");\n\n const value = futureValueFromCashFlows(ratePerPeriod, periods, payment, presentValue, timing);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PV equivalent.\n */\nexport function pv(params: PvParams): number {\n const { ratePerPeriod, periods, payment = 0, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(futureValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const paymentPv =\n ((payment * (1 - 1 / growth)) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n const value = -futureValue / growth - paymentPv;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PmtParams = {\n ratePerPeriod: number;\n periods: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PMT equivalent.\n */\nexport function pmt(params: PmtParams): number {\n const { ratePerPeriod, periods, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(presentValue + futureValue) / periods;\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const numerator = -(futureValue + presentValue * growth) * ratePerPeriod;\n const denominator = (growth - 1) * annuityDueFactor(ratePerPeriod, timing);\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type NperParams = {\n ratePerPeriod: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel NPER equivalent.\n */\nexport function nper(params: NperParams): number {\n const { ratePerPeriod, payment, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) {\n const linear = -(presentValue + futureValue) / payment;\n return Number.isFinite(linear) && linear >= 0 ? linear : Number.NaN;\n }\n\n const adjustedPayment = payment * annuityDueFactor(ratePerPeriod, timing);\n const numerator = adjustedPayment - futureValue * ratePerPeriod;\n const denominator = adjustedPayment + presentValue * ratePerPeriod;\n if (numerator === 0 || denominator === 0) return Number.NaN;\n const ratio = numerator / denominator;\n if (ratio <= 0) return Number.NaN;\n\n const periods = Math.log(ratio) / Math.log(1 + ratePerPeriod);\n return Number.isFinite(periods) ? periods : Number.NaN;\n}\n\nexport type RateParams = {\n periods: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n guess?: number;\n tolerance?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\n/**\n * Excel RATE equivalent.\n */\nexport function rate(params: RateParams): number {\n const {\n periods,\n payment,\n presentValue,\n futureValue = 0,\n timing = \"end\",\n guess = 0.1,\n tolerance = 1e-10,\n maxIterations = 100,\n lowerBound = -0.999999999,\n upperBound = 10,\n } = params;\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(lowerBound)) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n\n const fn = (r: number) =>\n futureValueFromCashFlows(r, periods, payment, presentValue, timing) - futureValue;\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-5 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findRateBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"RATE did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"RATE did not converge\");\n}\n\nfunction ratePerPeriodIsInvalidForDomain(ratePerPeriod: number): boolean {\n return ratePerPeriod <= -1;\n}\n\nfunction findRateBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevValue !== undefined && prevX !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type LoanPaymentParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n};\n\n/**\n * Fixed periodic payment for an amortizing loan.\n *\n * - `annualRate` is nominal annual rate (e.g. 0.06 for 6%)\n * - payment returned is per period (`paymentsPerYear`)\n */\nexport function loanPayment(params: LoanPaymentParams): number {\n const { principal, annualRate, paymentsPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0) return 0;\n\n const r = annualRate / paymentsPerYear;\n if (r <= -1) {\n throw new RangeError(\"annualRate / paymentsPerYear must be > -1\");\n }\n if (r === 0) return principal / n;\n\n const value = (r * principal) / (1 - (1 + r) ** -n);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type AmortizationScheduleParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n extraPaymentPerPeriod?: number;\n};\n\nexport type AmortizationRow = {\n period: number;\n payment: number;\n principalPayment: number;\n interestPayment: number;\n balance: number;\n};\n\nexport type AmortizationScheduleResult = {\n paymentPerPeriod: number;\n schedule: AmortizationRow[];\n totalPaid: number;\n totalInterest: number;\n};\n\nexport function amortizationSchedule(\n params: AmortizationScheduleParams,\n): AmortizationScheduleResult {\n const { principal, annualRate, paymentsPerYear, years, extraPaymentPerPeriod = 0 } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n const scheduledN = Math.round(paymentsPerYear * years);\n if (scheduledN === 0 || principal === 0) {\n return { paymentPerPeriod: 0, schedule: [], totalPaid: 0, totalInterest: 0 };\n }\n\n const basePayment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n\n const schedule: AmortizationRow[] = [];\n let balance = principal;\n let totalPaid = 0;\n let totalInterest = 0;\n\n for (let period = 1; period <= scheduledN && balance > 0; period++) {\n const interestPayment = r === 0 ? 0 : balance * r;\n let payment = basePayment + extraPaymentPerPeriod;\n let principalPayment = payment - interestPayment;\n\n if (principalPayment > balance) {\n principalPayment = balance;\n payment = principalPayment + interestPayment;\n }\n\n balance = balance - principalPayment;\n if (Math.abs(balance) < 1e-12) balance = 0;\n\n totalPaid += payment;\n totalInterest += interestPayment;\n\n schedule.push({\n period,\n payment,\n principalPayment,\n interestPayment,\n balance,\n });\n }\n\n return {\n paymentPerPeriod: basePayment,\n schedule,\n totalPaid,\n totalInterest,\n };\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PayoffPeriodWithExtraParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n basePaymentPerPeriod: number;\n extraPaymentPerPeriod: number;\n};\n\n/**\n * Number of periods until the loan is paid off with the given base + extra payment.\n */\nexport function payoffPeriodWithExtra(params: PayoffPeriodWithExtraParams): number {\n const { principal, annualRate, paymentsPerYear, basePaymentPerPeriod, extraPaymentPerPeriod } =\n params;\n\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(basePaymentPerPeriod, \"basePaymentPerPeriod\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n if (principal <= 0) return 0;\n const payment = basePaymentPerPeriod + extraPaymentPerPeriod;\n if (payment <= 0) return Number.POSITIVE_INFINITY;\n\n const r = annualRate / paymentsPerYear;\n let balance = principal;\n let period = 0;\n\n while (balance > 1e-12 && period < 100000) {\n const interest = r > 0 ? balance * r : 0;\n if (payment <= interest) return Number.POSITIVE_INFINITY;\n const principalPaid = Math.min(payment - interest, balance);\n balance -= principalPaid;\n period++;\n }\n return balance <= 1e-12 ? period : Number.POSITIVE_INFINITY;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type RemainingBalanceParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n afterPeriodNumber: number;\n};\n\n/**\n * Remaining balance after a given number of payments on an amortizing loan.\n */\nexport function remainingBalance(params: RemainingBalanceParams): number {\n const { principal, annualRate, paymentsPerYear, years, afterPeriodNumber } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(afterPeriodNumber, \"afterPeriodNumber\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0 || afterPeriodNumber >= n) return 0;\n if (afterPeriodNumber <= 0) return principal;\n\n const payment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n const k = afterPeriodNumber;\n\n if (r === 0) return Math.max(0, principal - payment * k);\n const balance = principal * (1 + r) ** k - payment * (((1 + r) ** k - 1) / r);\n return Math.max(0, balance);\n}\n","import { assertFiniteNumber } from \"./assertions.js\";\n\nexport type RoundToCurrencyParams = {\n value: number;\n /** Decimal places. Default 2. */\n decimals?: number;\n /** 'half-up': 0.5 rounds up. 'half-even': banker's rounding. Default 'half-up'. */\n mode?: \"half-up\" | \"half-even\";\n};\n\n/**\n * Rounds a number to currency (default 2 decimals). half-up: 2.125 -> 2.13. half-even: 2.125 -> 2.12.\n */\nexport function roundToCurrency(params: RoundToCurrencyParams): number {\n const { value, decimals = 2, mode = \"half-up\" } = params;\n assertFiniteNumber(value, \"value\");\n const d = Math.max(0, Math.floor(decimals));\n const factor = 10 ** d;\n if (mode === \"half-even\") {\n const scaled = value * factor;\n const sign = scaled < 0 ? -1 : 1;\n const absScaled = Math.abs(scaled);\n const floorAbs = Math.floor(absScaled);\n const fraction = absScaled - floorAbs;\n const epsilon = 1e-12;\n if (Math.abs(fraction - 0.5) <= epsilon) {\n const nearestEven = floorAbs % 2 === 0 ? floorAbs : floorAbs + 1;\n return (sign * nearestEven) / factor;\n }\n return Math.round(scaled) / factor;\n }\n return Math.round(value * factor) / factor;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/assertions.ts","../src/interest/cagr.ts","../src/interest/compound.ts","../src/interest/effectiveAnnualRate.ts","../src/interest/futureValue.ts","../src/interest/inflationAdjustedAmount.ts","../src/interest/investmentGrowth.ts","../src/utils/solvers.ts","../src/interest/irr.ts","../src/interest/npv.ts","../src/interest/paymentFromPresentValue.ts","../src/interest/periodsToReachGoal.ts","../src/interest/presentValue.ts","../src/interest/presentValueOfAnnuity.ts","../src/interest/rateToReachGoal.ts","../src/interest/realReturn.ts","../src/interest/ruleOf72.ts","../src/interest/tvom.ts","../src/loans/loanPayment.ts","../src/loans/amortizationSchedule.ts","../src/loans/payoffPeriodWithExtra.ts","../src/loans/remainingBalance.ts","../src/utils/roundToCurrency.ts"],"names":["rate","presentValue","futureValue","pmt","fv","pv","assertContributionTiming","findBracket"],"mappings":"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","file":"index.js","sourcesContent":["export function assertFiniteNumber(value: number, name: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be a finite number`);\n }\n}\n\nexport function assertNonNegative(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value < 0) {\n throw new RangeError(`${name} must be >= 0`);\n }\n}\n\nexport function assertPositive(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be > 0`);\n }\n}\n","import { assertPositive } from \"../utils/assertions.js\";\n\nexport type CagrParams = {\n startValue: number;\n endValue: number;\n years: number;\n};\n\n/**\n * Compound annual growth rate (CAGR) between start and end value over the given years.\n * CAGR = (endValue/startValue)^(1/years) - 1\n */\nexport function cagr(params: CagrParams): number {\n const { startValue, endValue, years } = params;\n assertPositive(startValue, \"startValue\");\n assertPositive(years, \"years\");\n if (endValue <= 0) return -1;\n return (endValue / startValue) ** (1 / years) - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type CompoundParams = {\n principal: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Computes compound growth using nominal annual `rate` compounded `timesPerYear`.\n * Returns the final amount (principal + interest).\n */\nexport function compound(params: CompoundParams): number {\n const { principal, rate, timesPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return principal;\n\n const n = timesPerYear;\n const t = years;\n return principal * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type EffectiveAnnualRateParams = {\n nominalRate: number;\n timesPerYear: number;\n};\n\n/**\n * Converts a nominal annual rate to effective annual rate (EAR).\n * EAR = (1 + nominalRate/timesPerYear)^timesPerYear - 1\n */\nexport function effectiveAnnualRate(params: EffectiveAnnualRateParams): number {\n const { nominalRate, timesPerYear } = params;\n assertFiniteNumber(nominalRate, \"nominalRate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n\n const r = nominalRate / timesPerYear;\n return (1 + r) ** timesPerYear - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type FutureValueParams = {\n presentValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Future value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function futureValue(params: FutureValueParams): number {\n const { presentValue, rate, timesPerYear, years } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return presentValue;\n\n const n = timesPerYear;\n const t = years;\n return presentValue * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertNonNegative } from \"../utils/assertions.js\";\n\nexport type InflationAdjustedAmountParams = {\n amount: number;\n annualInflationRate: number;\n years: number;\n direction: \"toPast\" | \"toFuture\";\n};\n\n/**\n * Purchasing power across time. toPast: amount/(1+rate)^years. toFuture: amount*(1+rate)^years.\n */\nexport function inflationAdjustedAmount(params: InflationAdjustedAmountParams): number {\n const { amount, annualInflationRate, years, direction } = params;\n assertFiniteNumber(amount, \"amount\");\n assertFiniteNumber(annualInflationRate, \"annualInflationRate\");\n assertNonNegative(years, \"years\");\n const factor = (1 + annualInflationRate) ** years;\n return direction === \"toPast\" ? amount / factor : amount * factor;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type InvestmentGrowthParams = {\n initial: number;\n contributionPerPeriod?: number;\n rate: number;\n timesPerYear: number;\n years: number;\n contributionTiming?: \"end\" | \"begin\";\n};\n\nexport type InvestmentGrowthResult = {\n futureValue: number;\n totalContributions: number;\n totalInterest: number;\n};\n\n/**\n * Future value of an investment with optional periodic contributions.\n *\n * - `rate` is nominal annual rate (e.g. 0.05 for 5%)\n * - contributions occur each compounding period (`timesPerYear`)\n */\nexport function investmentGrowth(params: InvestmentGrowthParams): InvestmentGrowthResult {\n const {\n initial,\n contributionPerPeriod = 0,\n rate,\n timesPerYear,\n years,\n contributionTiming = \"end\",\n } = params;\n\n assertNonNegative(initial, \"initial\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n const periods = Math.round(timesPerYear * years);\n if (periods === 0) {\n return {\n futureValue: initial,\n totalContributions: 0,\n totalInterest: 0,\n };\n }\n\n const r = rate / timesPerYear;\n\n // Lump sum growth\n const fvInitial = rate === 0 ? initial : initial * (1 + r) ** periods;\n\n // Annuity future value (ordinary vs due)\n let fvContrib = 0;\n if (contributionPerPeriod !== 0) {\n if (rate === 0) {\n fvContrib = contributionPerPeriod * periods;\n } else {\n const ordinary = contributionPerPeriod * (((1 + r) ** periods - 1) / r);\n fvContrib = contributionTiming === \"begin\" ? ordinary * (1 + r) : ordinary;\n }\n }\n\n const futureValue = fvInitial + fvContrib;\n const totalContributions = contributionPerPeriod * periods;\n const totalInterest = futureValue - initial - totalContributions;\n\n return { futureValue, totalContributions, totalInterest };\n}\n","export type NewtonRaphsonParams = {\n initialGuess: number;\n fn: (x: number) => number;\n derivative: (x: number) => number;\n tolerance?: number;\n maxIterations?: number;\n min?: number;\n max?: number;\n};\n\nexport function newtonRaphson(params: NewtonRaphsonParams): number | undefined {\n const {\n initialGuess,\n fn,\n derivative,\n tolerance = 1e-10,\n maxIterations = 100,\n min = Number.NEGATIVE_INFINITY,\n max = Number.POSITIVE_INFINITY,\n } = params;\n\n let x = initialGuess;\n for (let i = 0; i < maxIterations; i++) {\n const value = fn(x);\n if (!Number.isFinite(value)) return undefined;\n if (Math.abs(value) <= tolerance) return x;\n\n const slope = derivative(x);\n if (!Number.isFinite(slope) || Math.abs(slope) < 1e-14) return undefined;\n\n x -= value / slope;\n if (x < min) x = min;\n if (x > max) x = max;\n }\n\n return undefined;\n}\n\nexport type BisectionParams = {\n fn: (x: number) => number;\n lower: number;\n upper: number;\n tolerance?: number;\n maxIterations?: number;\n};\n\nexport function bisection(params: BisectionParams): number | undefined {\n const { fn, lower, upper, tolerance = 1e-10, maxIterations = 200 } = params;\n let a = lower;\n let b = upper;\n let fa = fn(a);\n let fb = fn(b);\n\n if (!Number.isFinite(fa) || !Number.isFinite(fb) || fa * fb > 0) return undefined;\n if (Math.abs(fa) <= tolerance) return a;\n if (Math.abs(fb) <= tolerance) return b;\n\n for (let i = 0; i < maxIterations; i++) {\n const c = (a + b) / 2;\n const fc = fn(c);\n if (!Number.isFinite(fc)) return undefined;\n if (Math.abs(fc) <= tolerance || Math.abs(b - a) <= tolerance) return c;\n\n if (fa * fc < 0) {\n b = c;\n fb = fc;\n } else {\n a = c;\n fa = fc;\n }\n }\n\n return (a + b) / 2;\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type IrrParams = {\n cashFlows: number[];\n guess?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\nfunction npvAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n\nfunction npvDerivativeAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 1; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum -= (t * cf) / (1 + rate) ** (t + 1);\n }\n return sum;\n}\n\nfunction hasPositiveAndNegative(cashFlows: number[]): boolean {\n let hasPositive = false;\n let hasNegative = false;\n for (const cf of cashFlows) {\n if (cf > 0) hasPositive = true;\n if (cf < 0) hasNegative = true;\n if (hasPositive && hasNegative) return true;\n }\n return false;\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n\nexport function irr(params: IrrParams): number {\n const {\n cashFlows,\n guess = 0.1,\n maxIterations = 100,\n lowerBound = -0.99,\n upperBound = 10,\n } = params;\n if (cashFlows.length === 0) {\n throw new RangeError(\"cashFlows must contain at least one value\");\n }\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n if (maxIterations <= 0 || !Number.isInteger(maxIterations)) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (lowerBound <= -1) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n\n for (const cf of cashFlows) assertFiniteNumber(cf, \"cashFlows[]\");\n if (!hasPositiveAndNegative(cashFlows)) {\n throw new RangeError(\"cashFlows must include at least one positive and one negative value\");\n }\n\n const fn = (rate: number) => npvAt(rate, cashFlows);\n const derivative = (rate: number) => npvDerivativeAt(rate, cashFlows);\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance: 1e-10,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"IRR did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance: 1e-10,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"IRR did not converge\");\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type NpvParams = {\n rate: number;\n cashFlows: number[];\n};\n\n/**\n * Net present value at a discount `rate`.\n * cashFlows[0] is the period-0 cash flow.\n */\nexport function npv(params: NpvParams): number {\n const { rate, cashFlows } = params;\n assertFiniteNumber(rate, \"rate\");\n if (rate <= -1) throw new RangeError(\"rate must be > -1\");\n if (cashFlows.length === 0) return 0;\n\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf === undefined) continue;\n assertFiniteNumber(cf, `cashFlows[${t}]`);\n sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PaymentFromPresentValueParams = {\n presentValue: number;\n ratePerPeriod: number;\n periods: number;\n /** Payment at start of each period (annuity due). Default end (ordinary). */\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Periodic payment required to pay off a present value (e.g. loan) over periods.\n * PMT = PV * r / (1 - (1+r)^-n). For due: divide by (1+r).\n */\nexport function paymentFromPresentValue(params: PaymentFromPresentValueParams): number {\n const { presentValue, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertNonNegative(periods, \"periods\");\n\n if (presentValue === 0 || periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pmt = presentValue / periods;\n return timing === \"begin\" ? pmt / (1 + ratePerPeriod) : pmt;\n }\n let pmt = (ratePerPeriod * presentValue) / (1 - (1 + ratePerPeriod) ** -periods);\n if (timing === \"begin\") pmt /= 1 + ratePerPeriod;\n return pmt;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PeriodsToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n rate: number;\n timesPerYear: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n maxPeriods?: number;\n};\n\nfunction assertContributionTiming(value: \"end\" | \"begin\", name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\n/**\n * Number of compounding periods until future value reaches the goal.\n * With no contributions: closed form. With contributions: iterative.\n */\nexport function periodsToReachGoal(params: PeriodsToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n rate,\n timesPerYear,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n maxPeriods = 100000,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertFiniteNumber(rate, \"rate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(maxPeriods, \"maxPeriods\");\n assertContributionTiming(contributionTiming, \"contributionTiming\");\n\n if (targetFutureValue <= principal) return 0;\n\n const r = rate / timesPerYear;\n if (r <= -1) {\n throw new RangeError(\"rate / timesPerYear must be > -1\");\n }\n\n if (contributionPerPeriod === 0) {\n if (principal === 0) return Number.POSITIVE_INFINITY;\n if (rate === 0) return targetFutureValue <= principal ? 0 : Number.POSITIVE_INFINITY;\n if (r < 0) return Number.POSITIVE_INFINITY;\n const n = Math.log(targetFutureValue / principal) / Math.log(1 + r);\n return Number.isFinite(n) && n >= 0 ? Math.ceil(n) : Number.POSITIVE_INFINITY;\n }\n\n if (rate === 0) {\n const needed = targetFutureValue - principal;\n if (needed <= 0) return 0;\n return Math.ceil(needed / contributionPerPeriod);\n }\n\n // With contributions: iterate until FV >= target\n let fv = principal;\n let periods = 0;\n while (fv < targetFutureValue && periods < maxPeriods) {\n if (contributionTiming === \"begin\") fv += contributionPerPeriod;\n fv = fv * (1 + r) + (contributionTiming === \"end\" ? contributionPerPeriod : 0);\n periods++;\n }\n if (fv >= targetFutureValue) return periods;\n throw new RangeError(\"maxPeriods exceeded before reaching target\");\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PresentValueParams = {\n futureValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Present value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function presentValue(params: PresentValueParams): number {\n const { futureValue: fv, rate, timesPerYear, years } = params;\n assertNonNegative(fv, \"futureValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return fv;\n\n const n = timesPerYear;\n const t = years;\n return fv / (1 + rate / n) ** (n * t);\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PresentValueOfAnnuityParams = {\n paymentPerPeriod: number;\n ratePerPeriod: number;\n periods: number;\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Present value of an annuity. PV = PMT * (1 - (1+r)^-n) / r. Due: multiply by (1+r).\n */\nexport function presentValueOfAnnuity(params: PresentValueOfAnnuityParams): number {\n const { paymentPerPeriod, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(paymentPerPeriod, \"paymentPerPeriod\");\n assertNonNegative(periods, \"periods\");\n\n if (periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pv = paymentPerPeriod * periods;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n }\n const pv = (paymentPerPeriod * (1 - (1 + ratePerPeriod) ** -periods)) / ratePerPeriod;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type RateToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n periods: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n lowerBound?: number;\n upperBound?: number;\n maxIterations?: number;\n tolerance?: number;\n};\n\nfunction assertContributionTiming(value: \"end\" | \"begin\", name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\n/**\n * Rate per period required to reach target future value in given periods.\n * Uses Newton-Raphson when contributions are present; closed form for lump sum.\n */\nexport function rateToReachGoal(params: RateToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n periods,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n lowerBound = -0.99,\n upperBound = 10,\n maxIterations = 100,\n tolerance = 1e-10,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertPositive(periods, \"periods\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(tolerance, \"tolerance\");\n assertContributionTiming(contributionTiming, \"contributionTiming\");\n if (lowerBound <= -1) throw new RangeError(\"lowerBound must be > -1\");\n if (upperBound <= lowerBound) throw new RangeError(\"upperBound must be greater than lowerBound\");\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (tolerance <= 0) throw new RangeError(\"tolerance must be > 0\");\n\n if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;\n\n if (contributionPerPeriod === 0) {\n if (targetFutureValue <= principal) return 0;\n if (principal === 0) {\n throw new RangeError(\n \"rateToReachGoal is undefined when principal is 0 and contributions are 0\",\n );\n }\n return (targetFutureValue / principal) ** (1 / periods) - 1;\n }\n\n const dueFactor = contributionTiming === \"begin\" ? 1 : 0;\n const fn = (r: number) => {\n const onePlusR = 1 + r;\n const onePlusRN = onePlusR ** periods;\n const fvLump = principal * onePlusRN;\n const annuityBase = r === 0 ? periods : (onePlusRN - 1) / r;\n const fvAnnuity = contributionPerPeriod * annuityBase * (1 + dueFactor * r);\n return fvLump + fvAnnuity - targetFutureValue;\n };\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-6 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const initialGuess =\n (targetFutureValue / (principal + contributionPerPeriod * periods)) ** (1 / periods) - 1;\n\n const newton = newtonRaphson({\n initialGuess: Number.isFinite(initialGuess) ? Math.max(initialGuess, lowerBound) : 0.01,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"rateToReachGoal did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n throw new RangeError(\"rateToReachGoal did not converge\");\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type RealReturnParams = { nominalReturn: number; inflationRate: number };\n\nexport function realReturn(params: RealReturnParams): number {\n const { nominalReturn, inflationRate } = params;\n assertFiniteNumber(nominalReturn, \"nominalReturn\");\n assertFiniteNumber(inflationRate, \"inflationRate\");\n if (inflationRate <= -1) return NaN;\n return (1 + nominalReturn) / (1 + inflationRate) - 1;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type RuleOf72Params = {\n rate: number;\n /** Use 69 for continuous-ish approximation (e.g. daily compounding). Default 72. */\n constant?: 72 | 69;\n};\n\n/**\n * Approximate years to double a lump sum at the given annual rate.\n * rate is decimal (e.g. 0.07 for 7%). Uses rule of 72 by default, or 69 if specified.\n */\nexport function ruleOf72(params: RuleOf72Params): number {\n const { rate, constant = 72 } = params;\n assertFiniteNumber(rate, \"rate\");\n assertPositive(rate, \"rate\");\n return constant / 100 / rate;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\ntype PaymentTiming = \"end\" | \"begin\";\n\nfunction assertTiming(value: PaymentTiming, name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\nfunction annuityDueFactor(ratePerPeriod: number, timing: PaymentTiming): number {\n return timing === \"begin\" ? 1 + ratePerPeriod : 1;\n}\n\nfunction futureValueFromCashFlows(\n ratePerPeriod: number,\n periods: number,\n payment: number,\n presentValue: number,\n timing: PaymentTiming,\n): number {\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n if (ratePerPeriod === 0) return -(presentValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) return Number.NaN;\n const paymentFv =\n payment * ((growth - 1) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n return -(presentValue * growth + paymentFv);\n}\n\nexport type FvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n presentValue: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel FV equivalent.\n */\nexport function fv(params: FvParams): number {\n const { ratePerPeriod, periods, payment = 0, presentValue, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertTiming(timing, \"timing\");\n\n const value = futureValueFromCashFlows(ratePerPeriod, periods, payment, presentValue, timing);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PV equivalent.\n */\nexport function pv(params: PvParams): number {\n const { ratePerPeriod, periods, payment = 0, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(futureValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const paymentPv =\n ((payment * (1 - 1 / growth)) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n const value = -futureValue / growth - paymentPv;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PmtParams = {\n ratePerPeriod: number;\n periods: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PMT equivalent.\n */\nexport function pmt(params: PmtParams): number {\n const { ratePerPeriod, periods, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(presentValue + futureValue) / periods;\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const numerator = -(futureValue + presentValue * growth) * ratePerPeriod;\n const denominator = (growth - 1) * annuityDueFactor(ratePerPeriod, timing);\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type NperParams = {\n ratePerPeriod: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel NPER equivalent.\n */\nexport function nper(params: NperParams): number {\n const { ratePerPeriod, payment, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) {\n const linear = -(presentValue + futureValue) / payment;\n return Number.isFinite(linear) && linear >= 0 ? linear : Number.NaN;\n }\n\n const adjustedPayment = payment * annuityDueFactor(ratePerPeriod, timing);\n const numerator = adjustedPayment - futureValue * ratePerPeriod;\n const denominator = adjustedPayment + presentValue * ratePerPeriod;\n if (numerator === 0 || denominator === 0) return Number.NaN;\n const ratio = numerator / denominator;\n if (ratio <= 0) return Number.NaN;\n\n const periods = Math.log(ratio) / Math.log(1 + ratePerPeriod);\n return Number.isFinite(periods) ? periods : Number.NaN;\n}\n\nexport type RateParams = {\n periods: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n guess?: number;\n tolerance?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\n/**\n * Excel RATE equivalent.\n */\nexport function rate(params: RateParams): number {\n const {\n periods,\n payment,\n presentValue,\n futureValue = 0,\n timing = \"end\",\n guess = 0.1,\n tolerance = 1e-10,\n maxIterations = 100,\n lowerBound = -0.999999999,\n upperBound = 10,\n } = params;\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(lowerBound)) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n\n const fn = (r: number) =>\n futureValueFromCashFlows(r, periods, payment, presentValue, timing) - futureValue;\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-5 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findRateBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"RATE did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"RATE did not converge\");\n}\n\nfunction ratePerPeriodIsInvalidForDomain(ratePerPeriod: number): boolean {\n return ratePerPeriod <= -1;\n}\n\nfunction findRateBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevValue !== undefined && prevX !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type LoanPaymentParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n};\n\n/**\n * Fixed periodic payment for an amortizing loan.\n *\n * - `annualRate` is nominal annual rate (e.g. 0.06 for 6%)\n * - payment returned is per period (`paymentsPerYear`)\n */\nexport function loanPayment(params: LoanPaymentParams): number {\n const { principal, annualRate, paymentsPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0) return 0;\n\n const r = annualRate / paymentsPerYear;\n if (r <= -1) {\n throw new RangeError(\"annualRate / paymentsPerYear must be > -1\");\n }\n if (r === 0) return principal / n;\n\n const value = (r * principal) / (1 - (1 + r) ** -n);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type AmortizationScheduleParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n extraPaymentPerPeriod?: number;\n};\n\nexport type AmortizationRow = {\n period: number;\n payment: number;\n principalPayment: number;\n interestPayment: number;\n balance: number;\n};\n\nexport type AmortizationScheduleResult = {\n paymentPerPeriod: number;\n schedule: AmortizationRow[];\n totalPaid: number;\n totalInterest: number;\n};\n\nexport function amortizationSchedule(\n params: AmortizationScheduleParams,\n): AmortizationScheduleResult {\n const { principal, annualRate, paymentsPerYear, years, extraPaymentPerPeriod = 0 } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n const scheduledN = Math.round(paymentsPerYear * years);\n if (scheduledN === 0 || principal === 0) {\n return { paymentPerPeriod: 0, schedule: [], totalPaid: 0, totalInterest: 0 };\n }\n\n const basePayment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n\n const schedule: AmortizationRow[] = [];\n let balance = principal;\n let totalPaid = 0;\n let totalInterest = 0;\n\n for (let period = 1; period <= scheduledN && balance > 0; period++) {\n const interestPayment = r === 0 ? 0 : balance * r;\n let payment = basePayment + extraPaymentPerPeriod;\n let principalPayment = payment - interestPayment;\n\n if (principalPayment > balance) {\n principalPayment = balance;\n payment = principalPayment + interestPayment;\n }\n\n balance = balance - principalPayment;\n if (Math.abs(balance) < 1e-12) balance = 0;\n\n totalPaid += payment;\n totalInterest += interestPayment;\n\n schedule.push({\n period,\n payment,\n principalPayment,\n interestPayment,\n balance,\n });\n }\n\n return {\n paymentPerPeriod: basePayment,\n schedule,\n totalPaid,\n totalInterest,\n };\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PayoffPeriodWithExtraParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n basePaymentPerPeriod: number;\n extraPaymentPerPeriod: number;\n};\n\n/**\n * Number of periods until the loan is paid off with the given base + extra payment.\n */\nexport function payoffPeriodWithExtra(params: PayoffPeriodWithExtraParams): number {\n const { principal, annualRate, paymentsPerYear, basePaymentPerPeriod, extraPaymentPerPeriod } =\n params;\n\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(basePaymentPerPeriod, \"basePaymentPerPeriod\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n if (principal <= 0) return 0;\n const payment = basePaymentPerPeriod + extraPaymentPerPeriod;\n if (payment <= 0) return Number.POSITIVE_INFINITY;\n\n const r = annualRate / paymentsPerYear;\n let balance = principal;\n let period = 0;\n\n while (balance > 1e-12 && period < 100000) {\n const interest = r > 0 ? balance * r : 0;\n if (payment <= interest) return Number.POSITIVE_INFINITY;\n const principalPaid = Math.min(payment - interest, balance);\n balance -= principalPaid;\n period++;\n }\n return balance <= 1e-12 ? period : Number.POSITIVE_INFINITY;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type RemainingBalanceParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n afterPeriodNumber: number;\n};\n\n/**\n * Remaining balance after a given number of payments on an amortizing loan.\n */\nexport function remainingBalance(params: RemainingBalanceParams): number {\n const { principal, annualRate, paymentsPerYear, years, afterPeriodNumber } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(afterPeriodNumber, \"afterPeriodNumber\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0 || afterPeriodNumber >= n) return 0;\n if (afterPeriodNumber <= 0) return principal;\n\n const payment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n const k = afterPeriodNumber;\n\n if (r === 0) return Math.max(0, principal - payment * k);\n const balance = principal * (1 + r) ** k - payment * (((1 + r) ** k - 1) / r);\n return Math.max(0, balance);\n}\n","import { assertFiniteNumber } from \"./assertions.js\";\n\nexport type RoundToCurrencyParams = {\n value: number;\n /** Decimal places. Default 2. */\n decimals?: number;\n /** 'half-up': 0.5 rounds up. 'half-even': banker's rounding. Default 'half-up'. */\n mode?: \"half-up\" | \"half-even\";\n};\n\n/**\n * Rounds a number to currency (default 2 decimals). half-up: 2.125 -> 2.13. half-even: 2.125 -> 2.12.\n */\nexport function roundToCurrency(params: RoundToCurrencyParams): number {\n const { value, decimals = 2, mode = \"half-up\" } = params;\n assertFiniteNumber(value, \"value\");\n const d = Math.max(0, Math.floor(decimals));\n const factor = 10 ** d;\n if (mode === \"half-even\") {\n const scaled = value * factor;\n const sign = scaled < 0 ? -1 : 1;\n const absScaled = Math.abs(scaled);\n const floorAbs = Math.floor(absScaled);\n const fraction = absScaled - floorAbs;\n const epsilon = 1e-12;\n if (Math.abs(fraction - 0.5) <= epsilon) {\n const nearestEven = floorAbs % 2 === 0 ? floorAbs : floorAbs + 1;\n return (sign * nearestEven) / factor;\n }\n return Math.round(scaled) / factor;\n }\n return Math.round(value * factor) / factor;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyverret/ratejs",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Lightweight, dependency-free TypeScript financial math library providing pure calculation utilities.",
|
|
5
5
|
"author": "Pierre-Yves Verret",
|
|
6
6
|
"license": "ISC",
|
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
51
51
|
"test": "vitest run",
|
|
52
52
|
"test:watch": "vitest",
|
|
53
|
-
"
|
|
53
|
+
"validate": "npm run lint && npm run typecheck && npm test && npm run build",
|
|
54
|
+
"release": "semantic-release",
|
|
55
|
+
"prepublishOnly": "npm run validate"
|
|
54
56
|
},
|
|
55
57
|
"publishConfig": {
|
|
56
58
|
"access": "public",
|
|
@@ -62,6 +64,8 @@
|
|
|
62
64
|
"devDependencies": {
|
|
63
65
|
"@biomejs/biome": "^2.4.4",
|
|
64
66
|
"@vitest/coverage-v8": "^3.2.4",
|
|
67
|
+
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
68
|
+
"semantic-release": "^24.2.9",
|
|
65
69
|
"tsup": "^8.5.0",
|
|
66
70
|
"typescript": "^5.9.2",
|
|
67
71
|
"vitest": "^3.2.4"
|