2010-07-07 24 views
6

Pracuję nad konwersją kalkulatora hipotecznego w PHP, ale niekoniecznie potrzebuję rozwiązania PHP. Szukam logiki potrzebnej do odtworzenia funkcji programu Excel RATE. Znalazłem rozwiązanie, które wykorzystuje bisekcji, a jeśli gorzej jest gorzej, używam tego.Odtwarzanie funkcji Excel RATE za pomocą metody Newtona

Wiem, że ktoś w świecie interwebs ma wiedzę na temat takiej funkcji, więc chciałbym mieć łatwą odpowiedź zamiast tworzyć rozwiązanie od zera.

Odniesienia:

Dzięki

Odpowiedz

8

Wdrożenie funkcji MS Excel przepływności() stosując metodę sieczny (skończoną różnicę przybliżenie metody Newtona) pobrane z 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

Perfectly perfect! Po prostu pamiętaj, aby ludzie wstawili jakieś instrukcje DEFINE dla FINANCIAL_PRECISION i FINANCIAL_MAX_ITERATIONS - lub - zamień je na wartości statyczne odpowiednio 0.0000001 i 20. Znalazłem te wartości na wspomnianej stronie internetowej MS. – Exit

+0

Ta metoda ma problemy z konwergencją, zobacz https://stackoverflow.com/questions/14031208/apache-poi-rate-formula-inconsistency- with-long-periods – sled

+0

@Exit - To może chcesz zapewnić lepsze rozwiązanie dzielenie się twoją wiedzą przyniesie nam korzyści –

0

Próbowałem użyć powyższego kodu, ale wyniki po prostu nie są takie same jak w programie Excel (lub arkuszu kalkulacyjnym Google).

Nie wiem, czy trzeba zaimplementować jeszcze tej funkcji, ale w każdym przypadku, patrzyłem, jak ten algorytm został zbudowany i mimo że nie był w stanie uzyskać dostęp do kodu źródłowego programu Excel (lub arkusz Google) znalazłem że to nie jest proste obliczenie. O tym matematyki, więcej można przeczytać tutaj:

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

funkcja w PHP, może być coś takiego:

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; 
}