I am trying to calculate APR using Newton Raphson in PHP. I have modified the code from this question into php

http://stackoverflow.com/questions/3102476/calculating-annual-percentage-rate-need-some-help-with-inherited-code

However the formula in this question is based on an initial principal, recurring monthly payments and a total number of payments. I need my APR calculation to include an initial start up fee. This would be added to the first monthly payment meaning the monthly payments are no longer all the the same. I take it that this would alter the original formula and hence its derivative. I have no idea what to use now as the initial formula or how to modify this

Here is the php

http://stackoverflow.com/questions/3102476/calculating-annual-percentage-rate-need-some-help-with-inherited-code

However the formula in this question is based on an initial principal, recurring monthly payments and a total number of payments. I need my APR calculation to include an initial start up fee. This would be added to the first monthly payment meaning the monthly payments are no longer all the the same. I take it that this would alter the original formula and hence its derivative. I have no idea what to use now as the initial formula or how to modify this

Here is the php

```
$numPay = 12;
$payment = 875;
$amount = 10000;
$error = pow(10,-5);
$approx = 0.05/12; // let's start with a guess that the APR is 5%
$prev_approx;
function f($x) {
global $numPay;
global $payment;
global $amount;
global $error;
return $amount * $x * (pow(1 + $x,$numPay)/(pow(1 + $x, $numPay) - 1)) - $payment;
}
function f_prime($x) {
global $numPay;
global $payment;
global $amount;
global $error;
return $amount * (pow(1 + $x,$numPay)/(-1 + pow(1 + $x,$numPay)) - $numPay * $x * pow(1 + $x,-1 + 2*$numPay)/pow(-1 + pow(1 + $x,$numPay),2) + $numPay * $x * pow(1 + $x,-1 + $numPay)/(-1 + pow(1 + $x,$numPay)));
}
echo f($approx) . "<br/>";
echo f_prime($approx) . "<br/>";
echo "initial guess $approx" . "<br/>";
for ($k=0;$k<20; $k++) {
$prev_approx = $approx;
$approx = $prev_approx - (f($prev_approx)/f_prime($prev_approx));
$diff = abs($approx-$prev_approx);
echo "new guess $approx diff is $diff <br/>";
if ($diff < $error) break;
}
$apr = round($approx * 12 * 10000 /100, 1); // this way we get APRs like 7.5% or 6.55%
echo "apr is $apr %";
```

Since each of the payments is expressed separately, you can use this for multiple discounted cash flows. Just add your loan origination fee (or whatever) to the initial payment or subtract it from the initial principal, plug in a balloon payment, whatever suits your business practices.

Note line 26.

This interest rate is within 0.00006 of the calculations on my HP12C.

```
<?php // RAY_temp_andieje_irr.php
error_reporting(E_ALL);
// COMPUTE (IRR) INTERNAL RATE OF RETURN - ITERATIVE METHOD, MONTHLY PAYMENTS
// SOME TEST DATA
$cashflow = array
( -10000 // INITIAL INVESTMENT
, 869.884 + 200
, 869.884
, 869.884
, 869.884
, 869.884
, 869.884
, 869.884
, 869.884
, 869.884
, 869.884
, 869.884
, 869.884
)
;
// TEST THE FUNCTION AND SHOW THE WORK PRODUCT
$net = array_sum($cashflow);
$irr = irr($cashflow, 7) / (1/12);
echo " CASH: ";print_r($cashflow);
echo " NET: $net";
echo " IRR: $irr";
// DETERMINE INTERNAL RATE OF RETURN FROM AN ARRAY OF ANNUAL PAYMENTS
function irr(array $cashflow, $accuracy=4)
{
// DETERMINE IF GROSS CASHFLOW IS POSITIVE OR NEGATIVE
$cash = round(array_sum($cashflow),$accuracy);
if ($cash == 0.0) return 0.0;
if ($cash > 0.0) $iterator = pow(10,-$accuracy);
if ($cash < 0.0) $iterator = -pow(10,-$accuracy);
$interest = 0.0;
$npv = 1.0;
$years = count($cashflow) - 1;
while ( (round(abs($npv),$accuracy) > 0.0) )
{
$interest = round($interest + $iterator,$accuracy);
$year = 0;
$npv = 0.0;
while ($year <= $years)
{
$yearly = $cashflow[$year];
// DENOMINATOR IS (1 + r)**t
$denominator = pow((1+$interest), $year);
$denominator = round($denominator,$accuracy);
$npv = $npv + ( $yearly / $denominator );
$year++;
}
if (($iterator > 0.0) && ($npv < 0.0) ) break;
if (($iterator < 0.0) && ($npv > 0.0) ) break;
}
// RETURN WHOLE.FRACTIONAL PERCENT
return round((($interest-$iterator) * 100.0),$accuracy);
}
```

Here is the basic code and f($x) is defined as in your code.

```
$x1=0; //lower approx
$x2=1000; //upper approx
while ( ($x2 - $x1 ) > 0.00001 ) {
$xMid=($x1+ $x2)/2; //new approx
$F1 = f($x1)
$FMid = f($xMid)
if ($FMid*$F1 > 0 ) //check for new interval containing root
$x1 = $xMid;
else
$x2 = $xMid;
}
echo "apr is $xMid%";
```

... doesn't give correct answer. It is off by about 50%I'm not able to find that kind of error. And I can't see enough of the information to get from a 6% interest rate to a 9.5% APR. Where are the other costs coming from? I get 12 payments of 861 and a sum of payments of 10,328.

In general, an APR takes into account multiple discounted cash flows. Among these cash flows are things like "points" (loan origination fees) that are charged by the lender. The notion of APR came up in the United States because lenders began a practice of quoting the interest rate without mentioning the points. This was obviously deceitful and laws were made to protect the borrowers by requiring the lender to state all of the charges in the form of an APR. Lenders can still get around this with pre-payment penalties, etc., but at least the concept is out there and borrowers have a chance to educate themselves.

This one is on us!

(Get your first solution completely free - no credit card required)

UNLOCK SOLUTION
Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.