【问题标题】:PHP IRR (Internal rate of return) financial functionPHP IRR(内部收益率)财务函数
【发布时间】:2017-07-21 21:14:38
【问题描述】:

如何在 PHP 中实现 MS Excel 的“IRR()”公式?

我尝试了this page中提到的算法,但结果并不准确,而且真的很慢。

【问题讨论】:

    标签: php financial


    【解决方案1】:

    调查了一段时间,我最终得到了下面复制的函数。

    它基于this question

    function IRR($investment, $flow, $precision = 0.001) {
        $min = 0;
        $max = 1;
        $net_present_value = 1;
        while(abs($net_present_value - $investment) > $precision) {
            $net_present_value = 0;
            $guess = ($min + $max) / 2;
            foreach ($flow as $period => $cashflow) {
                $net_present_value += $cashflow / (1 + $guess) ** ($period + 1);
            }
            if ($net_present_value - $investment > 0) {
                $min = $guess;
            } else {
                $max = $guess;
            }
        }
        return $guess * 100;
    }
    

    【讨论】:

    • 你总是可以看看implementation in PHPExcel
    • 当所有现金流的总和小于投资额时如何处理死循环?
    • PHPExcel 已存档,改为github.com/PHPOffice/PhpSpreadsheet
    • 当现金流等于或大于初始投资时效果很好。但是,当我们的现金流量小于初始投资时,计算结果为无穷大。当所有现金流的总和小于投资金额时如何处理死循环?
    【解决方案2】:

    这是根据托马斯的回答修改的。它通过在开始时检查以确保现金流大于投资来停止无限循环。我还提高了精度,最多运行 20 次。

    private function IRR($investment, $flow, $precision = 0.000001) {
    
        if (array_sum($flow) < $investment):
            return 0;
        endif;
        $maxIterations = 20;
        $i =0;
        if (is_array($flow)):
            $min = 0;
            $max = 1;
            $net_present_value = 1;
            while ((abs($net_present_value - $investment) > $precision)&& ($i < $maxIterations)) {
                $net_present_value = 0;
                $guess = ($min + $max) / 2;
                foreach ($flow as $period => $cashflow) {
                    $net_present_value += $cashflow / (1 + $guess) ** ($period + 1);
                }
                if ($net_present_value - $investment > 0) {
                    $min = $guess;
                } else {
                    $max = $guess;
                }
                $i++;
            }
            return $guess * 100;
        else:
            return 0;
        endif;
    }
    

    【讨论】:

    猜你喜欢
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 2019-10-19
    相关资源
    最近更新 更多