Php财务XIRR没有给出奇怪的结果

时间:2014-03-27 16:10:08

标签: php excel financial xirr

我使用了php财务库(http://www.phpclasses.org/package/892-PHP-Financial-functions-with-the-Excel-function-names-.html)中的XIRR函数,但是我得到了这些值的奇怪结果(日期是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);

任何人都能解释一下我做错了什么吗?提前感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

正确的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%

答案 1 :(得分:0)

使用美国mm/dd/yyyy

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

答案 2 :(得分:0)

我已经从PHP Excel Functions编写了一个代码。 我已经计算了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; 
    }

 ?>