Annuities are cool. They're fixed payments over a period of time. If you're living in England, there's another financial product called a *consol* that is an annuity that pays out in perpetuity. Amazing.

Below are simplified examples of how to calculate present value and future value for annuities. I wasn't intending to create a calculator as much as provide a really simple way to think about all the magic Microsoft Excel does behind the scenes.

Theres a lot of room for improvement but I think this is a pretty good starting point.

```
// Description
// https://helloacm.com/common-javascript-functions-for-financial-calculations/
class Currency{
static toUSD(num) {
num = Math.round(num * 100) * 0.01;
var currstring = num.toString();
if (currstring.match(/\./)) {
var curr = currstring.split('.');
} else {
var curr = [currstring, "00"];
}
curr[1] += "00";
curr[2] = "";
var returnval = "";
var length = curr[0].length;
// add 0 to decimal if necessary
for (var i = 0; i < 2; i++)
curr[2] += curr[1].substr(i, 1);
// insert commas for readability
for (i = length; (i - 3) > 0; i = i - 3) {
returnval = "," + curr[0].substr(i - 3, 3) + returnval;
}
returnval = curr[0].substr(0, i) + returnval + "." + curr[2];
return(returnval);
}
}
class Finance {
constructor(){
}
// Present Value Interest Factor for Annuities
// AKA: The present value of $1 a year for T years at an interest rate of R
PVIFA(rate, periods){
let annuityFactor = (1 - 1 / Math.pow(1 + rate, periods)) / rate;
// Truncate the value by 4 decimals
return annuityFactor.toFixed(4)
}
// Future Value of an Annuity
FVIFA(rate, periods){
let annuityFactor = (Math.pow(1 + rate, periods) - 1) / rate;
return annuityFactor
}
// Present Value of an Annuity
Annuity(cashflow, rate, periods){
return cashflow * this.PVIFA(rate, periods)
}
// Discounts are also known as opportunity costs
Discount(cashflow, rate, periods){
var discount = cashflow / Math.pow(1 + rate, periods)
return discount;
}
// Present Value of Perpetuity
Perpetuity(cashflow, rate){
let presentValue = cashflow / rate;
return presentValue;
}
// Present Value for Growing Perpetuity
GrowingPerpetuity(cashflow, discountRate, growthRate){
let presentValue = cashflow / (discountRate - growthRate);
return presentValue;
}
calculateAnnuity(){
// STEP 1 - Calculate the Present Value from the start of the Annuity
var cashflow = 50000;
var periods = 20;
var rate = 0.08;
var pv = this.Annuity(cashflow, rate, periods);
console.log("Present Value of Annuity #1: ", Currency.toUSD(pv));
}
calculateDelayedAnnuity(){
// Payment amount per period.
var amount = 500;
// Interest Rate
var rate = 0.10;
// The number of periods the investor has to wait to then start seeing payouts.
var periods = 5;
// The number of periods required for the annuity to mature
var maturityDate = periods - 1;
var pv = this.Annuity(amount, rate, maturityDate);
// Discount the present value of the annuity back to Date 0
var discount = this.Discount(pv, rate, periods);
console.log("Present Value of Annuity #2: ", Currency.toUSD(pv))
console.log("Present Value of Delayed Annuity #2: ", Currency.toUSD(discount));
}
calcualteFutureValueOfAnnuity(){
var cashflow = 3000;
var periods = 30;
var rate = 0.06
var fv = cashflow * this.FVIFA(rate, periods);
console.log("Future Value of an Annuity: ", Currency.toUSD(fv));
}
calculateAnnuityDue(){
var cashflow = 50000;
var rate = 0.08;
// Since the annuity will make its first payment today, you must subtract it.
var periods = 20;
periods = periods - 1;
// After you've calculated the 19 year annuity you must add back the initial payment
var pv = cashflow + this.Annuity(cashflow, rate, periods);
console.log("Annuity Due: ", Currency.toUSD(pv));
}
calculatePerpetuity(){
var cashflow = 10000;
var rate = 2.5;
var consol = this.Perpetuity(cashflow, rate)
console.log( "Perpetuity: ", Currency.toUSD(consol) );
}
calcualteGrowingPerpetuity(){
var cashflow = 100000;
var discountRate = 0.11;
var growthRate = 0.05;
var presentValue = this.GrowingPerpetuity(cashflow, discountRate, growthRate);
console.log( "Growing Perpetuity: ", Currency.toUSD(presentValue) )
}
}
const finance = new Finance();
finance.calculateAnnuity();
finance.calculateDelayedAnnuity()
finance.calculateAnnuityDue();
finance.calcualteFutureValueOfAnnuity();
finance.calculatePerpetuity();
finance.calcualteGrowingPerpetuity();
```