2010-07-07 2 views
6

Я работаю над преобразованием калькулятора ипотеки в PHP, но мне не обязательно нужно решение PHP. Я ищу логику, необходимую для репликации функции Excel RATE. Я нашел решение, которое использует деление пополам, и, если хуже, я использую это.Восстановить функцию Excel RATE с использованием метода Ньютона

Я знаю, что кто-то там, в мире interwebs, знает о такой функции, поэтому мне хотелось бы получить легкий ответ вместо того, чтобы создавать решение с нуля.

Ссылки:

Благодаря

ответ

8

Реализация функции MS Excel СТАВКА(), используя секущий метод (разностного приближение метода Ньютона) взято из PHPExcel:

define('FINANCIAL_MAX_ITERATIONS', 128); 
define('FINANCIAL_PRECISION', 1.0e-08); 


function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) { 

    $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 (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() 
+2

Совершенно отлично! Просто помните, чтобы люди подключали либо некоторые инструкции DEFINE для FINANCIAL_PRECISION, и FINANCIAL_MAX_ITERATIONS - или - заменяли их этими статическими значениями 0.0000001 и 20 соответственно. Я нашел эти значения на веб-сайте MS, упомянутом выше. – Exit

+0

Этот метод имеет проблемы с конвергенцией, см. Https://stackoverflow.com/questions/14031208/apache-poi-rate-formula-inconsistency-with-long-periods – sled

+0

@Exit - Тогда, возможно, вы захотите предоставить лучшее решение , обмен вашими знаниями принесет нам пользу –

0

Я попытался использовать приведенный выше код, но результаты просто не совпадают с Excel (или Google Spreadsheet).

Я не знаю, нужно ли еще реализовать эту функцию, но в любом случае я посмотрел, как был построен этот алгоритм, и хотя я не смог получить доступ к исходному коду excel (или рабочему листу google), я нашел что это не простой расчет. Об этой математике, больше можно прочитать здесь:

https://brownmath.com/bsci/loan.htm#Eq8

функция в PHP, может быть что-то вроде этого:

function rate($nprest, $vlrparc, $vp, $guess = 0.25) { 
    $maxit = 100; 
    $precision = 14; 
    $guess = round($guess,$precision); 
    for ($i=0 ; $i<$maxit ; $i++) { 
     $divdnd = $vlrparc - ($vlrparc * (pow(1 + $guess , -$nprest))) - ($vp * $guess); 
     $divisor = $nprest * $vlrparc * pow(1 + $guess , (-$nprest - 1)) - $vp; 
     $newguess = $guess - ($divdnd/$divisor); 
     $newguess = round($newguess, $precision); 
     if ($newguess == $guess) { 
      return $newguess; 
     } else { 
      $guess = $newguess; 
     } 
    } 
    return null; 
}