diff --git a/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Cumulative.php b/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Cumulative.php index 1e05a446..4f6ed170 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Cumulative.php +++ b/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Cumulative.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Financial\CashFlow\Constant\Perio use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Financial; +use PhpOffice\PhpSpreadsheet\Calculation\Financial\Securities\Constants; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Cumulative @@ -30,7 +31,7 @@ class Cumulative * * @return float|string */ - public static function interest($rate, $periods, $presentValue, $start, $end, $type = 0) + public static function interest($rate, $periods, $presentValue, $start, $end, $type = Constants::END_OF_PERIOD) { $rate = Functions::flattenSingleValue($rate); $periods = Functions::flattenSingleValue($periods); @@ -51,7 +52,7 @@ class Cumulative } // Validate parameters - if ($type !== 0 && $type !== 1) { + if ($type !== Constants::END_OF_PERIOD && $type !== Constants::BEGINNING_OF_PERIOD) { return Functions::NAN(); } if ($start < 1 || $start > $end) { @@ -61,7 +62,7 @@ class Cumulative // Calculate $interest = 0; for ($per = $start; $per <= $end; ++$per) { - $ipmt = Financial::IPMT($rate, $per, $periods, $presentValue, 0, $type); + $ipmt = Interest::payment($rate, $per, $periods, $presentValue, 0, $type); if (is_string($ipmt)) { return $ipmt; } diff --git a/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php b/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php index 1bb63a2a..3f579ce2 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php +++ b/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php @@ -23,12 +23,12 @@ class Interest * Excel Function: * IPMT(rate,per,nper,pv[,fv][,type]) * - * @param float $interestRate Interest rate per period - * @param int $period Period for which we want to find the interest - * @param int $numberOfPeriods Number of periods - * @param float $presentValue Present Value - * @param float $futureValue Future Value - * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @param mixed $interestRate Interest rate per period + * @param mixed $period Period for which we want to find the interest + * @param mixed $numberOfPeriods Number of periods + * @param mixed $presentValue Present Value + * @param mixed $futureValue Future Value + * @param mixed $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period * * @return float|string */ @@ -81,13 +81,10 @@ class Interest * Excel Function: * =ISPMT(interest_rate, period, number_payments, pv) * - * interest_rate is the interest rate for the investment - * - * period is the period to calculate the interest rate. It must be betweeen 1 and number_payments. - * - * number_payments is the number of payments for the annuity - * - * pv is the loan amount or present value of the payments + * @param mixed $interestRate is the interest rate for the investment + * @param mixed $period is the period to calculate the interest rate. It must be betweeen 1 and number_payments. + * @param mixed $numberOfPeriods is the number of payments for the annuity + * @param mixed $principleRemaining is the loan amount or present value of the payments */ public static function schedulePayment($interestRate, $period, $numberOfPeriods, $principleRemaining) { @@ -189,17 +186,17 @@ class Interest return $close ? $rate : Functions::NAN(); } - private static function rateNextGuess($rate, $nper, $pmt, $pv, $fv, $type) + private static function rateNextGuess($rate, $numberOfPeriods, $payment, $presentValue, $futureValue, $type) { if ($rate == 0) { return Functions::NAN(); } - $tt1 = ($rate + 1) ** $nper; - $tt2 = ($rate + 1) ** ($nper - 1); - $numerator = $fv + $tt1 * $pv + $pmt * ($tt1 - 1) * ($rate * $type + 1) / $rate; - $denominator = $nper * $tt2 * $pv - $pmt * ($tt1 - 1) * ($rate * $type + 1) / ($rate * $rate) - + $nper * $pmt * $tt2 * ($rate * $type + 1) / $rate - + $pmt * ($tt1 - 1) * $type / $rate; + $tt1 = ($rate + 1) ** $numberOfPeriods; + $tt2 = ($rate + 1) ** ($numberOfPeriods - 1); + $numerator = $futureValue + $tt1 * $presentValue + $payment * ($tt1 - 1) * ($rate * $type + 1) / $rate; + $denominator = $numberOfPeriods * $tt2 * $presentValue - $payment * ($tt1 - 1) + * ($rate * $type + 1) / ($rate * $rate) + $numberOfPeriods + * $payment * $tt2 * ($rate * $type + 1) / $rate + $payment * ($tt1 - 1) * $type / $rate; if ($denominator == 0) { return Functions::NAN(); } diff --git a/src/PhpSpreadsheet/Calculation/Financial/Coupons.php b/src/PhpSpreadsheet/Calculation/Financial/Coupons.php index c24b31be..cdd54015 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/Coupons.php +++ b/src/PhpSpreadsheet/Calculation/Financial/Coupons.php @@ -291,7 +291,11 @@ class Coupons return $e->getMessage(); } - $yearsBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac($settlement, $maturity, 0); + $yearsBetweenSettlementAndMaturity = DateTimeExcel\YearFrac::funcYearFrac( + $settlement, + $maturity, + Helpers::DAYS_PER_YEAR_NASD + ); return (int) ceil($yearsBetweenSettlementAndMaturity * $frequency); } diff --git a/src/PhpSpreadsheet/Calculation/Financial/Securities/Constants.php b/src/PhpSpreadsheet/Calculation/Financial/Securities/Constants.php index ba9d2389..f7bc2731 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/Securities/Constants.php +++ b/src/PhpSpreadsheet/Calculation/Financial/Securities/Constants.php @@ -7,4 +7,7 @@ class Constants public const FREQUENCY_ANNUAL = 1; public const FREQUENCY_SEMI_ANNUAL = 2; public const FREQUENCY_QUARTERLY = 4; + + public const END_OF_PERIOD = 0; + public const BEGINNING_OF_PERIOD = 1; }