PHP IRR(内部收益率)财务功能

问题描述 投票:0回答:4

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

我尝试了本页中提到的算法,但结果不准确,而且速度非常慢。

php financial
4个回答
5
投票

经过一段时间的研究,我最终得到了下面复制的函数。

它是基于这个问题

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

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

0
投票
 function IRR($values, $guess = 0.1) {
    $maxIterations = 100;
    $tolerance = 0.00001;

    $count = count($values);

    $positive = false;
    $negative = false;
    for ($i = 0; $i < $count; $i++) {
        if ($values[$i] > 0) {
            $positive = true;
       } else {
            $negative = true;
       }
    }

    if (!$positive || !$negative) {
        return null;
    }

    $guess = ($guess == 0) ? 0.1 : $guess;

    for ($i = 0; $i < $maxIterations; $i++) {
        $npv = 0;
        $dnpv = 0;

        for ($j = 0; $j < $count; $j++) {
            $npv += $values[$j] / pow(1 + $guess, $j);
            $dnpv -= $j * $values[$j] / pow(1 + $guess, $j + 1);
        }

        $newGuess = $guess - $npv / $dnpv;

        if (abs($newGuess - $guess) < $tolerance) {
            return $newGuess;
        }

        $guess = $newGuess;
    }
    enter code here
    return null;
}

0
投票

对于需要使用

IRR
但没有实现的人,我们可以从这个链接中的
PhpSpreadsheet
使用它

https://github.com/PHPOffice/PhpSpreadsheet/blob/master/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/Periodic.php

这是我使用此函数的 Laravel 代码

use PhpOffice\PhpSpreadsheet\Calculation\Financial\CashFlow\Variable\Periodic;

$data = array(-1000000, -1000000, -1000000, 4000000);

$irr_result = Periodic::rate($data);
© www.soinside.com 2019 - 2024. All rights reserved.