Amort

Table of Contents

Amort

  • Software to create an amortization schedule
  • Written in Python (requires Python 3)
  • MIT license

Features

  • Wide variety of basis conventions for monthly payments. The days can be calculated on the basis of actual days in the month or a fixed 30 days in the month. The length of the year can be calculated as the actual days (taking into account leap years) or as a fixed 365 or 360. By default the actual days in the year calculation uses the "civil year" convention, but you could specify the "anniversary" convention instead.
  • Payments may be specified as monthly, quarterly, semi-annual, or annual. For the last three, each period is treated as a fixed fraction of a year (1/4, 1/2, or a full year).
  • Irregular first payments may be specified, in the event that some payments are on different dates or for different amounts than later payments.
  • A fixed payment amount may be specified and the number of payments may be "unknown", in which case the number of payments necessary to pay off the loan in full will be calculated.
  • A fixed number of payments may be specified and payment amount may be "unknown", in which case payment amount will be calculated.
  • Specifying both the payment and the number of payments allows for a final "balloon" payment which can be (much) larger than the periodic payment.

Installation

The README file has more installation information. Essentially you download and unzip amort.zip into an appropriate directory (such as amort), then you create a small custom file in the same directory for each amortization schedule you wish to produce.

Simple Example

That custom file is really a small Python program and it can look like this. For a loan to John Smith, you might name the file johnsmith.py.

#!/usr/bin/env python3

from amort import Loan

loan1 = Loan (
        originDate="2015-07-10",
        loanAmount=2000.00,
        payment=100.00,
        interest=7,
        days="actual",
        basis="actual",
        dueDay=10,
        numberOfPayments="unknown")

loan1.amort()

The above specifies a loan in the amount of $2000.00 made on July 10, 2015 at 7% per annum, with a monthly payment of $100.00 due on the 10th of each month. Since the payment is specified, the number of payments is not specified (it is set to "unknown"), and the software will figure out how many payments are needed.

To actually create the amortization schedule, simply run that program. For example, in Linux, open a terminal, change to your amort directory, and execute it:

$ cd ~/amort
$ ./johnsmith.py

This displays the amortization schedule in the terminal. You can copy/paste it to a file and edit it further. Or, you can run it as follows to redirect the output to a file:

$ ./johnsmith.py > johnsmithloan.txt

Here is the output from the above:

   #        date  prev balance        payment   period             interest     principal   new balance
----  ----------  ------------   ------------   -------------  ------------  ------------  ------------
   1  2015-08-10      2,000.00         100.00   31/365                11.89         88.11      1,911.89
   2  2015-09-10      1,911.89         100.00   31/365                11.37         88.63      1,823.26
   3  2015-10-10      1,823.26         100.00   30/365                10.49         89.51      1,733.75
   4  2015-11-10      1,733.75         100.00   31/365                10.31         89.69      1,644.06
   5  2015-12-10      1,644.06         100.00   30/365                 9.46         90.54      1,553.52
   6  2016-01-10      1,553.52         100.00   22/365,9/366           9.23         90.77      1,462.75
   7  2016-02-10      1,462.75         100.00   31/366                 8.67         91.33      1,371.42
   8  2016-03-10      1,371.42         100.00   29/366                 7.61         92.39      1,279.03
   9  2016-04-10      1,279.03         100.00   31/366                 7.58         92.42      1,186.61
  10  2016-05-10      1,186.61         100.00   30/366                 6.81         93.19      1,093.42
  11  2016-06-10      1,093.42         100.00   31/366                 6.48         93.52        999.90
  12  2016-07-10        999.90         100.00   30/366                 5.74         94.26        905.64
  13  2016-08-10        905.64         100.00   31/366                 5.37         94.63        811.01
  14  2016-09-10        811.01         100.00   31/366                 4.81         95.19        715.82
  15  2016-10-10        715.82         100.00   30/366                 4.11         95.89        619.93
  16  2016-11-10        619.93         100.00   31/366                 3.68         96.32        523.61
  17  2016-12-10        523.61         100.00   30/366                 3.00         97.00        426.61
  18  2017-01-10        426.61         100.00   22/366,9/365           2.53         97.47        329.14
  19  2017-02-10        329.14         100.00   31/365                 1.96         98.04        231.10
  20  2017-03-10        231.10         100.00   28/365                 1.24         98.76        132.34
  21  2017-04-10        132.34         100.00   31/365                 0.79         99.21         33.13
  22  2017-05-10         33.13          33.32   30/365                 0.19         33.13          0.00

Of course, under Linux, the johnsmith.py file must be marked as executable, e.g.,

$ chmod +x johnsmith.py

Or, you can start by copying the included sample.py file, e.g.,

$ cp sample.py johnsmith.py

and not need to mark it executable (since sample.py was already marked executable).

Or, you can run it this way without marking it as executable:

$ python3 johnsmith.py

TMI

The previous example may display more information than you are interested in. In particular, you may not need the "period" column which indicates the fraction of a year covered by each payment. This can be removed easily with an editor, such as Emacs, that allows deleting rectangles.

This column is present to help you verify the correctness of the amortization schedule.

(Don't) Trust the Computer

Or, perhaps more accurately, don't trust me! I believe the calculations are correct when using the actual days conventions (actual/actual, actual/365, actual/360) but I am not nearly as confident about the 30 days conventions (30/actual, 30/365, 30/360). Please be vigilant regardless, but be especially vigilant if you use one of the 30 days conventions.

If you find an error, please email me at frank@pygmy.utoh.org with the details.

Further examples

#!/usr/bin/env python3

from amort import Loan

loan1 = Loan (
        originDate="2014-03-10",
        loanAmount=2000.00,
        payment=100.00,
        interest=7,
        firstPayments=(("2014-04-15", 100.00),
                       ("2014-05-10", 100.00)),
        days="actual",
        basis="actual",
        dueDay=10,
        numberOfPayments="unknown")

loan1.amort()

Above shows two first payments, after which the specified payment kicks in. Note, the first of the two has an "irregular" date in that it is not on the 10th of the month. The second of the two does not actually need to be specified, as it is "regular" in both amount and payment date.

Below is a similar example, but with four first payments. The fourth is not actually irregular and could have been omitted. Note each of the first payments consists of a date and an amount, wrapped in parenthesis marks and the entire group of first payments is wrapped in parenthesis marks.

#!/usr/bin/env python3

from amort import Loan

loan = Loan (
        originDate="2014-03-10",
        loanAmount=2000.00,
        payment=100.00,
        interest=7,
        firstPayments=(("2014-04-15",  50.00),
                       ("2014-05-12",  75.00),
                       ("2014-06-09",  45.00),
                       ("2014-07-10", 100.00)),
        days="actual",
        basis="actual",
        dueDay=10,
        numberOfPayments="unknown")

loan.amort()

Author: Frank Sergeant

Created: 2015-06-09 Tue 18:00

Emacs 24.4.1 (Org mode 8.2.10)

Validate