calculator.127local.net/public/calculators/interest.js
2025-09-01 16:06:47 -07:00

50 lines
2.5 KiB
JavaScript

import {currency, revive, persist, labelInput, labelSelect} from '/js/util.js';
export default {
id:'interest', name:'Interest (Simple & Compound)', about:'Compute simple or compound interest with flexible compounding and contributions.',
render(root){
const key='calc_interest_v1';
const s = revive(key,{principal:1000, rate:5, years:3, compound:'12', contrib:0, contribFreq:'12'});
const ui = document.createElement('div');
ui.append(
labelInput('Principal','number','principal', s.principal,{step:'0.01',min:'0'}),
labelInput('Annual rate (%)','number','rate', s.rate,{step:'0.0001',min:'0'}),
labelSelect('Compounding','compound', s.compound, [['1','Yearly'],['4','Quarterly'],['12','Monthly'],['365','Daily'],['0','Simple (no compounding)']]),
labelInput('Years','number','years', s.years,{step:'0.1',min:'0'}),
labelInput('Recurring contribution (per period below)','number','contrib', s.contrib,{step:'0.01',min:'0'}),
labelSelect('Contribution frequency','contribFreq', s.contribFreq, [['1','Yearly'],['4','Quarterly'],['12','Monthly']])
);
const out = document.createElement('div'); out.className='result'; ui.append(out);
function calc(){
const P = +ui.querySelector('[name=principal]').value||0;
const r = (+ui.querySelector('[name=rate]').value||0)/100;
const years = +ui.querySelector('[name=years]').value||0;
const n = +ui.querySelector('[name=compound]').value; // 0 => simple
const A = +ui.querySelector('[name=contrib]').value||0;
const f = +ui.querySelector('[name=contribFreq]').value||1;
let future=0, interest=0;
if(n===0){
interest = P * r * years;
const contribs = A * f * years;
future = P + interest + contribs;
}else{
const periods = n * years;
const i = r / n;
future = P * Math.pow(1+i, periods);
if(A>0){
const eff = Math.pow(1+i, n/f) - 1;
const m = Math.round(periods * f / n);
future += A * ((Math.pow(1+eff, m) - 1) / eff);
}
interest = future - P - (A>0?A*Math.round(n*years * f / n):0);
}
out.innerHTML = `
<div><strong>Future value:</strong> ${currency(future)}</div>
<div class="muted">Estimated interest earned: ${currency(Math.max(0,interest))}</div>
`;
persist(key,{principal:P, rate:r*100, years, compound:String(n), contrib:A, contribFreq:String(f)});
}
ui.addEventListener('input', calc); calc(); root.append(ui);
}
}