Question

I have been playing around making amortization schedules in PHP. My php.ini currently has the precision set to 14. I understand going into this that there will be rounding errors however I am hoping to minimize these errors.

My current way of doing this is only rounding my payment amounts and then leaving all other values at their php default precision value. Calculations below:

$Term_Rate = $Annual_Rate / $Year_Terms;// annual_rate / terms per year

$Payment = round(( $Term_Rate * $Principle ) / ( 1 - (( 1 + $Term_Rate )**( -$Total_Terms ))), 2 );

if($y%4===0)
    $leap = 1;

$interval = $date_2->diff($date_1); 
$days = $interval->days;

$interest = $days * (( $Annual_Rate * $Principle ) / ( 365 + $leap ));

if($Payment>($Principle+$interest))
    $Payment = round( $Principle + $interest, 2);

$balance = ( $Principle + $interest ) - $Payment;

$Principle=$balance;

Then for any values that are displayed back I do my rounding to 2 decimal places. For most of the inputs I have tried the calculator performs well, meaning the loan is paid of on the final payment of the term. However, some input values can cause my loan to be paid off early. Inputs such as:

$Pay_Type = "Monthly";
$Principle = "25000000.00";
$Annual_Rate = "0.2";
$Term_Length = "360"; 
$Term_Unit = "Months"; 
$Start_Date = "2020-01-31"; 

Not all of the inputs will be realistic but Im hoping to be able to handle even some of the more obsurred inputs such as a 90% interest rate on $25000000.

Please inform me if more of my code is required or if any calculations are handled improperly.

Was it helpful?

Solution

This is not a rounding error, but a wrong application of financial formulas.

The formula used for your loan payment is based on financial math designed for a periodic payment with an interest rate for the same period, assuming compound interests.

In your usage of this formula, you base yourself on an annual rate r. You calculate the periodic rate by subdividing it linearly (proportionaly to to nulber of days in the term).So for a monthly term, you are using roughly r/12 as interest rate. And this is mathematically not correct in case of a compound interest formula. It's only an approximation.

The right way of finding the term-rate t if you have n terms per year would be (1+r)**(1/n)-1.

You can read more about annual and subannual rates in the wikipedia article liked above, as well as in this wikipedia article about effective interest rate (caution: the formula in that article is the reverse one, i.e. how to calculate the annual based on the exact monthly one).

Let's give some numeric examples for an annual rate r:

  • for r=4% the monthly rate for compound interest is 0.327% whereas your linera calculation would be 0.333%. The difference is very small, so it's easy to misregard it as rounding issue.
  • for r=10% the correct monthly rate would be 0.797% whereas the linear one would be 0.833%. So the magnitude of the error increases with the rate.
  • for r=90% (hope you have better rates ;-) ) it would be 5,4% per month whereas your code would use 7,5%. So your monthly figures would be based on rate that is 38% higher than it should be: no wonder that you have significantly shortened the number of terms !

Not related: for the daily calculation of interest rates, depending on the party you represent and your country, the denominator could be 360 or 365 or the exact number of days as you did.

Licensed under: CC-BY-SA with attribution
scroll top