PHP Mortgage Calculator Canada - php

I just found a mortgage calculator function:
function calculatePayment($price, $down, $term)
{
$loan = $price - $down;
$rate = (2.5/100) / 12;
$month = $term * 12;
$payment = floor(($loan*$rate/(1-pow(1+$rate,(-1*$month))))*100)/100;
return $payment;
}
So if I do:
calculatePayment(200000,0,25)
it return me 897.23$.
The problem is that, if I compare with BMO Bank or duproprio.com calculators, it seem that my function is not exactly working as on the 2 other sites, the result is 895,93$.
Can someone help me figuring out why it doesn't return the good amount?
Thanks alot

Ive converted the Balance calculation portion of http://www.secureapp.com/tools/mortgage.html into a PHP function (Also ive added a down payment variable) and given an usage example:
$principal = 684000; //Mortgage Amount
$interest_rate = 2.89; //Interest Rate %
$down = $principal *0.10; //10% down payment
$years = 25;
$months = 0;
$compound = 2; //compound is always set to 2
$frequency = 12; //Number of months (Monthly (12), Semi-Monthly (24), Bi-Weekly(26) and Weekly(52)
function calcPay($MORTGAGE, $AMORTYEARS, $AMORTMONTHS, $INRATE, $COMPOUND, $FREQ, $DOWN){
$MORTGAGE = $MORTGAGE - $DOWN;
$compound = $COMPOUND/12;
$monTime = ($AMORTYEARS * 12) + (1 * $AMORTMONTHS);
$RATE = ($INRATE*1.0)/100;
$yrRate = $RATE/$COMPOUND;
$rdefine = pow((1.0 + $yrRate),$compound)-1.0;
$PAYMENT = ($MORTGAGE*$rdefine * (pow((1.0 + $rdefine),$monTime))) / ((pow((1.0 + $rdefine),$monTime)) - 1.0);
if($FREQ==12){
return $PAYMENT;}
if($FREQ==26){
return $PAYMENT/2.0;}
if($FREQ==52){
return $PAYMENT/4.0;}
if($FREQ==24){
$compound2 = $COMPOUND/$FREQ;
$monTime2 = ($AMORTYEARS * $FREQ) + ($AMORTMONTHS * 2);
$rdefine2 = pow((1.0 + $yrRate),$compound2)-1.0;
$PAYMENT2 = ($MORTGAGE*$rdefine2 * (pow((1.0 + $rdefine2),$monTime2)))/ ((pow((1.0 + $rdefine2),$monTime2)) - 1.0);
return $PAYMENT2;
}
}
$payment = calcPay($principal, $years, $months, $interest_rate, $compound, $frequency, $down);

Instead of compounding monthly, compound the mortgage every 6 months.
Canadian mortgages are compounded every 6 months not monthly.
With the exception of variable rate mortgages, all mortgages are compounded semi-annually, by law. Therefore, if you are quoted a rate of 6% on a mortgage, the mortgage will actually have an effective annual rate of 6.09%, based on 3% semi-annually. However, you make your interest payments monthly, so your mortgage lender needs to use a monthly rate based on an annual rate that is less than 6%. Why? Because this rate will get compounded monthly. Therefore, we need to find the rate that compounded monthly, results in an effective annual rate of 6.09%. Mathematically, this would be:
(1+rM)12-1 = 0.0609
rM = (1.0609)1/12
rM = 0.493862…%
Source: http://www.yorku.ca/amarshal/mortgage.htm

Your calculation is ok - se this mortgage calculator : http://aprc.eu/index.php?page=APR-loan-calculator
The difference of your result and cited Bank calcultor stems from different assumptions. The formula you use is for monthly payments at the end of the month. If the payments are made at the beginning of the month, then iterests are lower, hence payment may be lower too.

Related

PHP calculation logic issue

Not sure if I'm being stupid here. Probably something obvious but when you've been staring at the same issue for hours on end it starts to drive you crazy.
I'm doing a few calcuations using PHP, all fairly straight forward.
I have a table called sales, say:
total, costs
424.53, 125
853.91, 125
To get the data I need...
gross = total - cost
vat = gross - ( gross / 1.2 )
profit = gross - vat
I need to generate a report, so for each row in the sales database I need to loop over and run the above calculations to get the data I need.
If I add the sum of total and the sum of costs, and then work out the gross, vat and profit above, and round vat and profit to 2 decimal plates the values are as expected.
The problem I'm having is where I'm looping over each row and calculating gross, vat and profit. If I don't round vat and profit on each row, but round the final totals, they match the values where I add sum(total) and sum(costs).
But then in the report I generate, if I don't round vat and profit then they don't show to two decimal places, which I need.
Actual code is below, pretty sure it's more of a logic issue than code.
$sum = 0; // Test variable
foreach( .. as ... )
{
// Assigning $total and $cost
$gross = $total - $cost;
$data['profit'] = $gross;
// If I round this VAT so vat shows to two decimal points, $sum becomes off by some pence.
// If I don't round it but then round $sum after the loop, it matches the echo statement value which is the correct amount
$vat = $this->vat( $gross );
$data['vat'] = $vat;
$profit = $gross - $vat;
$data['net_profit'] = $profit;
$sum += $profit;
$array[] = $data;
}
echo "131547.82<br><br>";
echo $sum;
die;
It's an accuracy problem caused by using floats.
When you do calculations with pure PHP you need to be careful.
You may run into glitches, when comparing two floats.
I would suggest to use some helper function or a currency / money object in order to work with them. It might be better to use a PHP Extension for math stuff, like the PHP Extensions BCMath, which has for instance the function bcadd(). Anyway, here are some helpers, which you might use in your calculation loop.
/**
* turn "string float" into "rounded float with precision 2"
* (string) 123,19124124 = (float) 123.19
*
* #param type $string
*/
function formatNumber($string, $precision = 2)
{
return round((float) str_replace(',', '.', $string), $precision);
}
There is also sprintf: echo sprintf("%.2f", $a);.
These two are based on PHP's NumberFormatter from the Intl Extension.
// 123,19 EUR = 123.19
function parseNumber($string_number)
{
$fmt = numfmt_create('de_DE', \NumberFormatter::DECIMAL);
return numfmt_parse($fmt, $string_number);
}
// 123.19 = 123,19 EUR
function numberFormat($value)
{
$f = \NumberFormatter::create("de_DE", \NumberFormatter::CURRENCY);
return $f->formatCurrency($value, 'EUR');
}
For comparing two floats:
/**
* Do not check, that the numbers are exactly the same,
* but check that their difference is very small!
* A really small rounding error margin (epsilon) is expected.
* It's an equals check within defined precision.
*/
function compareFloats($a, $b)
{
return (abs(($a - $b) / $b) < 0.000001) ? true : false;
}

Showing a finance payment estimaton

I am attempting to add a estimated payment on my website, getting stuck on the interest amount.
Here's what I'd like to do:
(These will vary based on the year of the car, here for demonstration purposes)
$asking = 16495;
$down = 2474;
$doc = 200;
$interest = .05;
$tax = .0635;
$term = 60;
Basically what I'm trying to do is:
$asking + $doc x $tax - $down x $interest / $term
In my finance calculator the payment comes out to $288.37.
On my site the payment is over $7000.
What am I not seeing?
$asking = '$'.number_format($row['asking']);
$down_amount = $row['asking'] * .15;
$rate = .05;
$term = 60;
$loan_amount = ($row['asking'] * 6.35 ) - $down_amount;
$payment_amount = $loan_amount / $term * $rate;
You need parentheses to indicate the order of operation.
I am not 100% sure this is the order you want, but it should be close.
(($asking + $doc) x $tax - $down) x $interest / $term
Remember the computer will do division and multiplication first, and then do addition and subtraction, unless you specify your own order with parentheses.
Also,
$loan_amount = ($row['asking'] * 6.35 ) - $down_amount;
Should probably be
($row['asking'] * 1.0635 )
if that is supposed to be 6.35%.
Four things:
Order of operations and parentheses -- using your formula without any parentheses, you won't get the right answer.
The annual interest rate needs to be divided by the number of payments per year.
You will want to figure out the size of payments to amortize the loan to zero after 60 payments. Auto loans usually use actual/365 accrual.
VERY IMPORTANTLY,
Due to the Truth-in-Lending Act and Regulation Z, you need to be careful to have an adequate disclaimer.

Representing percentage amounts for rate calculations in PHP

I'm working with a few financial formulas that involve float's and rates in percentages, and i'm having a little bit of problems trying to represent these values in my PHP code. Should i use BC Math? Should i divide all my percentages by 100? How would you represent the following formulas in PHP?
e.g: Amount has a tax amount of 8% and an interest rate of 1% a day. Given i want to borrow X amount and pay in 15 days, divided in 3 installments, how much per installment and total payback?
totalTax = amount * 0.08
totalAmount = (amount + totalTax)
interest = totalAmount * 0.01 * 15
perInstallment = totalAmount + totalInterest / 3
The crucial PHP function is number_format(). I'm also casting the type to (float) inside my custom function. As always, test this code. I'm curious if you find any edge cases where this math doesn't sync up with your financial calculations. It passed my tests...
function formatCurrency($input){
$result = number_format((float)$input, 2, '.', ',');
return $result;
}
$amount = 6458.56;
$totalTax = $amount * 0.08;
$totalAmount = $amount + $totalTax;
$interest = $totalAmount * 0.01 * 15;
$perInstallment = ($totalAmount + $interest) / 3;
echo 'Principal = $'.formatCurrency($amount).'<br/>';
echo 'Total Tax = $'.formatCurrency($totalTax).'<br/>';
echo 'Total Amount = $'.formatCurrency($totalAmount).'<br/>';
echo 'Total Interest = $'.formatCurrency($interest).'<br/>';
echo 'Each Installment = $'.formatCurrency($perInstallment).'<br/>';
Attention with your financial operations: 15 days with 1% a day
is not 15% but 16.1 %. Better use pow() function instead of multiply operator.
In PHP (run in command line, for example):
<?
$amount = 1000.0 ;
$tax = 1.08 ; // 8%
$interestPerDay = 1.01 ; // 1%/day
$days = 15 ;
$totalAmount = ($amount * $tax);
$totalAmountWithInterest = $totalAmount * pow($interestPerDay, $days) ;
$perInstallment = $totalAmountWithInterest / 3;
printf("Initial amout: %.2f\n", $amount);
printf("Amount tax inc.: %.2f\n", $totalAmount);
printf("Total amount: %.2f\n", $totalAmountWithInterest);
printf("Total interest: %.2f\n", $totalAmountWithInterest - $amount);
printf("Per installment: %.2f\n", $perInstallment );
Gives:
Initial amout: 1000.00
Amount tax inc.: 1080.00
Total amount: 1253.85
Total interest: 253.85
Per installment: 417.95
According to #larsAnders, it now needs currency conversion.

Point Formula based on a dynamic amount

I'm trying to create a dynamic point system based off of how much money is available in a bank account. For instance, if someone has 20 points and we have 100 dollars in the bank account, I want the formula to return something along the lines of $1.
I don't care too much about the ratio at this point - more about the formula to get there.
So far, I've come up with a handful of different formulas,
$val = (1 / $this->bank) * $amt; //goes the wrong way
$val = ($amt / $this->bank) * 5000; //isn't a good ratio
Assume val is the amount you can get with all the points, bank is how much is in the bank, and $amt is the amount of points the user has.
A gentle nudge in the right direction would be helpful!
Thanks!
$bank * ($points / 2000)
This satisfies your test case, giving 1 for $bank = 100 and $points = 20.
Saying $percentage is the percentage you want between your points and the bank account amount to have 1$ reward, you will have:
$percentage = 20;
$val = $amt * $this->bank / ($percentage * 100);

Add VAT to Price

I have 2 variables: $vatRate and $priceExVat. I want to create another variable named $endPrice which adds the VAT on. I have no clue on how to do this, and am a begginner at PHP so I would like to have a code example ;)
$priceExVat == $_POST['priceExVat'];
$vatRate = $_POST['vatRate'];
rtrim($vatRate ,'%');
$endPrice = ($vatRate * $priceExVat) + $priceExVat;
echo $endPrice;
EDIT: Above is the non-working code which returns a 0
To break it down in full:
<?php
$vatRate = 20; // This must be the percentage VAT rate. e.g.: 20, 17.5.
$priceExVat = 10;
$vatComponent = ($priceExVat / 100) * $vatRate;
$endPrice = $priceExVat + $vatComponent;
echo 'The resultant price is £' . number_format($endPrice, 2);
?>
Incidentally, you may require the VAT portion at a later date, so if you're using this in any non-trivial manner you should really store the base (i.e.: pre-VAT) price and then apply the VAT rate and round accordingly for the purposes of output.
Additionally, you may also want to allow for multiple VAT rates, as not all goods are taxed at 20% in the UK. (Some are exempt, some are taxed at the "reduced" 5% rate, etc.)
$endPrice = ($vatRate * $priceExVat) + $priceExVat;
or
$endPrice = (1+$vatRate * $priceExVat);
Example
$vatRate = 0.07;
$priceExVat = 100.00;
Since getting -3
All the answer is somehow wrong if the value is string 20%
$endPrice = ((int)$vatRate/100)*$priceExVat)+$priceExVat;
This is how it should be done:
function vat($ex_vat,$vat = 20.0)
{
return round($ex_vat+ ((double)$vat*($ex_vat/100)),2);
}
Example:
$withVat = vat(80,20); //£0.80 > £0.96
Assuming $vatRate is specified as percentage.
$endPrice = $priceExVat * $vatRate/100
$vatRate = "20%";
$priceExVat = 100;
$endPrice = (intval($vatRate) / 100) * $priceExVat + $priceExVat;

Categories