Mortgage Calculation Demo -- Commentary and Description

Program Description and General Comments

This demo will allow you to calculate the regularly scheduled series of payments needed to pay off a mortgage or any other type of long term annuity. Besides, displaying the payment schedule in table form the program will also solve for one of either two unknown variables in the calculation. The program can either be asked to solve for the payment value needed to pay off the debt in exactly equal sized payments or the time it takes to pay off the debt given the current set of financial data. Originally, I also planned to solve for the interest rate, but my browser (Internet Explorer) seems to choke on this.

Overview of The Mortgage Class

The main areas of interest in this class are the member functions: The other methods are not very interesting. They are basically utility functions used for setting the internal class data and for displaying the final results. The above listed functions are the one's that will be doing the actual calculation work.

Overview of SetupData method

The SetupData function is used to initialize member variables of a Mortgage object based on the data entered onto the form. Specifically it initializes: These internal values are used within the program to do the calculations. The Min and Max values are used as the high and low ends for the bisection root finding algorithm used for finding the value required for exact sized mortgage payments.

Overview of Amortize method

The amortize method implements the algorithm for mortgage amortization. Amortize is just financial jargon for paying off a debt in regularly scheduled payments. A simple for loop is able to accomplish this. Within the loop, each successive balance value is subtracted by the payment value to get the result of the debt amortization. In addition to this, each payment period has a break down of the payment as to what portion goes toward paying the interest and what goes toward paying the principal of the loan. The payment, interest paid, principal paid and balance are stored in an array of objects with each object being able to store these four values. The amortize method returns the ending balance after all payments have been completed. A positive result would indicate that the payment value was not sufficiently high enough to pay off the loan within the specified time interval. A negative value indicates that it was too high. A zero value would indicate that the loan was paid off with exactly equal payments of the specified size. These return values are very useful to the root finding algorithm covered later on.

Overview of FindPayment method

The find payment method implements the textbook bisection root finding algorithm to find the required value for exact equal sized payments to fit a given payment schedule. The idea of the algorithm is simple: Repeatedly execute the function with the midpoint value of the high and low ends passed as the argument. If the result comes out positive it means the midpoint value was too low. We find another midpoint using the current midpoint as the low end value in the calculation. If the result comes out negative it means the midpoint value was too high. We find another midpoint using the current midpoint as the high end value in the calculation.

There are other methods available for root finding. Another commonly used one is Newton's method. I did not choose to use Newton's method because I saw no real advantage in using it over the bisection method in this situation. Newton's method is able to find the root of a function which has both increasing and decreasing slope over an interval, but the amortization function only has decreasing slope over the whole of its interval. The bisection method is quite reliable in finding roots of function that are either increasing or decreasing so there's no disadvantage in this area. Furthermore, we need to solve for the derivative of the function when applying Newton's method. In the case of the amortization function there is no easy way to simplify the function into its derivative form. The only choice is to call the amortization method twice per iteration, once for the function value and once for the value given by the derivative of the function. Any efficiency gained by Newton's method over the bisection method would not be overwhelming in this case.

Overview of FindRate method

The FindRate method also uses the bisection method, but on a different term of the amortization formula. The method solves for the interest rate needed for equal sized payments of the given payment value to completely pay off the mortgage within the given amount of time. To do this we simply solve for the low end rate by re-arranging the formula for finding the "Max" high end payment value in the SetupData method. We also solve for the high end rate by re-arranging the formula for finding the "Min" low end payment value. By doing this we assume that the given payment value is at the lowest allowable value and therefore, requires the highest interest rate or that the given payment value is at the high end and therefore, requires the lowest interest rate value. Using the bisection method we can verify any matching values that lie in between these two extremes.

Overview of FindTime Method

The FindTime method simply runs the Amortize method once to find the required time to completely eliminate the mortgage. If solving for "time required" is specified for a mortgage object then the loop iteration limit within the Amortize method is set to maximum number of iterations instead of the specified TotalPeriods. This is so that the program can iterate through an arbitrary number of payment periods until the resulting balance finally reaches zero. The iteration limit is set high enough as to allow reasonably valid time intervals. One limit in solving for required time is that the payment value must be greater or equal to a specified minimum value. This is reasonable, since the payment value must be at least high enough to repay the interest on the loan. To have any chance of repaying the loan, the payment value must also be high enough to pay at least a small portion of the principal during each payment period.

Overview of CheckArguments Method

The CheckArgument method does exactly what its name describes. The method checks the input arguments of the user to determine if they meet a specific boundary condition like an absolute minimum value. If the input values fail in any of the tests the procedure returns false and the program will not execute. More specifically the CheckArgument method tests for:

Prototype of Mortgage Program

A prototype of the mortgage program was first written in C++ to test ideas and algorithms. Prototyping is a commonly used technique in software projects to make a model of the problem to be solved. The idea is to build a small scale working model which closely follows how the real program should function. Once the prototype is finished and working according to plan, the ideas used in its development are transferred over in the development of the real program. The C++ prototype program that I've made is an exact working copy of the JavaScript demo program used in this website. In fact its more functional since the solve for "interest rate" feature works on the prototype. The only minor glitch is that it is command line driven (sorry no GUI). Here it is: compound.cpp

Testing The Mortgage Calculator

As with any other serious programs, when preparing to test the mortgage program we must come up with a detailed and complete test plan so we can be sure to catch most if not all of the potential errors in the program. The test plan for the mortgage program is simple and involves two stages: First we test the general case. To do this, we input typical values into the form and then execute the script. The script should produce the correct answers for the requested calculation. With a calculator we can verify that these answers are indeed correct.

Next we do boundary value testing. To do this, we input values into the program that are almost at the bounding limit for valid data. For example, the lower bound limit for the payment value when solving for "time needed" is $806.705 given the rest of the financial data is: so we put in 806.71 which is just 1 cent greater than $806.705 as the payment value and execute the script. It should still give us the correct results even at this lower limit.

The boundary values for the rest of the tests are as follows: The rest of the financial data is the same as the preceeding list.

Note On Performance of Demo Program

Note: because of the performance problems inherent in JavaScript and other interpreted scripting languages it is best to do the boundary testing of the program in a compiled language like C++. The prototype for this demo was written in C++ so you can use the prototype to do the testing instead of the demo itself. The C++ version is faster and doesn't take nearly as much resources to run.

Summary

Although this is a relatively simple program in terms of coding and design, it has the most immediate and practical uses of all the demo programs. With this program you could generate payment schedules for mortgages or loans. You could also answer a number of what-if scenarios, by changing the financial data listed in the form controls. You can also find out some computed values like the value of equal sized payments and the total time needed to repay the loan. In the actual implementation of the program I used simple conditional loops and textbook examples of algorithms, nothing fancy at all.