@pyverret/ratejs 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,24 @@ Lightweight, dependency-free TypeScript financial math library providing pure ca
8
8
  npm i @pyverret/ratejs
9
9
  ```
10
10
 
11
+ ## Validate Before Push
12
+
13
+ ```bash
14
+ npm run validate
15
+ ```
16
+
17
+ ## Automated Releases
18
+
19
+ Releases are managed by `semantic-release` on pushes to `main`.
20
+
21
+ Required GitHub secrets:
22
+ - `NPM_TOKEN`: npm automation token with publish access.
23
+
24
+ Behavior:
25
+ - Conventional Commits drive version bumps (`fix` = patch, `feat` = minor, `feat!` or `BREAKING CHANGE` = major).
26
+ - Release workflow runs `npm run validate` before publishing.
27
+ - Git tags use format `vX.Y.Z`.
28
+
11
29
  ## Live Demo
12
30
 
13
31
  - GitHub Pages URL: `https://pyverret.github.io/ratejs/`
@@ -44,16 +62,19 @@ const payment = pmt({
44
62
  ratePerPeriod: 0.06 / 12,
45
63
  periods: 360,
46
64
  presentValue: 250000,
47
- futureValue: 0,
48
- timing: "end",
65
+ futureValue: 0, // optional
66
+ timing: "end", // optional
49
67
  });
50
68
 
51
69
  const impliedRate = rate({
52
70
  periods: 360,
53
71
  payment,
54
72
  presentValue: 250000,
55
- futureValue: 0,
56
- timing: "end",
73
+ futureValue: 0, // optional
74
+ timing: "end", // optional
75
+ guess: 0.1, // optional
76
+ maxIterations: 100, // optional
77
+ tolerance: 1e-10, // optional
57
78
  lowerBound: -0.99, // optional
58
79
  upperBound: 10, // optional
59
80
  });
@@ -89,11 +110,11 @@ presentValue({ futureValue: 5000, rate: 0.06, timesPerYear: 12, years: 5 });
89
110
  ```ts
90
111
  investmentGrowth({
91
112
  initial: 1000,
92
- contributionPerPeriod: 100,
113
+ contributionPerPeriod: 100, // optional
93
114
  rate: 0.06,
94
115
  timesPerYear: 12,
95
116
  years: 2,
96
- contributionTiming: "end", // or "begin"
117
+ contributionTiming: "end", // optional ("end" | "begin")
97
118
  });
98
119
  ```
99
120
 
@@ -112,7 +133,8 @@ periodsToReachGoal({
112
133
  rate: 0.06,
113
134
  timesPerYear: 12,
114
135
  contributionPerPeriod: 0, // optional
115
- contributionTiming: "end",
136
+ contributionTiming: "end", // optional
137
+ maxPeriods: 100000, // optional
116
138
  });
117
139
  ```
118
140
 
@@ -120,6 +142,7 @@ Edge cases:
120
142
  - Returns `Infinity` when the goal is unreachable.
121
143
  - Throws `RangeError` when `rate / timesPerYear <= -1`.
122
144
  - Throws `RangeError` when `maxPeriods` is exceeded for contribution-based iteration.
145
+ - Throws `RangeError` when `contributionTiming` is not `"end"` or `"begin"`.
123
146
 
124
147
  - **`rateToReachGoal`** - Rate per period required to reach a target future value in a given number of periods.
125
148
 
@@ -128,8 +151,10 @@ rateToReachGoal({
128
151
  principal: 1000,
129
152
  targetFutureValue: 1500,
130
153
  periods: 24,
131
- contributionPerPeriod: 0,
132
- contributionTiming: "end",
154
+ contributionPerPeriod: 0, // optional
155
+ contributionTiming: "end", // optional
156
+ maxIterations: 100, // optional
157
+ tolerance: 1e-10, // optional
133
158
  lowerBound: -0.99, // optional
134
159
  upperBound: 10, // optional
135
160
  });
@@ -137,6 +162,7 @@ rateToReachGoal({
137
162
 
138
163
  Edge cases:
139
164
  - Throws `RangeError` when no root is found within search bounds.
165
+ - Throws `RangeError` when `contributionTiming` is not `"end"` or `"begin"`.
140
166
 
141
167
  - **`ruleOf72`** - Approximate years to double a lump sum at a given annual rate. Optional `constant: 69` for rule of 69.
142
168
 
@@ -158,8 +184,8 @@ cagr({ startValue: 1000, endValue: 2000, years: 10 });
158
184
  ```ts
159
185
  irr({
160
186
  cashFlows: [-1000, 300, 400, 500],
161
- guess: 0.1,
162
- maxIterations: 100,
187
+ guess: 0.1, // optional
188
+ maxIterations: 100, // optional
163
189
  lowerBound: -0.99, // optional
164
190
  upperBound: 10, // optional
165
191
  });
@@ -204,7 +230,7 @@ presentValueOfAnnuity({
204
230
  paymentPerPeriod: 100,
205
231
  ratePerPeriod: 0.01,
206
232
  periods: 36,
207
- timing: "end",
233
+ timing: "end", // optional
208
234
  });
209
235
  ```
210
236
 
@@ -215,7 +241,7 @@ paymentFromPresentValue({
215
241
  presentValue: 100000,
216
242
  ratePerPeriod: 0.005,
217
243
  periods: 360,
218
- timing: "end",
244
+ timing: "end", // optional
219
245
  });
220
246
  ```
221
247
 
@@ -243,7 +269,7 @@ amortizationSchedule({
243
269
  annualRate: 0.06,
244
270
  paymentsPerYear: 12,
245
271
  years: 30,
246
- extraPaymentPerPeriod: 50,
272
+ extraPaymentPerPeriod: 50, // optional
247
273
  });
248
274
  ```
249
275
 
@@ -280,7 +306,7 @@ Edge cases:
280
306
 
281
307
  ```ts
282
308
  roundToCurrency({ value: 2.125 }); // 2.13
283
- roundToCurrency({ value: 2.125, decimals: 2, mode: "half-even" });
309
+ roundToCurrency({ value: 2.125, decimals: 2, mode: "half-even" }); // decimals/mode optional
284
310
  ```
285
311
 
286
312
  ## Design
package/dist/index.cjs CHANGED
@@ -301,6 +301,11 @@ function paymentFromPresentValue(params) {
301
301
  }
302
302
 
303
303
  // src/interest/periodsToReachGoal.ts
304
+ function assertContributionTiming(value, name) {
305
+ if (value !== "end" && value !== "begin") {
306
+ throw new RangeError(`${name} must be "end" or "begin"`);
307
+ }
308
+ }
304
309
  function periodsToReachGoal(params) {
305
310
  const {
306
311
  principal,
@@ -317,6 +322,7 @@ function periodsToReachGoal(params) {
317
322
  assertPositive(timesPerYear, "timesPerYear");
318
323
  assertNonNegative(contributionPerPeriod, "contributionPerPeriod");
319
324
  assertPositive(maxPeriods, "maxPeriods");
325
+ assertContributionTiming(contributionTiming, "contributionTiming");
320
326
  if (targetFutureValue <= principal) return 0;
321
327
  const r = rate2 / timesPerYear;
322
328
  if (r <= -1) {
@@ -372,6 +378,11 @@ function presentValueOfAnnuity(params) {
372
378
  }
373
379
 
374
380
  // src/interest/rateToReachGoal.ts
381
+ function assertContributionTiming2(value, name) {
382
+ if (value !== "end" && value !== "begin") {
383
+ throw new RangeError(`${name} must be "end" or "begin"`);
384
+ }
385
+ }
375
386
  function rateToReachGoal(params) {
376
387
  const {
377
388
  principal,
@@ -392,13 +403,13 @@ function rateToReachGoal(params) {
392
403
  assertFiniteNumber(upperBound, "upperBound");
393
404
  assertFiniteNumber(maxIterations, "maxIterations");
394
405
  assertFiniteNumber(tolerance, "tolerance");
406
+ assertContributionTiming2(contributionTiming, "contributionTiming");
395
407
  if (lowerBound <= -1) throw new RangeError("lowerBound must be > -1");
396
408
  if (upperBound <= lowerBound) throw new RangeError("upperBound must be greater than lowerBound");
397
409
  if (!Number.isInteger(maxIterations) || maxIterations <= 0) {
398
410
  throw new RangeError("maxIterations must be a positive integer");
399
411
  }
400
412
  if (tolerance <= 0) throw new RangeError("tolerance must be > 0");
401
- if (periods === 0) return 0;
402
413
  if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;
403
414
  if (contributionPerPeriod === 0) {
404
415
  if (targetFutureValue <= principal) return 0;
@@ -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.2",
4
4
  "description": "Lightweight, dependency-free TypeScript financial math library providing pure calculation utilities.",
5
5
  "author": "Pierre-Yves Verret",
6
6
  "license": "ISC",
@@ -50,7 +50,9 @@
50
50
  "typecheck": "tsc -p tsconfig.json --noEmit",
51
51
  "test": "vitest run",
52
52
  "test:watch": "vitest",
53
- "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"