Php финансовый XIRR не дает странных результатов

Я использую функцию XIRR из финансовой библиотеки php ( http://www.phpclasses.org/package/892-PHP-Financial-functions-with-the-Excel-function-names-.html), но я получаю странное результаты с этими значениями (даты d / m / y):

(01.01.2014, -400), (01.10.2014, 18)

MS Excel правильно возвращает 0,98, а функция XIRR возвращает -1,5714653207915E+40. Код выглядит следующим образом:

$f->XIRR(array(-400,18), array( 
    mktime(0,0,0,1,1,2014), 
    mktime(0,0,0,10,1,2014),
    ), 0.1);

Может кто-нибудь объяснить мне, что я делаю не так? Заранее благодарю за любую помощь.

2 ответа

Я написал один код из функций PHP Excel. Я рассчитал XIRR и XNPV. Вот пример кода с некоторыми фиктивными данными.

Основным преимуществом является то, что в этом коде нет зависимости ни от какой библиотеки.

<?php

$rate = 0.12;
$values = array(-5000,-3000,-8000,25000,-4000);
$dates = array('01-02-2015','05-05-2016','02-03-2018','03-03-2019','05-03-2019');


/** FINANCIAL_MAX_ITERATIONS */
define('FINANCIAL_MAX_ITERATIONS', 128);

/** FINANCIAL_PRECISION */
define('FINANCIAL_PRECISION', 1.0e-08);

$result = XIRR($values,$dates,0.1);
print_r($result);


 function XIRR($values, $dates, $guess = 0.1) { 
        $x1 = 0.0;
        $x2 = $guess;
        $f1 = XNPV($x1, $values, $dates);  
        $f2 = XNPV($x2, $values, $dates); 
        for ($i = 0; $i < 128; ++$i) {
            if (($f1 * $f2) < 0.0) break;
            if (abs($f1) < abs($f2)) {
                $f1 = XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates);
            } else {
                $f2 = XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates);
            }
        } 

        $f = XNPV($x1, $values, $dates);
        if ($f < 0.0) {
            $rtb = $x1;
            $dx = $x2 - $x1;
        } else {
            $rtb = $x2;
            $dx = $x1 - $x2;
        }

        for ($i = 0;  $i < FINANCIAL_MAX_ITERATIONS; ++$i) {
            $dx *= 0.5;
            $x_mid = $rtb + $dx;
            $f_mid = XNPV($x_mid, $values, $dates);
            if ($f_mid <= 0.0) $rtb = $x_mid;

            if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid;
        } 

    }



      function XNPV($rate, $values, $dates) {

        $valCount = count($values);  
        $xnpv = 0.0;
        for ($i = 0; $i < $valCount; ++$i) 
        { 

            $datediff = strtotime($dates[$i]) - strtotime($dates[0]);
            $datediff =  round($datediff / (60 * 60 * 24));  
            $xnpv += $values[$i] / pow(1 + $rate,$datediff / 365); 
        } 
        return $xnpv; 
    }

 ?>

Используй американский mm/dd/yyyy:

mktime(0,0,0,1,1,2014), 
mktime(0,0,0,1,10,2014)

Правильное значение XIRR составляет -98,417%, как показано ниже.

-400 + 18(1+i)^-(273/365) = 0
18(1+i)^-(273/365) = 400
(1+i)^-(273/365) = 400/18
(1+i)^(273/365) = 18/400
(1+i) = (18/400)^(365/273)
1+i = (0.045)^(1.336996337)
i = (0.045)^(1.336996337) - 1
i = -0.984174769
i = -98.417%
Другие вопросы по тегам