Viewing file: Finance.php (31.69 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/** * Math_Finance: Class of financial functions * * Assorted financial functions for interest rates, bonds, amortizations and time value of money calculations (annuities) * Same interface as Excel financial functions. * * PHP versions 4 and 5 * * LICENSE: This source file is subject to version 3.0 of the PHP license * that is available through the world-wide-web at the following URI: * http://www.php.net/license/3_0.txt. If you did not receive a copy of * the PHP License and are unable to obtain it through the web, please * send a note to license@php.net so we can mail you a copy immediately. * * @category Math * @package Math_Finance * @author Original Author <alejandro.pedraza@dataenlace.com> * @copyright 2005 Alejandro Pedraza * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id: Finance.php 274632 2009-01-26 14:29:28Z clockwerx $ * @link http://pear.php.net/Math/Finance * @since File available since Release 1.2.0 */
// to be able to throw PEAR errors require_once 'PEAR.php';
// precision of calculations define('FINANCE_PRECISION', 1E-6);
// payment types define('FINANCE_PAY_END', 0); define('FINANCE_PAY_BEGIN', 1);
// types of daycount basis define('FINANCE_COUNT_NASD', 0); define('FINANCE_COUNT_ACTUAL_ACTUAL', 1); define('FINANCE_COUNT_ACTUAL_360', 2); define('FINANCE_COUNT_ACTUAL_365', 3); define('FINANCE_COUNT_EUROPEAN', 4);
/** * Math_Finance: Main class * * @category Math * @package Math_Finance * @author Original Author <alejandro.pedraza@dataenlace.com> * @copyright 2005 Alejandro Pedraza * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version Release: @package_version@ * @link http://pear.php.net/Math/Finance * @since Class available since Release 1.2.0 */ class Math_Finance { /******************************************************************* ** Interest Rates Conversion Functions ***** *******************************************************************/
/** * Returns the effective interest rate given the nominal rate and the number of compounding payments per year * Excel equivalent: EFFECT * * @param float Nominal interest rate * @param int Number of compounding payments per year * @return float * @static * @access public */ function effectiveRate($nominal_rate, $npery) { $npery = (int)$npery; if ($npery < 0) { return PEAR::raiseError('Number of compounding payments per year is not positive'); }
$effect = pow((1 + $nominal_rate / $npery), $npery) - 1; return $effect; }
/** * Returns the nominal interest rate given the effective rate and the number of compounding payments per year * Excel equivalent: NOMINAL * * @param float Effective interest rate * @param int Number of compounding payments per year * @return float * @static * @access public */ function nominalRate($effect_rate, $npery) { $npery = (int)$npery; if ($npery < 0) { return PEAR::raiseError('Number of compounding payments per year is not positive'); }
$nominal = $npery * (pow($effect_rate + 1, 1/$npery) - 1); return $nominal; }
/******************************************************************* ** TVM (annuities) Functions ***** *******************************************************************/
/** * Returns the Present Value of a cash flow with constant payments and interest rate (annuities) * Excel equivalent: PV * * TVM functions solve for a term in the following formula: * pv(1+r)^n + pmt(1+r.type)((1+r)^n - 1)/r) +fv = 0 * * * @param float Interest rate per period * @param int Number of periods * @param float Periodic payment (annuity) * @param float Future Value * @param int Payment type: FINANCE_PAY_END (default): at the end of each period FINANCE_PAY_BEGIN: at the beginning of each period * @return float * @static * @access public */ function presentValue($rate, $nper, $pmt, $fv = 0, $type = 0) { if ($nper < 0) { return PEAR::raiseError('Number of periods must be positive'); } if ($type != FINANCE_PAY_END && $type != FINANCE_PAY_BEGIN) { return PEAR::raiseError('Payment type must be FINANCE_PAY_END or FINANCE_PAY_BEGIN'); }
if ($rate) { $pv = (-$pmt * (1 + $rate * $type) * ((pow(1 + $rate, $nper) - 1) / $rate) - $fv) / pow(1 + $rate, $nper); } else { $pv = -$fv - $pmt * $nper; } return $pv; }
/** * Returns the Future Value of a cash flow with constant payments and interest rate (annuities) * Excel equivalent: FV * * @param float Interest rate per period * @param int Number of periods * @param float Periodic payment (annuity) * @param float Present Value * @param int Payment type: FINANCE_PAY_END (default): at the end of each period FINANCE_PAY_BEGIN: at the beginning of each period * @return float * @static * @access public */ function futureValue($rate, $nper, $pmt, $pv = 0, $type = 0) { if ($nper < 0) { return PEAR::raiseError('Number of periods must be positive'); } if ($type != FINANCE_PAY_END && $type != FINANCE_PAY_BEGIN) { return PEAR::raiseError('Payment type must be FINANCE_PAY_END or FINANCE_PAY_BEGIN'); }
if ($rate) { $fv = -$pv * pow(1 + $rate, $nper) - $pmt * (1 + $rate * $type) * (pow(1 + $rate, $nper) - 1) / $rate; } else { $fv = -$pv - $pmt * $nper; } return $fv; }
/** * Returns the constant payment (annuity) for a cash flow with a constant interest rate * Excel equivalent: PMT * * @param float Interest rate per period * @param int Number of periods * @param float Present Value * @param float Future Value * @param int Payment type: FINANCE_PAY_END (default): at the end of each period FINANCE_PAY_BEGIN: at the beginning of each period * @return float * @static * @access public */ function payment($rate, $nper, $pv, $fv = 0, $type = 0) { if ($nper < 0) { return PEAR::raiseError('Number of periods must be positive'); } if ($type != FINANCE_PAY_END && $type != FINANCE_PAY_BEGIN) { return PEAR::raiseError('Payment type must be FINANCE_PAY_END or FINANCE_PAY_BEGIN'); }
if ($rate) { $pmt = (-$fv - $pv * pow(1 + $rate, $nper)) / (1 + $rate * $type) / ((pow(1 + $rate, $nper) - 1) / $rate); } else { $pmt = (-$pv - $fv) / $nper; } return $pmt; }
/** * Returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate * Excel equivalent: NPER * * @param float Interest rate per period * @param float Periodic payment (annuity) * @param float Present Value * @param float Future Value * @param int Payment type: FINANCE_PAY_END (default): at the end of each period FINANCE_PAY_BEGIN: at the beginning of each period * @return float * @static * @access public */ function periods($rate, $pmt, $pv, $fv = 0, $type = 0) { if ($type != FINANCE_PAY_END && $type != FINANCE_PAY_BEGIN) { return PEAR::raiseError('Payment type must be FINANCE_PAY_END or FINANCE_PAY_BEGIN'); }
if ($rate) { if ($pmt == 0 && $pv == 0) { return PEAR::raiseError('Payment and Present Value can\'t be both zero when the rate is not zero'); } $nper = log(($pmt * (1 + $rate * $type) / $rate - $fv) / ($pv + $pmt * (1 + $rate * $type) / $rate)) / log(1 + $rate); } else { if ($pmt == 0) { return PEAR::raiseError('Rate and Payment can\'t be both zero'); } $nper = (-$pv -$fv) / $pmt; } return $nper; }
/** * Returns the periodic interest rate for a cash flow with constant periodic payments (annuities) * Excel equivalent: RATE * * @param int Number of periods * @param float Periodic payment (annuity) * @param float Present Value * @param float Future Value * @param int Payment type: FINANCE_PAY_END (default): at the end of each period FINANCE_PAY_BEGIN: at the beginning of each period * @param float guess for the interest rate * @return float * @static * @access public */ function rate($nper, $pmt, $pv, $fv = 0, $type = 0, $guess = 0.1) { // To solve the equation require_once 'Math/Numerical/RootFinding/NewtonRaphson.php'; // To preserve some variables in the Newton-Raphson callback functions require_once 'Math/Finance_FunctionParameters.php';
if ($type != FINANCE_PAY_END && $type != FINANCE_PAY_BEGIN) { return PEAR::raiseError('Payment type must be FINANCE_PAY_END or FINANCE_PAY_BEGIN'); }
// Utilization of a Singleton class to preserve given values of other variables in the callback functions $parameters = array( 'nper' => $nper, 'pmt' => $pmt, 'pv' => $pv, 'fv' => $fv, 'type' => $type, ); $parameters_class =& Math_Finance_FunctionParameters::getInstance($parameters, True);
$newtonRaphson = new Math_Numerical_RootFinding_Newtonraphson(array('err_tolerance' => FINANCE_PRECISION)); return $newtonRaphson->compute(array('Math_Finance', '_tvm'), array('Math_Finance', '_dtvm'), $guess); }
/** * Callback function only used by Newton-Raphson algorithm. Returns value of function to be solved. * * Uses a previously instanced Singleton class to retrieve given values of other variables in the function * * @param float Interest rate * @return float * @static * @access private */ function _tvm($rate) { require_once 'Math/Finance_FunctionParameters.php';
$parameters_class =& Math_Finance_FunctionParameters::getInstance(); $nper = $parameters_class->parameters['nper']; $pmt = $parameters_class->parameters['pmt']; $pv = $parameters_class->parameters['pv']; $fv = $parameters_class->parameters['fv']; $type = $parameters_class->parameters['type'];
return $pv * pow(1 + $rate, $nper) + $pmt * (1 + $rate * $type) * (pow(1 + $rate, $nper) - 1) / $rate + $fv; }
/** * Callback function only used by Newton-Raphson algorithm. Returns value of derivative of function to be solved. * * Uses a previously instanced Singleton class to retrieve given values of other variables in the function * * @return float * @static * @access private */ function _dtvm($rate) { require_once 'Math/Finance_FunctionParameters.php';
$parameters_class =& Math_Finance_FunctionParameters::getInstance(); $nper = $parameters_class->parameters['nper']; $pmt = $parameters_class->parameters['pmt']; $pv = $parameters_class->parameters['pv']; $type = $parameters_class->parameters['type'];
return $nper * $pv * pow(1 + $rate, $nper - 1) + $pmt * ($type * (pow(1 + $rate, $nper) - 1) / $rate + (1 + $rate * $type) * ($nper * $rate * pow(1 + $rate, $nper - 1) - pow(1 + $rate, $nper) + 1) / pow($rate,2)); }
/** * Returns the interest payment for a given period for a cash flow with constant periodic payments (annuities) * and interest rate. * Excel equivalent: IMPT * * @param float Interest rate per period * @param int Period for which the interest payment will be calculated * @param int Number of periods * @param float Present Value * @param float Future Value * @param int Payment type: FINANCE_PAY_END (default): at the end of each period FINANCE_PAY_BEGIN: at the beginning of each period * @return float * @static * @access public */ function interestPayment($rate, $per, $nper, $pv, $fv = 0, $type = 0) { if ($type != FINANCE_PAY_END && $type != FINANCE_PAY_BEGIN) { return PEAR::raiseError('Payment type must be FINANCE_PAY_END or FINANCE_PAY_BEGIN'); }
$interestAndPrincipal = Math_Finance::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); return $interestAndPrincipal[0]; }
/** * Returns the principal payment for a given period for a cash flow with constant periodic payments (annuities) * and interest rate * Excel equivalent: PPMT * * @param float Interest rate per period * @param int Period for which the principal payment will be calculated * @param int Number of periods * @param float Present Value * @param float Future Value * @param int Payment type: FINANCE_PAY_END (default): at the end of each period FINANCE_PAY_BEGIN: at the beginning of each period * @return float * @static * @access public */ function principalPayment($rate, $per, $nper, $pv, $fv = 0, $type = 0) { if ($type != FINANCE_PAY_END && $type != FINANCE_PAY_BEGIN) { return PEAR::raiseError('Payment type must be FINANCE_PAY_END or FINANCE_PAY_BEGIN'); }
$interestAndPrincipal = Math_Finance::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); return $interestAndPrincipal[1]; }
/** * Returns the interest and principal payment for a given period for a cash flow with constant * periodic payments (annuities) and interest rate * * @param float Interest rate per period * @param int Number of periods * @param float Present Value * @param float Future Value * @param int Payment type: FINANCE_PAY_END (default): at the end of each period FINANCE_PAY_BEGIN: at the beginning of each period * @return array * @static * @access private */ function _interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type) { $pmt = Math_Finance::payment($rate, $nper, $pv, $fv, $type); //echo "pmt: $pmt\n\n"; $capital = $pv; for ($i = 1; $i<= $per; $i++) { // in first period of advanced payments no interests are paid $interest = ($type && $i == 1)? 0 : -$capital * $rate; $principal = $pmt - $interest; $capital += $principal; //echo "$i\t$capital\t$interest\t$principal\n"; } return array($interest, $principal); }
/******************************************************************* ** Cash Flow Functions ***** *******************************************************************/
/** * Returns the Net Present Value of a cash flow series given a discount rate * Excel equivalent: NPV * * @param float Discount interest rate * @param array Cash flow series * @return float * @static * @access public */
function netPresentValue($rate, $values) { if (!is_array($values)) { return PEAR::raiseError('The cash flow series most be an array'); } return MATH_Finance::_npv($rate, $values); }
/** * Returns the internal rate of return of a cash flow series * Excel equivalent: IRR * * @param array Cash flow series * @param float guess for the interest rate * @return float * @static * @access public */ function internalRateOfReturn($values, $guess = 0.1) { // To solve the equation require_once 'Math/Numerical/RootFinding/NewtonRaphson.php'; // To preserve some variables in the Newton-Raphson callback functions require_once 'Math/Finance_FunctionParameters.php';
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'); }
$parameters_class =& Math_Finance_FunctionParameters::getInstance(array('values' => $values), True); $newtonRaphson = new Math_Numerical_RootFinding_Newtonraphson(array('err_tolerance' => FINANCE_PRECISION)); return $newtonRaphson->compute(array('Math_Finance', '_npv'), array('Math_Finance', '_dnpv'), $guess); }
/** * Function used by NPV() and as a callback by Newton-Raphson algorithm. * Returns value of Net Present Value of a cash flow series. * * Uses a previously instanced Singleton class to retrieve given values of other variables in the function * * @param float Discount interest rate * @param array Cash flow series * @return float * @static * @access private */ function _npv($rate, $values = array()) { require_once 'Math/Finance_FunctionParameters.php';
if (!$values) { // called from IRR $parameters_class =& Math_Finance_FunctionParameters::getInstance(); $values = $parameters_class->parameters['values']; }
$npv = 0; $nper = count($values); for ($i = 1; $i <= $nper; $i++) { $npv += $values[$i-1]/ pow(1 + $rate, $i); } return $npv; }
/** * Callback function used by by Newton-Raphson algorithm to calculate IRR. * Returns value of derivative function to be solved. * * Uses a previously instanced Singleton class to retrieve given values of other variables in the function * * @param float Discount interest rate * @param array Cash flow series * @return float * @static * @access private */ function _dnpv($rate, $values = array()) { require_once 'Math/Finance_FunctionParameters.php';
if (!$values) { // called from IRR $parameters_class =& Math_Finance_FunctionParameters::getInstance(); $values = $parameters_class->parameters['values']; }
$dnpv = 0; $nper = count($values); for ($i = 1; $i <= $nper; $i++) { $dnpv += $values[$i-1] * (-$i) * pow(1 + $rate, $i - 1) / pow(1 + $rate, 2 * $i); } return $dnpv; }
/** * 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; }
/******************************************************************* ** Bonds Functions ***** *******************************************************************/
/** * Returns the difference of days between two dates based on a daycount basis * * @param int First date (UNIX timestamp) * @param int Second date (UNIX timestamp) * @param int Type of day count basis: FINANCE_COUNT_NASD(default): US(NASD) 30/360 FINANCE_COUNT_ACTUAL_ACTUAL: Actual/actual FINANCE_COUNT_ACTUAL_360: Actual/360 FINANCE_COUNT_ACTUAL_365: Actual/365 FINANCE_COUNT_EUROPEAN: European 30/360 * @return int * @static * @access public */ function daysDifference($date1, $date2, $basis) { $y1 = date('Y', $date1); $m1 = date('n', $date1); $d1 = date('j', $date1); $y2 = date('Y', $date2); $m2 = date('n', $date2); $d2 = date('j', $date2);
switch ($basis) { case FINANCE_COUNT_NASD: if ($d2 == 31 && ($d1 == 30 || $d1 == 31)) { $d2 = 30; } if ($d1 == 31) { $d1 = 30; } return ($y2 - $y1) * 360 + ($m2 - $m1) * 30 + $d2 - $d1; case FINANCE_COUNT_ACTUAL_ACTUAL: case FINANCE_COUNT_ACTUAL_360: case FINANCE_COUNT_ACTUAL_365: return ($date2 - $date1) / 86400; case FINANCE_COUNT_EUROPEAN: // European 30/360 return ($y2 - $y1) * 360 + ($m2 - $m1) * 30 + $d2 - $d1; } }
/** * Returns the number of days in the year based on a daycount basis * * @param int Year * @param int Type of day count basis: FINANCE_COUNT_NASD(default): US(NASD) 30/360 FINANCE_COUNT_ACTUAL_ACTUAL: Actual/actual FINANCE_COUNT_ACTUAL_360: Actual/360 FINANCE_COUNT_ACTUAL_365: Actual/365 FINANCE_COUNT_EUROPEAN: European 30/360 * @return int * @static * @access public */ function daysPerYear($year, $basis) { switch ($basis) { case FINANCE_COUNT_NASD: return 360; case FINANCE_COUNT_ACTUAL_ACTUAL: return checkdate(2, 29, $year)? 366 : 365; case FINANCE_COUNT_ACTUAL_360: return 360; case FINANCE_COUNT_ACTUAL_365: return 365; case FINANCE_COUNT_EUROPEAN: return 360; } }
/** * Returns the yield for a treasury bill * Excel equivalent: TBILLYIELD * * @param int Settlement date (UNIX timestamp) * @param int Maturity date (UNIX timestamp) * @param float TBill price per $100 face value * @return float * @static * @access public */ function TBillYield($settlement, $maturity, $pr) { if ($settlement >= $maturity) { return PEAR::raiseError('Maturity must happen before settlement!'); }
$dsm = ($maturity - $settlement) / 86400; // transform to days
if ($dsm > 360) { return PEAR::raiseError("maturity can't be more than one year after settlement"); }
return (100 - $pr) * 360 / $pr / $dsm; }
/** * Returns the price per $100 face value for a Treasury bill * Excel equivalent: TBILLPRICE * * @param int Settlement date (UNIX timestamp) * @param int Maturity date (UNIX timestamp) * @param float T-Bill discount rate * @return float * @static * @access public */ function TBillPrice($settlement, $maturity, $discount) { if ($settlement >= $maturity) { return PEAR::raiseError('Maturity must happen before settlement!'); }
$dsm = ($maturity - $settlement) / 86400; // transform to days
if ($dsm > 360) { return PEAR::raiseError("maturity can't be more than one year after settlement"); }
return 100 * (1 - $discount * $dsm / 360); }
/** * Returns the bond-equivalent yield for a Treasury bill * Excel equivalent: TBILLEQ * * @param int Settlement date (UNIX timestamp) * @param int Maturity date (UNIX timestamp) * @param float T-Bill discount rate * @return float * @static * @access public */ function TBillEquivalentYield($settlement, $maturity, $discount) { if ($settlement >= $maturity) { return PEAR::raiseError('Maturity must happen before settlement!'); }
$dsm = Math_Finance::daysDifference($settlement, $maturity, FINANCE_COUNT_ACTUAL_365);
if ($dsm <= 182) { // for one half year or less, the bond-equivalent-yield is equivalent to an actual/365 interest rate return 365 * $discount / (360 - $discount * $dsm); } elseif ($dsm == 366 && ((date('m', $settlement) <= 2 && checkdate(2, 29, date('Y', $settlement))) || (date('m', $settlement) > 2 && checkdate(2, 29, date('Y', $maturity))))) { return 2 * (sqrt(1 - $discount * 366 / ($discount * 366 - 360)) - 1); } elseif ($dsm > 365) { return PEAR::raiseError("maturity can't be more than one year after settlement"); } else { // thanks to Zhang Qingpo (zhangqingpo@yahoo.com.cn) for solving this riddle :) return (-$dsm + sqrt(pow($dsm, 2) - (2 * $dsm - 365) * $discount * $dsm * 365 / ($discount * $dsm - 360))) / ($dsm - 365 / 2); } }
/** * Returns the discount rate for a bond * Excel equivalent: DISC * * @param int Settlement date (UNIX timestamp) * @param int Maturity date (UNIX timestamp) * @param float The bond's price per $100 face value * @param float The bond's redemption value per $100 face value * @param int Type of day count basis: FINANCE_COUNT_NASD(default): US(NASD) 30/360 FINANCE_COUNT_ACTUAL_ACTUAL: Actual/actual FINANCE_COUNT_ACTUAL_360: Actual/360 FINANCE_COUNT_ACTUAL_365: Actual/365 FINANCE_COUNT_EUROPEAN: European 30/360 * @return float * @static * @access public */ function discountRate($settlement, $maturity, $pr, $redemption, $basis = 0) { $days_per_year = Math_Finance::daysPerYear(date('Y', $settlement), $basis); $dsm = Math_Finance::daysDifference($settlement, $maturity, $basis);
return ($redemption - $pr) * $days_per_year / $redemption / $dsm; }
/** * Returns the price per $100 face value of a discounted bond * Excel equivalent: PRICEDISC * * @param int Settlement date (UNIX timestamp) * @param int Maturity date (UNIX timestamp) * @param float The bond's discount rate * @param float The bond's redemption value per $100 face value * @param int Type of day count basis: FINANCE_COUNT_NASD(default): US(NASD) 30/360 FINANCE_COUNT_ACTUAL_ACTUAL: Actual/actual FINANCE_COUNT_ACTUAL_360: Actual/360 FINANCE_COUNT_ACTUAL_365: Actual/365 FINANCE_COUNT_EUROPEAN: European 30/360 * @return float * @static * @access public */ function priceDiscount($settlement, $maturity, $discount, $redemption, $basis = 0) { $days_per_year = Math_Finance::daysPerYear(date('Y', $settlement), $basis); $dsm = Math_Finance::daysDifference($settlement, $maturity, $basis);
return $redemption - $discount * $redemption * $dsm / $days_per_year; }
/******************************************************************* ** Depreciation Functions ***** *******************************************************************/
/** * Returns the depreciation of an asset using the fixed-declining balance method * Excel equivalent: DB * * @param float The initial cost of the asset * @param float Salvage value of the asset * @param int Number of depreciation periods (same unit as $life) * @param int Number of months in the first year, defaults to 12 * @return float * @static * @access public */ function depreciationFixedDeclining($cost, $salvage, $life, $period, $month = 12) { $cost = (float) $cost; $salvage = (float) $salvage; $life = (int) $life; $period = (int) $period; $month = (int) $month; if ($cost < 0 || $life < 0) { return PEAR::raiseError('cost and life must be absolute positive numbers'); } if ($period < 1) { return PEAR::raiseError('period must be greater or equal than one'); }
$rate = 1 - pow(($salvage / $cost), (1 / $life)); $rate = round($rate, 3);
$acc_depreciation = 0; for ($i = 1; $i <= $period; $i++) { if ($i == 1) { $depreciation_period = $cost * $rate * $month / 12; } elseif ($i == ($life + 1)) { $depreciation_period = ($cost - $acc_depreciation) * $rate * (12 - $month) / 12; } else { $depreciation_period = ($cost - $acc_depreciation) * $rate; } $acc_depreciation += $depreciation_period; }
return $depreciation_period; }
/** * Returns the straight-line depreciation of an asset for each period * Excel equivalent: SLN * * @param float The initial cost of the asset * @param float Salvage value of the asset * @param int Number of depreciation periods * @return float * @static * @access public */ function depreciationStraightLine($cost, $salvage, $life) { $life = (int) $life; if ($cost < 0 || $life < 0) { return PEAR::raiseError('cost and life must be absolute positive numbers'); }
return (($cost - $salvage) / $life); }
/** * Returns the depreciation for an asset in a given period using the sum-of-years' digits method * Excel equivalent: SYD * * @param float The initial cost of the asset * @param float Salvage value of the asset * @param int Number of depreciation periods * @param int Period (must be in the same unit as $life) * @return float * @static * @access public */ function depreciationSYD($cost, $salvage, $life, $per) { return (($cost - $salvage) * ($life - $per + 1) * 2 / ($life) / ($life +1)); } }
?>
|