Inventory Management Software

Kardex Tauro

Kardex Tauro® Inventory Software is designed to efficiently manage your warehouse or storage facility, and it is quick and easy to learn.

Kardex Tauro is free for non-commercial use.
It does not require an internet connection; it runs on Windows.

Python code: loan amortization schedule (free download)

Python code: loan amortization schedule (free download)

Borrowing money is the easy half. Understanding how each instalment is split is where most people get lost. When the bank says «fixed payment», it is natural to picture the principal dropping by the same amount every month. It does not: in the early payments almost everything you hand over is interest and only a sliver touches the principal, and that is why the loan seems to stand still. This Python program builds the complete amortization schedule, month by month, with opening balance, payment, interest, principal repaid and closing balance, and then gives you the two numbers that matter: what you pay in total and how much of it is interest.

It is written for three readers. The small-business owner weighing a loan who wants to see the real cost before signing. The accountant who needs the schedule to post this period's interest separately from the principal repaid. And the warehouse or stockroom manager who took the loan to buy goods and wants to understand why the balance the bank reports never matches the one they worked out by hand.

Everything travels inside the ZIP and nothing else has to be installed: Python 3.11 or newer, and that is the whole list. You get the program, the sample loan, the expected output and a short guide.

⬇ Descargar el código (ZIP)

These are the files waiting for you when you unzip the folder:

FileWhat it is for
amortizacion_credito.pyThe complete program, commented line by line
datos/credito.csvThe sample loan: a single row with amount, nominal annual rate, term in months and disbursement date
salida_ejemplo.txtThe output you should get, so you can compare it with yours
README.mdThe instructions and the details of the calculation, in short

What the program does

  1. Reads datos/credito.csv, which holds one single row: loan amount, nominal annual rate, term in months and disbursement date.
  2. Turns the annual rate into a monthly one: the nominal rate is divided by one hundred and by twelve. A nominal annual rate of eighteen percent comes out as one and a half percent a month.
  3. Works out the fixed payment with the French-system formula and rounds it to cents.
  4. Walks the months one by one: charges interest on the balance still owed, works out how much of the payment cuts the principal and leaves the closing balance of that month.
  5. Adjusts the last payment to the cent. Without that tweak the closing balance would end at a tiny amount instead of zero and the schedule would never tie.
  6. Builds every due date with its own function, so it never trips over a day that does not exist in the target month.
  7. Prints the summary with four totals and saves the schedule to salida/amortizacion.csv, ready to open in Excel.

How to run it

First install Python 3.11 or newer from the official site, ticking the box that adds Python to your PATH. Then unzip the whole folder somewhere convenient and open a terminal inside that folder: on Windows you can type cmd in the address bar of the file explorer. Once you are there, call the program by name:

python amortizacion_credito.py

There is no library to install: the program uses only what ships with Python. It runs in under a second, prints the schedule on screen and leaves the result file in the salida folder. If your machine does not recognise the python command, try py amortizacion_credito.py, which is the short form the Windows installer sets up.

The code, explained

These are the five pieces that really matter. Everything else is file reading and column formatting.

The fixed-payment formula. This is the one from the French system: the payment equals the amount times the monthly rate, divided by one minus the discount factor for the term.

def cuota_fija(monto: Decimal, tasa: Decimal, plazo: int) -> Decimal:
    """Computes the fixed payment of the French system, rounded to cents."""
    # # French system: payment = amount * i / (1 - (1+i)^-n). Decimal handles (1+i)**-n
    factor = (UNO + tasa) ** -plazo
    return redondear(monto * tasa / (UNO - factor))

The sum is done with Decimal, not with floating-point numbers, and the result is rounded to cents. It sounds like a technicality and it is money: if the amount were stored as a binary decimal, the cents would drift payment after payment and the principal repaid would no longer add up to exactly the loan amount.

The monthly rate. The rate the bank advertises is nominal annual, so the program divides it by one hundred and by twelve. That single line is the key to the whole exercise:

    tasa = tasa_anual / CIEN / DOCE                 # # Monthly rate = nominal annual rate / 100 / 12

With a nominal annual rate of eighteen percent the monthly rate is one and a half percent. Charged every month on the balance still owed, it weighs rather more than the yearly figure the bank puts on the poster.

The heart of the calculation. Here is why a loan seems to stand still at the beginning: interest is charged on the balance still owed, and that balance is large in the first months, so the interest is large too.

    for numero in range(1, plazo + 1):
        interes = redondear(saldo * tasa)          # # Interest is charged on the balance still owed: that is why it weighs so much at first
        # # The last payment absorbs the rounding cents so that the balance ends at zero
        cuota_mes = redondear(saldo + interes) if numero == plazo else cuota
        abono = redondear(cuota_mes - interes)     # # Principal repaid: what really cuts the debt (payment - interest)
        final = redondear(saldo - abono)

Read the block slowly, because it sums up the whole system. The interest of the month comes from the opening balance multiplied by the rate. The payment minus the interest is what genuinely cuts the debt, and the closing balance is the opening balance minus that principal. The comment on the last line explains why the final payment is almost never the same as the others and why the program has to adjust it.

Dates without surprises. Adding months to a date looks trivial until a thirty-first or a February shows up:

def sumar_meses(fecha: date, meses: int) -> date:
    """Adds months to a date and pulls the day to the last day of the month when it does not exist."""
    # Se pasa el año a meses para no equivocarse al cruzar diciembre.
    total = fecha.year * 12 + (fecha.month - 1) + meses

If the disbursement day does not exist in the target month, the program falls back to the last day of that month. A loan born on a thirty-first never hands you an impossible date.

The two checks. They close the exercise and they are the part you will value most once you load your own data:

    print(f"  Sum of principal = amount: {'TIES' if total_abono == monto else 'REVIEW'}")
    print(f"  Closing balance = 0.00: {'TIES' if saldo_final == 0 else 'REVIEW'}")

The first check adds up every principal repayment and confirms it matches the loan amount exactly. The second confirms the closing balance lands on zero. If either of them said REVIEW, something moved in the input data and there is no point reading further down the table.

What you will see on screen

With the sample loan, an amount of 12,000,000.00 over twelve months, the program first prints the terms: the fixed payment and the note that the rate is divided by twelve. Then comes the schedule, shown here with a single numeric format in all three language versions of this article — point for thousands, comma for cents — so the figures can be checked against one another:

Fixed payment (French system): 1,100,159.91
Note: the rate is nominal annual and is divided by 12 to get the monthly rate.

MONTH-BY-MONTH AMORTIZATION SCHEDULE
------------------------------------------------------------------------------------------------
No.  Date        Opening balance         Payment        Interest       Principal Closing balance
------------------------------------------------------------------------------------------------
1    2026-05-01    12,000,000.00    1,100,159.91      180,000.00      920,159.91   11,079,840.09
2    2026-06-01    11,079,840.09    1,100,159.91      166,197.60      933,962.31   10,145,877.78
3    2026-07-01    10,145,877.78    1,100,159.91      152,188.17      947,971.74    9,197,906.04
4    2026-08-01     9,197,906.04    1,100,159.91      137,968.59      962,191.32    8,235,714.72
5    2026-09-01     8,235,714.72    1,100,159.91      123,535.72      976,624.19    7,259,090.53
6    2026-10-01     7,259,090.53    1,100,159.91      108,886.36      991,273.55    6,267,816.98
7    2026-11-01     6,267,816.98    1,100,159.91       94,017.25    1,006,142.66    5,261,674.32
8    2026-12-01     5,261,674.32    1,100,159.91       78,925.11    1,021,234.80    4,240,439.52
9    2027-01-01     4,240,439.52    1,100,159.91       63,606.59    1,036,553.32    3,203,886.20
10   2027-02-01     3,203,886.20    1,100,159.91       48,058.29    1,052,101.62    2,151,784.58
11   2027-03-01     2,151,784.58    1,100,159.91       32,276.77    1,067,883.14    1,083,901.44
12   2027-04-01     1,083,901.44    1,100,159.96       16,258.52    1,083,901.44            0.00
------------------------------------------------------------------------------------------------

Look at the first payment: out of the 1,100,159.91 you hand over, 180,000.00 goes to interest and only 920,159.91 cuts the debt. By the last payment the proportion has flipped: interest is down to 16,258.52 and nearly all of the payment is principal. Then the summary gives you the figures that count:

LOAN SUMMARY
================================================================================================
  Total paid     : 13,201,918.97
  Total interest : 1,201,918.97
  Total principal: 12,000,000.00
  Last instalment: 1,100,159.96

  Note: the last payment differs because it absorbs the rounding cents.

  Sum of principal = amount: TIES
  Closing balance = 0.00: TIES

So a loan of 12,000,000.00 ends up costing you 13,201,918.97, of which 1,201,918.97 is interest. And look at the last instalment: it comes to 1,100,159.96, five cents more than the other eleven. That is not a bug. It is the cent-level adjustment we just described, and it is exactly why banks put the precise value of the final payment in the contract.

Common mistakes and tips

  • If the window closes the moment you double-click the file, nothing broke: the program finished and the console shut itself. Open it from a terminal so you get to read the whole schedule.
  • If you see an error mentioning datos/credito.csv, it is almost always because the archive was opened inside the viewer instead of being unzipped. The program needs the datos folder right next to the program file.
  • In the data file write the numbers the plain way: the amount without thousands separators, the rate without a percent sign. If you type the amount with separators, the program will read it wrongly.
  • Always save the data file as UTF-8. If you edit it and save it in another encoding, the accents in the output break and some columns look shifted.
  • Whenever you change the amount, the rate or the term, check the summary: both checks must say TIES. If they say REVIEW, one of the inputs is not coherent and it needs fixing before you trust the numbers.
  • The schedule does not replace the bank's own statement. Your lender may use a different compounding, insurance, account fees or a grace period; compare line by line before you accept that a difference is real.
  • Keep your version together with its data file. When the bank changes a condition, you rerun the program and compare the two schedules in a single minute.

When this is not enough

This program answers one very specific question: how a fixed payment splits into interest and principal. It works perfectly while there is one loan, the term is fixed and the rate does not move. Once the business carries several loans at once, suppliers financing at thirty, sixty and ninety days, rates reviewed every quarter or extra repayments halfway through, a text file falls short and the sheet stops telling the full story.

That is the point where real software starts to pay for itself. Kardex Tauro is a free program that puts a small company's inventory and finance records in order, and it exists for exactly that moment: when spreadsheets and loose scripts are no longer enough and you need the numbers to live in one place. It does not replace your accountant and it does not decide for you; it leaves the figures tidy so the conversation with the bank starts from a clear point.

⬇ Descargar el código (ZIP)

Download the ZIP, swap the sample data for your own loan and put the result next to the bank's statement. Half an hour of that comparison will teach you more about your loan than any brochure. And if the program earns its keep, keep it handy: when the credit grows, Kardex Tauro is the next step, and the habit of checking the numbers stays exactly the same.

Share
Link copied
Microsoft Store from Microsoft StoreDownload free
Chatea por WhatsApp