用PHP计算利率 [英] Calculating interest rate in PHP
问题描述
在给定初始贷款金额,还款数量和还款金额的情况下,我试图计算贷款的利息.我似乎无法使用基本公式得出足够接近的数字,所以我一直在尝试使用Newton Raphson方法,该方法可以在此处使用:
I'm trying to calculate the interest on a loan given the initial loan amount, the number of repayments and the amount of repayments. I can't seem to get a close enough figure using a basic formula, so I've been trying to use the Newton Raphson method, which can be seen in use here: http://www.efunda.com/formulae/finance/loan_calculator.cfm (this is the exact functionality I am looking to implement)
我尝试过使用PHPExcel中的RATE()函数,但是我的输入没有得到正确的输出,即,利率回到0.1%或类似的水平(而实际上是5.75%)
I've tried using the RATE() function from PHPExcel, however I'm not getting a correct output for my inputs, i.e. the interest rate comes back as 0.1% or similar (when in fact it's more like 5.75%)
这是PHPExcel的相关代码
This is the relevant code for PHPExcel's
/** FINANCIAL_MAX_ITERATIONS */
define('FINANCIAL_MAX_ITERATIONS', 128);
/** FINANCIAL_PRECISION */
define('FINANCIAL_PRECISION', 1.0e-08);
/**
* Convert an array to a single scalar value by extracting the first element
*
* @param mixed $value Array or scalar value
* @return mixed
*/
function flattenSingleValue($value = '') {
while (is_array($value)) {
$value = array_pop($value);
}
return $value;
}
/**
* RATE
*
* Returns the interest rate per period of an annuity.
* RATE is calculated by iteration and can have zero or more solutions.
* If the successive results of RATE do not converge to within 0.0000001 after 20 iterations,
* RATE returns the #NUM! error value.
*
* Excel Function:
* RATE(nper,pmt,pv[,fv[,type[,guess]]])
*
* @access public
* @category Financial Functions
* @param float nper The total number of payment periods in an annuity.
* @param float pmt The payment made each period and cannot change over the life
* of the annuity.
* Typically, pmt includes principal and interest but no other
* fees or taxes.
* @param float pv The present value - the total amount that a series of future
* payments is worth now.
* @param float fv The future value, or a cash balance you want to attain after
* the last payment is made. If fv is omitted, it is assumed
* to be 0 (the future value of a loan, for example, is 0).
* @param integer type A number 0 or 1 and indicates when payments are due:
* 0 or omitted At the end of the period.
* 1 At the beginning of the period.
* @param float guess Your guess for what the rate will be.
* If you omit guess, it is assumed to be 10 percent.
* @return float
**/
function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) {
$nper = (int) flattenSingleValue($nper);
$pmt = flattenSingleValue($pmt);
$pv = flattenSingleValue($pv);
$fv = (is_null($fv)) ? 0.0 : flattenSingleValue($fv);
$type = (is_null($type)) ? 0 : (int) flattenSingleValue($type);
$guess = (is_null($guess)) ? 0.1 : flattenSingleValue($guess);
$rate = $guess;
if (abs($rate) < FINANCIAL_PRECISION) {
$y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv;
} else {
$f = exp($nper * log(1 + $rate));
$y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;
}
$y0 = $pv + $pmt * $nper + $fv;
$y1 = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;
// find root by secant method
$i = $x0 = 0.0;
$x1 = $rate;
while ((abs($y0 - $y1) > FINANCIAL_PRECISION) && ($i < FINANCIAL_MAX_ITERATIONS)) {
$rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0);
$x0 = $x1;
$x1 = $rate;
if (($nper * abs($pmt)) > ($pv - $fv))
$x1 = abs($x1);
if (abs($rate) < FINANCIAL_PRECISION) {
$y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv;
} else {
$f = exp($nper * log(1 + $rate));
$y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;
}
$y0 = $y1;
$y1 = $y;
++$i;
}
return $rate;
} // function RATE()
我对该函数的输入是:
RATE(60, 1100, 50000); // Outputs 0.00420298759161
RATE(60, -1100, 50000); // Outputs 0.00959560344752
RATE(60, 1100, 66000); // Outputs -1.05036370955
其中60是5年的月数,每月1100或-1100是还款额,50,000是总借贷额.
Where 60 is the number of months in 5 years, 1100 or -1100 is the amount repaid each month, and 50,000 is the total borrowed.
我不是数学家,上述功能对我来说意义不大,但我的阅读显示这是计算费率的最佳方法.希望我只是犯了一个愚蠢的错误...
I'm not a mathematician, the above function doesn't make much sense to me, but my reading says this is the best way to calculate the rate. Hopefully I'm just making a silly mistake...
推荐答案
您可以使用二进制搜索"代替牛顿拉夫森方法".
You can use "Binary Search" instead of "Newton Raphson method".
function rate($month, $payment, $amount)
{
// make an initial guess
$error = 0.0000001; $high = 1.00; $low = 0.00;
$rate = (2.0 * ($month * $payment - $amount)) / ($amount * $month);
while(true) {
// check for error margin
$calc = pow(1 + $rate, $month);
$calc = ($rate * $calc) / ($calc - 1.0);
$calc -= $payment / $amount;
if ($calc > $error) {
// guess too high, lower the guess
$high = $rate;
$rate = ($high + $low) / 2;
} elseif ($calc < -$error) {
// guess too low, higher the guess
$low = $rate;
$rate = ($high + $low) / 2;
} else {
// acceptable guess
break;
}
}
return $rate * 12;
}
var_dump(rate(60, 1000, 20000));
// Return 0.56138305664063, which means 56.1383%
二进制搜索"和牛顿拉夫森法"基本上是一种猜测方法.它会做出初步猜测,并随着时间的推移改善其猜测,直到达到可接受的猜测为止. 牛顿拉夫森法"通常比二元搜索"更快,因为它具有更好的改善猜测"策略.
The "Binary Search" and "Newton Raphson method" are basically a guess method. It make an initial guess and improve their guess over time until it meet the acceptable guess. "Newton Raphson method" usually is faster than "binary search" because it has a better "improving guess" strategy.
这个概念很简单:
我们想知道r
这是利率.我们知道N,C和P.我们不知道什么是r
,但让我们猜测介于0.00到1.00之间的任何数字. (在这种情况下,我们假设利率不能超过100%).
We want to know r
which is the interest rate. We know, N, C, and P. We don't know what is r
, but let just guess any number between 0.00 to 1.00. (In this case, we assume that the interest rate cannot be over 100%).
- 第1步:随机猜测
- 第2步:将费率插入公式,
- 第3步:检查猜测值是否太低,更高的猜测值,转到第2步
- 步骤4:检查猜测是否过高,降低猜测,转到步骤2
- 第5步:我们得到了可以接受的费率.
- 步骤6:
r
是月费率.乘以12即可得出年利率.
- Step 1: Make a random guess
- Step 2: Plug the rate into formula,
- Step 3: Check if the guess is too low, higher the guess, goto Step 2
- Step 4: Check if the guess is too high, lower the guess, goto Step 2
- Step 5: We got acceptable rate.
- Step 6:
r
is monthly rate. Multiple by 12 to get annually rate.
这篇关于用PHP计算利率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!