/** * Returns the internal rate of return of a cash flow series, considering both financial and reinvestment rates * Excel equivalent: MIRR * * @param array Cash flow series * @param float Interest rate on the money used in the cash flow * @param float Interest rate received when reinvested * @return float * @static * @access public */ function modifiedInternalRateOfReturn($values, $finance_rate, $reinvest_rate) { if (!is_array($values)) { return PEAR::raiseError('The cash flow series most be an array'); } if (min($values) * max($values) >= 0) { return PEAR::raiseError('Cash flow must contain at least one positive value and one negative value'); } $positive_flows = $negative_flows = array(); foreach ($values as $value) { if ($value >= 0) { $positive_flows[] = $value; $negative_flows[] = 0; } else { $positive_flows[] = 0; $negative_flows[] = $value; } } $nper = count($values); return pow(-Math_Finance::netPresentValue($reinvest_rate, $positive_flows) * pow(1 + $reinvest_rate, $nper) / Math_Finance::netPresentValue($finance_rate, $negative_flows) / (1 + $finance_rate), 1 / ($nper - 1)) - 1; }
function testnetPresentValue() { // various random calculations $this->assertTrue(abs(1188.443412 - Math_Finance::netPresentValue(0.1, array(-10000, 3000, 4200, 6800))) < FINANCE_PRECISION); // cash flow series must be an array $this->assertType('object', Math_Finance::netPresentValue(0.1, -1000, 3000, 4200, 6800)); }