UNPKG

compound-calc

Version:

Compound Interest calculator that allows dynamic series of contributions

54 lines (53 loc) 2.31 kB
export function compound(initial, amount, years, interest, accrualPeriod = 1, contributionPeriod = 1, contributeBeforeInterest = false) { initial = Number(initial) * 100; years = Number(years); interest = Number(interest); const periods = accrualPeriod * years; const offsetContribution = contributeBeforeInterest ? 0 : 1; const rate = interest / accrualPeriod; // amount can be a flat amount, an array of amounts, or a function returning an array of amounts const emptyYears = (() => { if (typeof amount === 'number') { if (contributionPeriod >= accrualPeriod) { // if we're contributing faster than we're accruing interest, roll up the contributions per accrual period return Array(periods).fill(amount * (contributionPeriod / accrualPeriod)); } else { // otherwise populate the array with mix of zeroes and contributions return [...Array(periods)].map((x, i) => { if ((i + offsetContribution) % ((12 / contributionPeriod) * (accrualPeriod / 12)) === 0) { return amount; } else { return 0; } }); } } else if (Array.isArray(amount)) { return [...Array(periods)].map((x, i) => amount[i] || 0); } else if (typeof amount === 'function') { return [...Array(periods)].map(amount); } return []; })().map(x => x * 100); // add "year-zero" to beginning of years emptyYears.unshift(0); const annuityTotals = [...emptyYears].map((curr, i, arr) => { const offsetBefore = contributeBeforeInterest ? curr : 0; const offsetAfter = contributeBeforeInterest ? 0 : curr; if (arr[i - 1] !== undefined) { const totalFromAnnuity = (1 + rate) * (arr[i - 1] + offsetBefore); return arr[i] = totalFromAnnuity + offsetAfter; } else { return arr[i] = initial; } }).map(x => Math.round(x) / 100); return { result: annuityTotals, principal: emptyYears.map(x => Math.round(x) / 100), total: annuityTotals[annuityTotals.length - 1] }; }