You are here

public static function PHPExcel_Calculation_Financial::XIRR in Loft Data Grids 7.2

Same name and namespace in other branches
  1. 6.2 vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Financial.php \PHPExcel_Calculation_Financial::XIRR()

File

vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Financial.php, line 2106

Class

PHPExcel_Calculation_Financial
PHPExcel_Calculation_Financial

Code

public static function XIRR($values, $dates, $guess = 0.1) {
  if (!is_array($values) && !is_array($dates)) {
    return PHPExcel_Calculation_Functions::VALUE();
  }
  $values = PHPExcel_Calculation_Functions::flattenArray($values);
  $dates = PHPExcel_Calculation_Functions::flattenArray($dates);
  $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess);
  if (count($values) != count($dates)) {
    return PHPExcel_Calculation_Functions::NaN();
  }

  // create an initial range, with a root somewhere between 0 and guess
  $x1 = 0.0;
  $x2 = $guess;
  $f1 = self::XNPV($x1, $values, $dates);
  $f2 = self::XNPV($x2, $values, $dates);
  for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) {
    if ($f1 * $f2 < 0.0) {
      break;
    }
    if (abs($f1) < abs($f2)) {
      $f1 = self::XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates);
    }
    else {
      $f2 = self::XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates);
    }
  }
  if ($f1 * $f2 > 0.0) {
    return PHPExcel_Calculation_Functions::VALUE();
  }
  $f = self::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 = self::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;
    }
  }
  return PHPExcel_Calculation_Functions::VALUE();
}