@pyverret/ratejs 1.1.1 → 1.1.3

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 CHANGED
@@ -8,9 +8,15 @@ 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
+
11
17
  ## Live Demo
12
18
 
13
- - GitHub Pages URL: `https://pyverret.github.io/ratejs/`
19
+ - GitHub Pages URL: [https://pyverret.github.io/ratejs/](https://pyverret.github.io/ratejs/)
14
20
  - Demo source: [`demo/`](./demo)
15
21
 
16
22
  Run locally:
@@ -44,16 +50,19 @@ const payment = pmt({
44
50
  ratePerPeriod: 0.06 / 12,
45
51
  periods: 360,
46
52
  presentValue: 250000,
47
- futureValue: 0,
48
- timing: "end",
53
+ futureValue: 0, // optional
54
+ timing: "end", // optional
49
55
  });
50
56
 
51
57
  const impliedRate = rate({
52
58
  periods: 360,
53
59
  payment,
54
60
  presentValue: 250000,
55
- futureValue: 0,
56
- timing: "end",
61
+ futureValue: 0, // optional
62
+ timing: "end", // optional
63
+ guess: 0.1, // optional
64
+ maxIterations: 100, // optional
65
+ tolerance: 1e-10, // optional
57
66
  lowerBound: -0.99, // optional
58
67
  upperBound: 10, // optional
59
68
  });
@@ -89,11 +98,11 @@ presentValue({ futureValue: 5000, rate: 0.06, timesPerYear: 12, years: 5 });
89
98
  ```ts
90
99
  investmentGrowth({
91
100
  initial: 1000,
92
- contributionPerPeriod: 100,
101
+ contributionPerPeriod: 100, // optional
93
102
  rate: 0.06,
94
103
  timesPerYear: 12,
95
104
  years: 2,
96
- contributionTiming: "end", // or "begin"
105
+ contributionTiming: "end", // optional ("end" | "begin")
97
106
  });
98
107
  ```
99
108
 
@@ -112,7 +121,8 @@ periodsToReachGoal({
112
121
  rate: 0.06,
113
122
  timesPerYear: 12,
114
123
  contributionPerPeriod: 0, // optional
115
- contributionTiming: "end",
124
+ contributionTiming: "end", // optional
125
+ maxPeriods: 100000, // optional
116
126
  });
117
127
  ```
118
128
 
@@ -120,6 +130,7 @@ Edge cases:
120
130
  - Returns `Infinity` when the goal is unreachable.
121
131
  - Throws `RangeError` when `rate / timesPerYear <= -1`.
122
132
  - Throws `RangeError` when `maxPeriods` is exceeded for contribution-based iteration.
133
+ - Throws `RangeError` when `contributionTiming` is not `"end"` or `"begin"`.
123
134
 
124
135
  - **`rateToReachGoal`** - Rate per period required to reach a target future value in a given number of periods.
125
136
 
@@ -128,8 +139,10 @@ rateToReachGoal({
128
139
  principal: 1000,
129
140
  targetFutureValue: 1500,
130
141
  periods: 24,
131
- contributionPerPeriod: 0,
132
- contributionTiming: "end",
142
+ contributionPerPeriod: 0, // optional
143
+ contributionTiming: "end", // optional
144
+ maxIterations: 100, // optional
145
+ tolerance: 1e-10, // optional
133
146
  lowerBound: -0.99, // optional
134
147
  upperBound: 10, // optional
135
148
  });
@@ -137,6 +150,7 @@ rateToReachGoal({
137
150
 
138
151
  Edge cases:
139
152
  - Throws `RangeError` when no root is found within search bounds.
153
+ - Throws `RangeError` when `contributionTiming` is not `"end"` or `"begin"`.
140
154
 
141
155
  - **`ruleOf72`** - Approximate years to double a lump sum at a given annual rate. Optional `constant: 69` for rule of 69.
142
156
 
@@ -158,8 +172,8 @@ cagr({ startValue: 1000, endValue: 2000, years: 10 });
158
172
  ```ts
159
173
  irr({
160
174
  cashFlows: [-1000, 300, 400, 500],
161
- guess: 0.1,
162
- maxIterations: 100,
175
+ guess: 0.1, // optional
176
+ maxIterations: 100, // optional
163
177
  lowerBound: -0.99, // optional
164
178
  upperBound: 10, // optional
165
179
  });
@@ -204,7 +218,7 @@ presentValueOfAnnuity({
204
218
  paymentPerPeriod: 100,
205
219
  ratePerPeriod: 0.01,
206
220
  periods: 36,
207
- timing: "end",
221
+ timing: "end", // optional
208
222
  });
209
223
  ```
210
224
 
@@ -215,7 +229,7 @@ paymentFromPresentValue({
215
229
  presentValue: 100000,
216
230
  ratePerPeriod: 0.005,
217
231
  periods: 360,
218
- timing: "end",
232
+ timing: "end", // optional
219
233
  });
220
234
  ```
221
235
 
@@ -243,7 +257,7 @@ amortizationSchedule({
243
257
  annualRate: 0.06,
244
258
  paymentsPerYear: 12,
245
259
  years: 30,
246
- extraPaymentPerPeriod: 50,
260
+ extraPaymentPerPeriod: 50, // optional
247
261
  });
248
262
  ```
249
263
 
@@ -280,7 +294,7 @@ Edge cases:
280
294
 
281
295
  ```ts
282
296
  roundToCurrency({ value: 2.125 }); // 2.13
283
- roundToCurrency({ value: 2.125, decimals: 2, mode: "half-even" });
297
+ roundToCurrency({ value: 2.125, decimals: 2, mode: "half-even" }); // decimals/mode optional
284
298
  ```
285
299
 
286
300
  ## 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;
@@ -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.1",
3
+ "version": "1.1.3",
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
- "prepublishOnly": "npm run lint && npm run typecheck && npm test && npm run build"
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"