# Calculating APR using binary chop

Hello

I was wondering if anyone had code for calcualting APR using binary chop. I have been able to find some code for solving APR using Newton Rhapson and this seems to work ok but for various reasons I have been advised to use the binary chop method and compare my answers to this

http://www.creditunion.ie/files/file_20050316024652OFT%20-%20Credit%20Charges%20and%20APR.pdf

(bisection method page 49) but this is a little too high leve psuedo code for me and could do with knowing what formulae to apply where in this code.
I can find examples online for how to solve this in matlab but i dont have access to matlab. I have access to /net, php and things like that. I can also use a groovy console online

Thanks a lot and happy christmas
###### Who is Participating?

Commented:
A little more generalized solution here.  The execution time goes up sharply with the requirement for increasing precision.  Try setting the \$accuracy value to 7, for example.

``````<?php // RAY_irr.php
error_reporting(E_ALL);

// COMPUTE (IRR) INTERNAL RATE OF RETURN - ITERATIVE METHOD, ANNUAL
// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28324332.html

// SOME TEST DATA
\$cashflow = array
( -1000.0   // INITIAL INVESTMENT
, 400.0     // ANNUAL INTEREST OR DIVIDEND PAYMENTS
, 400.0
, 400.0
)
;

// TEST THE FUNCTION AND SHOW THE WORK PRODUCT
\$irr = irr(\$cashflow);
echo " CASH: ";print_r(\$cashflow);
echo " IRR: \$irr";

// DETERMINE INTERNAL RATE OF RETURN FROM AN ARRAY OF ANNUAL PAYMENTS
function irr(\$cashflow, \$accuracy=4)
{
// DETERMINE IF GROSS CASHFLOW IS POSITIVE
\$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 round(((\$interest-\$iterator) * 100.0),\$accuracy);
} // END FUNCTION irr
``````
0

Chief Technology OfficerCommented:
Hi.

This is similar to a binary search algorithm, which you can find good examples on for .NET.

Remember, if you are dealing with continuous compound interest, then:
{future value} = {present value} * e^({annual interest rate}*{number of years})

Therefore, you can rearrange the formula to solve for different values, such as the present value or interest rate given the other values.

e.g., {present value} = {future value} / e^({annual interest rate}*{number of years})
{annual interest rate} = ln({future value}/{present value}) / {number of years}

Where ln() is the natural logarithm.

Similarly, you can do the same for periodic compound interest:
{future value} = {present value} * (1 + {annual interest rate}/{periods per year})^({periods per year}*{number of years})

Regarding the pseudo code, here is my interpretation.

(1) obtain known values of above formula, including the amount of future values and the specific time period.
(2) initialize minimum and maximum values of i.
(3) repeat binary chop algorithm where you try "i" at the midpoint of min/max.  I read this as you pass "i" to present value function with the values of advances/installments.  If you have the correct APR, the present value of the amount paid out should equal the present value of the amount paid in if I understand correctly.  If installments are higher, you move to upper half of "i"; if lower, the bottom half.

You iterate until the difference between the min/max approaches zero:
Do While ((max - min) < 0.0000001)
...
Loop

Does that help?
0

Commented:
This might help lead you in the right direction.  I'll see if I have any other examples later today.
http://www.laprbass.com/RAY_irr.php

``````<?php // RAY_irr.php
error_reporting(E_ALL);

// COMPUTE (IRR) INTERNAL RATE OF RETURN - ITERATIVE METHOD, ANNUAL

// SOME TEST DATA
\$cashflow = array
( -100.0   // INITIAL INVESTMENT
, 5.0      // ANNUAL INTEREST OR DIVIDEND PAYMENTS
, 5.0
, 5.0
, 5.0
, 5.0
, 110.0    // CASH OUT
)
;

// TEST THE FUNCTION AND SHOW THE WORK PRODUCT
\$irr = irr(\$cashflow);
echo " CASH: ";print_r(\$cashflow);
echo " IRR: \$irr";

// DETERMINE INTERNAL RATE OF RETURN FROM AN ARRAY OF ANNUAL PAYMENTS
function irr(\$cashflow)
{
// DETERMINE IF GROSS CASHFLOW IS POSITIVE
\$cash = round(array_sum(\$cashflow),2);
if (\$cash == 0.0) return 0.0;

if (\$cash >  0.0) \$iterator =  0.0001;
if (\$cash <  0.0) \$iterator = -0.0001;
\$interest = 0.0;
\$npv      = 1.0;
\$years    = count(\$cashflow) - 1;

while ( (round(abs(\$npv),4) > 0.0) )
{
\$interest = round(\$interest + \$iterator,4);
\$year     = 0;
\$npv      = 0.0;

while (\$year <= \$years)
{
\$yearly = \$cashflow[\$year];
// DENOMINATOR IS (1 + r)**t
\$denominator = pow((1+\$interest), \$year);
\$denominator = round(\$denominator,6);
\$npv = \$npv + ( \$yearly / \$denominator );
\$year++;
}
if  ((\$iterator > 0.0) && (\$npv < 0.0) ) break;
if  ((\$iterator < 0.0) && (\$npv > 0.0) ) break;
}
return round(((\$interest-\$iterator) * 100.0),2);
} // END FUNCTION irr
``````
0

Author Commented:
Thank you for your replies. I have been off over christmas but will look at this information today and hopefully close the question
0

Author Commented:
Hello, on the first answer posted by JohnRay, what is the last input option 'cash out'

How would i modify the second answer for something that wasn't an exact number of years e.g. 30 months?

Thanks
0

Chief Technology OfficerCommented:
@Ray: you also may want to chime in on explanation of NPV/IRR.
http://www.experts-exchange.com/Other/Math_Science/Q_28327419.html
0

Author Commented:
If i test run a flat rate loan of 7500 at 6% interest paid back over 1 year I ran it with this input based on 12 repayments of 662.50

\$cashflow = array
( -7500.0   // INITIAL INVESTMENT
, 7950
)
;

Have i ran it right?
0

Commented:
I posted this in the other question, but it has merit here, too.
http://en.wikipedia.org/wiki/Internal_rate_of_return

The period of the calculations is infinitely adjustable, as are the inflows and outflows of cash.  I just did it in years because it was convenient to the test data.
what is the last input option 'cash out'
When analyzing multiple discounted cash flows, your investment is typically treated as a negative value and the returns of interest, dividend yields, etc., are treated as positive values.  In the example, the "cash out" value would represent liquidation of the investment at a future date.  This would occur if a bond matured and the principal was returned or a rental property is sold for cash.
0

Commented:
Have i ran it right?
Sort of.  There is a lot of deep background involved in making these calculations.  The cash flows are not usually as hard-and-fast as you see in these theoretical examples, and interest on loans usually does not compound annually; there are different compounding periods for different financial instruments.  Mortgages, for example, are typically compounded continuously.
0

Author Commented:
Thanks for your replies. The person who wants APR calulcated does want a flat rate of interest and not compound. I should have mentioned that in my post!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.