Amortize.js

Table of Contents

Fork me on GitHub

1 About this program   info

This is a literate program authored in org-mode.

The program generate a JavaScript file called amortize.js.

2 Source Code   code

The source code is written JavaScript; and implements:

function name purpose
pmt Calculate amortized payment
compute-schedule Computes amortization schedule as multi-dimensional array

2.1 Calculate Payment

The function 'pmt' computes the payment amount for a loan.

The function accepts arguments:

name comments
rate is the interest rate for the loan.
nper is the total number of payments for the loan.
pv is the present value, or the total amount that a series of future payments is worth now; also known as the principal.
  1. The function signature:
    pmt(rate,nper,pv)
    
  2. In order to calculate the payment we need to first calculate the Present Value Interest Factor (PVIF).o
    pvif = Math.pow( 1 + rate, nper);
    
  3. Using the PVIF we can calculate the payment.
    pmt = rate / (pvif - 1) * -(pv * pvif);
    
  4. Finally, the sections are combined into a function.
    function pmt(rate,nper,pv) {
        var pvif, pmt;
    
        pvif = Math.pow( 1 + rate, nper);
        pmt = rate / (pvif - 1) * -(pv * pvif);   
    
        return pmt;
    };
    

2.2 Calculate Schedule

The 'computeSchedule' function to compute amortization schedule is named 'computeSchedule'.

The function accepts arguments:

name comments
loan_amount is the amount borrowed to purchase the property.
interest_rate is the percentage used to calculate interest due.
payments_per_year is the number of payments made in a calendar year.
years is the number of years.
payment is the amount of the payment each period.
  1. The function signature is:
    computeSchedule(loan_amount, interest_rate, payments_per_year, years, payment)
    
  2. Define an array to capture the schedule.
    var schedule = [];
    
  3. Define a variable to track the remaining balance.
    var remaining = loan_amount;
    
  4. Compute the total number of payments.
    var number_of_payments = payments_per_year * years;
    
  5. Loop through all of the periods and capture the entries in the schedule.
    for (var i=0; i<=number_of_payments; i++) {
        var interest = remaining * (interest_rate/100/payments_per_year);
        var principle = (payment-interest);
        var row = [i, principle>0?principle:0, interest>0?interest:0, remaining>0?remaining:0];
        schedule.push(row);
        remaining -= principle
    }
    
  6. Finally, the sections are combined into a function.
    function computeSchedule(loan_amount, interest_rate, payments_per_year, years, payment) {
        var schedule = [];
        var remaining = loan_amount;
        var number_of_payments = payments_per_year * years;
    
        for (var i=0; i<=number_of_payments; i++) {
            var interest = remaining * (interest_rate/100/payments_per_year);
            var principle = (payment-interest);
            var row = [i, principle>0?principle:0, interest>0?interest:0, remaining>0?remaining:0];
            schedule.push(row);
            remaining -= principle
        }
    
        return schedule;
    }
    

3 Tests   code

3.1 Should be 297.47

function pmt(rate,nper,pv) {
    var pvif, pmt;

    pvif = Math.pow( 1 + rate, nper);
    pmt = rate / (pvif - 1) * -(pv * pvif);   

    return pmt;
};

console.log('loan_amount: ' + loan_amount);
console.log('interest_rate: ' + interest_rate);
console.log('payments_per_year: ' + payments_per_year);
console.log('years: ' + years);
console.log( "The calculated payment is: " + 
             pmt(interest_rate/100/payments_per_year, payments_per_year * years, -loan_amount)
             .toFixed(2) );
loan_amount: 10000
interest_rate: 4.5
payments_per_year: 12
years: 3
The calculated payment is: 297.47

3.2 Should be 2245.22

loan_amount: 500000
interest_rate: 3.5
payments_per_year: 12
years: 30
The calculated payment is: 2245.22

3.3 Generate Schedule

function computeSchedule(loan_amount, interest_rate, payments_per_year, years, payment) {
    var schedule = [];
    var remaining = loan_amount;
    var number_of_payments = payments_per_year * years;

    for (var i=0; i<=number_of_payments; i++) {
        var interest = remaining * (interest_rate/100/payments_per_year);
        var principle = (payment-interest);
        var row = [i, principle>0?principle:0, interest>0?interest:0, remaining>0?remaining:0];
        schedule.push(row);
        remaining -= principle
    }

    return schedule;
}

console.log('loan_amount: ' + loan_amount);
console.log('interest_rate: ' + interest_rate);
console.log('payments_per_year: ' + payments_per_year);
console.log('years: ' + years);
console.log('payment: ' + payment);
console.log( JSON.stringify(
    computeSchedule(loan_amount, interest_rate, payments_per_year, years, payment), 0, 4
))
loan_amount: 10000
interest_rate: 4.5
payments_per_year: 12
years: 3
payment: 297.47
[
    [
	0,
	259.97,
	37.5,
	10000
    ],
    [
	1,
	260.94488750000005,
	36.5251125,
	9740.03
    ],
    [
	2,
	261.92343082812505,
	35.546569171875,
	9479.0851125
    ],
    [
	3,
	262.9056436937305,
	34.56435630626953,
	9217.161681671876
    ],
    [
	4,
	263.89153985758196,
	33.578460142418045,
	8954.256037978146
    ],
    [
	5,
	264.8811331320479,
	32.58886686795211,
	8690.364498120563
    ],
    [
	6,
	265.8744373812931,
	31.59556261870693,
	8425.483364988515
    ],
    [
	7,
	266.87146652147294,
	30.59853347852708,
	8159.608927607222
    ],
    [
	8,
	267.8722345209285,
	29.597765479071555,
	7892.737461085749
    ],
    [
	9,
	268.87675540038197,
	28.593244599618075,
	7624.86522656482
    ],
    [
	10,
	269.8850432331334,
	27.584956766866643,
	7355.988471164438
    ],
    [
	11,
	270.89711214525767,
	26.57288785474239,
	7086.103427931304
    ],
    [
	12,
	271.9129763158023,
	25.557023684197674,
	6815.206315786047
    ],
    [
	13,
	272.9326499769866,
	24.537350023013413,
	6543.293339470244
    ],
    [
	14,
	273.95614741440033,
	23.513852585599714,
	6270.360689493257
    ],
    [
	15,
	274.98348296720434,
	22.486517032795714,
	5996.404542078857
    ],
    [
	16,
	276.01467102833135,
	21.455328971668695,
	5721.4210591116525
    ],
    [
	17,
	277.0497260446876,
	20.420273955312453,
	5445.406388083321
    ],
    [
	18,
	278.08866251735515,
	19.381337482644877,
	5168.356662038634
    ],
    [
	19,
	279.13149500179526,
	18.338504998204794,
	4890.267999521278
    ],
    [
	20,
	280.17823810805197,
	17.291761891948063,
	4611.136504519483
    ],
    [
	21,
	281.2289065009572,
	16.24109349904287,
	4330.958266411431
    ],
    [
	22,
	282.2835149003358,
	15.186485099664278,
	4049.729359910474
    ],
    [
	23,
	283.342078081212,
	14.127921918788019,
	3767.4458450101383
    ],
    [
	24,
	284.40461087401656,
	13.065389125983472,
	3484.1037669289262
    ],
    [
	25,
	285.4711281647941,
	11.998871835205911,
	3199.6991560549095
    ],
    [
	26,
	286.5416448954121,
	10.928355104587933,
	2914.2280278901153
    ],
    [
	27,
	287.6161760637699,
	9.853823936230137,
	2627.6863829947033
    ],
    [
	28,
	288.69473672400903,
	8.775263275991001,
	2340.0702069309336
    ],
    [
	29,
	289.7773419867241,
	7.692658013275967,
	2051.3754702069245
    ],
    [
	30,
	290.86400701917427,
	6.605992980825752,
	1761.5981282202006
    ],
    [
	31,
	291.95474704549616,
	5.515252954503849,
	1470.7341212010263
    ],
    [
	32,
	293.0495773469168,
	4.420422653083238,
	1178.7793741555301
    ],
    [
	33,
	294.1485132619677,
	3.3214867380323003,
	885.7297968086134
    ],
    [
	34,
	295.2515701867001,
	2.218429813299921,
	591.5812835466456
    ],
    [
	35,
	296.35876357490025,
	1.1112364250997957,
	296.3297133599455
    ],
    [
	36,
	297.4701089383061,
	0,
	0
    ]
]

Date: <2014-09-26 Fri>

Author: Peter Moresi

Created: 2015-03-10 Tue 23:45

Emacs 24.4.1 (Org mode 8.2.10)

Validate