Skip to content

Instantly share code, notes, and snippets.

@gillesdemey
Created December 3, 2017 18:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gillesdemey/6e34f99e622e16b64cf03ee85f1ed766 to your computer and use it in GitHub Desktop.
Save gillesdemey/6e34f99e622e16b64cf03ee85f1ed766 to your computer and use it in GitHub Desktop.
'use strict'
const AMOUNT = 300000
const YEARS = 25
const RATE = 2.19
const MONTHS = yearsToMonths(YEARS)
const MONTHLY = monthly(AMOUNT, YEARS, RATE)
// generate an array with shorted name of each month
const MONTHNAMES = new Array(12).fill().map((_, i) => {
return new Date(0, i).toLocaleString('en', { month: 'short' })
})
function monthly (amount, years, rate) {
const mPrate = prate(rate)
const months = yearsToMonths(years)
const mPow = Math.pow(1 + mPrate, months)
return amount * (mPrate * mPow) / (mPow - 1)
}
function monthlyBreakdown (amount, years, rate) {
let leftToPay = amount
let totalInterest = 0
const monthlyPay = monthly(amount, years, rate)
return new Array(yearsToMonths(years)).fill().map((_, month) => {
const interest = getInterest(leftToPay, rate)
const aflos = monthlyPay - interest
leftToPay -= aflos
totalInterest += interest
return { month, monthlyPay, aflos, interest, leftToPay }
})
}
const breakdown = monthlyBreakdown(AMOUNT, YEARS, RATE)
const totalCap = sum(breakdown, 'aflos')
const totalInterest = sum(breakdown, 'interest')
const totalSum = totalCap + totalInterest
const monthlyBreakdownLines = breakdown.map((perMonth, i) => {
const { month, monthlyPay, aflos, interest, leftToPay } = perMonth
return `${MONTHNAMES[i]} ${monthlyPay.toFixed(2)} ${aflos.toFixed(2)} ${interest.toFixed(2)} ${leftToPay.toFixed(2)}`
})
const yearlyBreakdownLines = chunk(breakdown, 12).map((months, i) => {
const yearlyPay = sum(months, 'monthlyPay').toFixed(2)
const yearlyAflos = sum(months, 'aflos').toFixed(2)
const yearlyInterest = sum(months, 'interest').toFixed(2)
const leftToPay = months.slice(12)
return `Year ${i + 1} ${yearlyPay} ${yearlyAflos} ${yearlyInterest} ${leftToPay}`
})
console.log(`
Quick & dirty mortgage simulator
Written by nib, (c) GPL
Modified by Gilles De Mey
Amount loaned ..... : € ${AMOUNT}
Duration .......... : ${YEARS} years
Duration .......... : ${yearsToMonths(YEARS)} months
Fixed rate ........ : ${RATE} %
Periodic rate...... : ${(prate(RATE) * 100).toFixed(3)} %
Monthly pay ....... : € ${MONTHLY.toFixed(6)}
Year 1
${monthlyBreakdownLines.slice(0, 12).join('\n ')}
${yearlyBreakdownLines.slice(1).join('\n')}
Total capital ..... : € ${totalCap.toFixed(2)}
Total interest .... : € ${totalInterest.toFixed(2)}
Sum ................: € ${totalSum.toFixed(2)}
`)
function yearsToMonths (years) {
return years * 12
}
function prate (rate) {
return Math.pow((rate / 100) + 1, 1 / 12) - 1
}
function getInterest (amount, rate) {
return prate(rate) * amount
}
// split array in smaller chunks
function chunk (list, size) {
return new Array(Math.ceil(list.length / size)).fill().map(_ => list.splice(0, size))
}
// sum of a property in an array
function sum (array, prop) {
return array.reduce((sum, obj) => sum += obj[prop], 0)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment