PHPExcel_Calculation
[ class tree: PHPExcel_Calculation ] [ index: PHPExcel_Calculation ] [ all elements ]

Source for file Financial.php

Documentation is available at Financial.php

  1. <?php
  2. /**
  3.  * PHPExcel
  4.  *
  5.  * Copyright (c) 2006 - 2011 PHPExcel
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  *
  21.  * @category    PHPExcel
  22.  * @package        PHPExcel_Calculation
  23.  * @copyright    Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  24.  * @license        http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  25.  * @version        1.7.6, 2011-02-27
  26.  */
  27.  
  28.  
  29. /** PHPExcel root directory */
  30. if (!defined('PHPEXCEL_ROOT')) {
  31.     /**
  32.      * @ignore
  33.      */
  34.     define('PHPEXCEL_ROOT'dirname(__FILE__'/../../');
  35.     require(PHPEXCEL_ROOT 'PHPExcel/Autoloader.php');
  36. }
  37.  
  38.  
  39. /** FINANCIAL_MAX_ITERATIONS */
  40. define('FINANCIAL_MAX_ITERATIONS'128);
  41.  
  42. /** FINANCIAL_PRECISION */
  43. define('FINANCIAL_PRECISION'1.0e-08);
  44.  
  45.  
  46. /**
  47.  * PHPExcel_Calculation_Financial
  48.  *
  49.  * @category    PHPExcel
  50.  * @package        PHPExcel_Calculation
  51.  * @copyright    Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  52.  */
  53.  
  54.     private static function _lastDayOfMonth($testDate{
  55.         $date clone $testDate;
  56.         $date->modify('+1 day');
  57.         return ($date->format('d'== 1);
  58.     }    //    function _lastDayOfMonth()
  59.  
  60.  
  61.     private static function _firstDayOfMonth($testDate{
  62.         $date clone $testDate;
  63.         return ($date->format('d'== 1);
  64.     }    //    function _lastDayOfMonth()
  65.  
  66.  
  67.     private static function _coupFirstPeriodDate($settlement$maturity$frequency$next{
  68.         $months 12 $frequency;
  69.  
  70.         $result PHPExcel_Shared_Date::ExcelToPHPObject($maturity);
  71.         $eom self::_lastDayOfMonth($result);
  72.  
  73.         while ($settlement PHPExcel_Shared_Date::PHPToExcel($result)) {
  74.             $result->modify('-'.$months.' months');
  75.         }
  76.         if ($next{
  77.             $result->modify('+'.$months.' months');
  78.         }
  79.  
  80.         if ($eom{
  81.             $result->modify('-1 day');
  82.         }
  83.  
  84.         return PHPExcel_Shared_Date::PHPToExcel($result);
  85.     }    //    function _coupFirstPeriodDate()
  86.  
  87.  
  88.     private static function _validFrequency($frequency{
  89.         if (($frequency == 1|| ($frequency == 2|| ($frequency == 4)) {
  90.             return true;
  91.         }
  92.         if ((PHPExcel_Calculation_Functions::getCompatibilityMode(== PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC&&
  93.             (($frequency == 6|| ($frequency == 12))) {
  94.             return true;
  95.         }
  96.         return false;
  97.     }    //    function _validFrequency()
  98.  
  99.  
  100.     private static function _daysPerYear($year,$basis{
  101.         switch ($basis{
  102.             case :
  103.             case :
  104.             case :
  105.                 $daysPerYear 360;
  106.                 break;
  107.             case :
  108.                 $daysPerYear 365;
  109.                 break;
  110.             case :
  111.                 if (PHPExcel_Calculation_DateTime::_isLeapYear($year)) {
  112.                     $daysPerYear 366;
  113.                 else {
  114.                     $daysPerYear 365;
  115.                 }
  116.                 break;
  117.             default    :
  118.                 return PHPExcel_Calculation_Functions::NaN();
  119.         }
  120.         return $daysPerYear;
  121.     }    //    function _daysPerYear()
  122.  
  123.  
  124.     private static function _interestAndPrincipal($rate=0$per=0$nper=0$pv=0$fv=0$type=0{
  125.         $pmt self::PMT($rate$nper$pv$fv$type);
  126.         $capital $pv;
  127.         for ($i 1$i<= $per++$i{
  128.             $interest ($type && $i == 1: -$capital $rate;
  129.             $principal $pmt $interest;
  130.             $capital += $principal;
  131.         }
  132.         return array($interest$principal);
  133.     }    //    function _interestAndPrincipal()
  134.  
  135.  
  136.     /**
  137.      *    ACCRINT
  138.      *
  139.      *    Returns the discount rate for a security.
  140.      *
  141.      *    @param    mixed    issue        The security's issue date.
  142.      *    @param    mixed    firstinter    The security's first interest date.
  143.      *    @param    mixed    settlement    The security's settlement date.
  144.      *    @param    float    rate        The security's annual coupon rate.
  145.      *    @param    float    par            The security's par value.
  146.      *    @param    int        basis        The type of day count to use.
  147.      *                                         0 or omitted    US (NASD) 30/360
  148.      *                                         1                Actual/actual
  149.      *                                         2                Actual/360
  150.      *                                         3                Actual/365
  151.      *                                         4                European 30/360
  152.      *    @return    float 
  153.      */
  154.     public static function ACCRINT($issue$firstinter$settlement$rate$par=1000$frequency=1$basis=0{
  155.         $issue        PHPExcel_Calculation_Functions::flattenSingleValue($issue);
  156.         $firstinter    PHPExcel_Calculation_Functions::flattenSingleValue($firstinter);
  157.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  158.         $rate        = (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  159.         $par        (is_null($par))        1000 :    (float) PHPExcel_Calculation_Functions::flattenSingleValue($par);
  160.         $frequency    (is_null($frequency))    1    :         (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);
  161.         $basis        (is_null($basis))        0    :        (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  162.  
  163.         //    Validate
  164.         if ((is_numeric($rate)) && (is_numeric($par))) {
  165.             if (($rate <= 0|| ($par <= 0)) {
  166.                 return PHPExcel_Calculation_Functions::NaN();
  167.             }
  168.             $daysBetweenIssueAndSettlement PHPExcel_Calculation_DateTime::YEARFRAC($issue$settlement$basis);
  169.             if (!is_numeric($daysBetweenIssueAndSettlement)) {
  170.                 //    return date error
  171.                 return $daysBetweenIssueAndSettlement;
  172.             }
  173.  
  174.             return $par $rate $daysBetweenIssueAndSettlement;
  175.         }
  176.         return PHPExcel_Calculation_Functions::VALUE();
  177.     }    //    function ACCRINT()
  178.  
  179.  
  180.     /**
  181.      *    ACCRINTM
  182.      *
  183.      *    Returns the discount rate for a security.
  184.      *
  185.      *    @param    mixed    issue        The security's issue date.
  186.      *    @param    mixed    settlement    The security's settlement date.
  187.      *    @param    float    rate        The security's annual coupon rate.
  188.      *    @param    float    par            The security's par value.
  189.      *    @param    int        basis        The type of day count to use.
  190.      *                                         0 or omitted    US (NASD) 30/360
  191.      *                                         1                Actual/actual
  192.      *                                         2                Actual/360
  193.      *                                         3                Actual/365
  194.      *                                         4                European 30/360
  195.      *    @return    float 
  196.      */
  197.     public static function ACCRINTM($issue$settlement$rate$par=1000$basis=0{
  198.         $issue        PHPExcel_Calculation_Functions::flattenSingleValue($issue);
  199.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  200.         $rate        = (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  201.         $par        (is_null($par))    1000 :    (float) PHPExcel_Calculation_Functions::flattenSingleValue($par);
  202.         $basis        (is_null($basis))    :        (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  203.  
  204.         //    Validate
  205.         if ((is_numeric($rate)) && (is_numeric($par))) {
  206.             if (($rate <= 0|| ($par <= 0)) {
  207.                 return PHPExcel_Calculation_Functions::NaN();
  208.             }
  209.             $daysBetweenIssueAndSettlement PHPExcel_Calculation_DateTime::YEARFRAC($issue$settlement$basis);
  210.             if (!is_numeric($daysBetweenIssueAndSettlement)) {
  211.                 //    return date error
  212.                 return $daysBetweenIssueAndSettlement;
  213.             }
  214.             return $par $rate $daysBetweenIssueAndSettlement;
  215.         }
  216.         return PHPExcel_Calculation_Functions::VALUE();
  217.     }    //    function ACCRINTM()
  218.  
  219.  
  220.     public static function AMORDEGRC($cost$purchased$firstPeriod$salvage$period$rate$basis=0{
  221.         $cost            PHPExcel_Calculation_Functions::flattenSingleValue($cost);
  222.         $purchased        PHPExcel_Calculation_Functions::flattenSingleValue($purchased);
  223.         $firstPeriod    PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod);
  224.         $salvage        PHPExcel_Calculation_Functions::flattenSingleValue($salvage);
  225.         $period            floor(PHPExcel_Calculation_Functions::flattenSingleValue($period));
  226.         $rate            PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  227.         $basis            (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  228.  
  229.         $fUsePer 1.0 $rate;
  230.  
  231.         if ($fUsePer 3.0{
  232.             $amortiseCoeff 1.0;
  233.         elseif ($fUsePer 5.0{
  234.             $amortiseCoeff 1.5;
  235.         elseif ($fUsePer <= 6.0{
  236.             $amortiseCoeff 2.0;
  237.         else {
  238.             $amortiseCoeff 2.5;
  239.         }
  240.  
  241.         $rate *= $amortiseCoeff;
  242.         $fNRate round(PHPExcel_Calculation_DateTime::YEARFRAC($purchased$firstPeriod$basis$rate $cost,0);
  243.         $cost -= $fNRate;
  244.         $fRest $cost $salvage;
  245.  
  246.         for ($n 0$n $period++$n{
  247.             $fNRate round($rate $cost,0);
  248.             $fRest -= $fNRate;
  249.  
  250.             if ($fRest 0.0{
  251.                 switch ($period $n{
  252.                     case 0    :
  253.                     case 1    return round($cost 0.5,0);
  254.                               break;
  255.                     default    return 0.0;
  256.                               break;
  257.                 }
  258.             }
  259.             $cost -= $fNRate;
  260.         }
  261.         return $fNRate;
  262.     }    //    function AMORDEGRC()
  263.  
  264.  
  265.     public static function AMORLINC($cost$purchased$firstPeriod$salvage$period$rate$basis=0{
  266.         $cost            PHPExcel_Calculation_Functions::flattenSingleValue($cost);
  267.         $purchased        PHPExcel_Calculation_Functions::flattenSingleValue($purchased);
  268.         $firstPeriod    PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod);
  269.         $salvage        PHPExcel_Calculation_Functions::flattenSingleValue($salvage);
  270.         $period            PHPExcel_Calculation_Functions::flattenSingleValue($period);
  271.         $rate            PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  272.         $basis            (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  273.  
  274.         $fOneRate $cost $rate;
  275.         $fCostDelta $cost $salvage;
  276.         //    Note, quirky variation for leap years on the YEARFRAC for this function
  277.         $purchasedYear PHPExcel_Calculation_DateTime::YEAR($purchased);
  278.         $yearFrac PHPExcel_Calculation_DateTime::YEARFRAC($purchased$firstPeriod$basis);
  279.  
  280.         if (($basis == 1&& ($yearFrac 1&& (PHPExcel_Calculation_DateTime::_isLeapYear($purchasedYear))) {
  281.             $yearFrac *= 365 366;
  282.         }
  283.  
  284.         $f0Rate $yearFrac $rate $cost;
  285.         $nNumOfFullPeriods intval(($cost $salvage $f0Rate$fOneRate);
  286.  
  287.         if ($period == 0{
  288.             return $f0Rate;
  289.         elseif ($period <= $nNumOfFullPeriods{
  290.             return $fOneRate;
  291.         elseif ($period == ($nNumOfFullPeriods 1)) {
  292.             return ($fCostDelta $fOneRate $nNumOfFullPeriods $f0Rate);
  293.         else {
  294.             return 0.0;
  295.         }
  296.     }    //    function AMORLINC()
  297.  
  298.  
  299.     public static function COUPDAYBS($settlement$maturity$frequency$basis=0{
  300.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  301.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  302.         $frequency    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);
  303.         $basis        (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  304.  
  305.         if (is_string($settlement PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {
  306.             return PHPExcel_Calculation_Functions::VALUE();
  307.         }
  308.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  309.             return PHPExcel_Calculation_Functions::VALUE();
  310.         }
  311.  
  312.         if (($settlement $maturity||
  313.             (!self::_validFrequency($frequency)) ||
  314.             (($basis 0|| ($basis 4))) {
  315.             return PHPExcel_Calculation_Functions::NaN();
  316.         }
  317.  
  318.         $daysPerYear self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);
  319.         $prev self::_coupFirstPeriodDate($settlement$maturity$frequencyFalse);
  320.  
  321.         return PHPExcel_Calculation_DateTime::YEARFRAC($prev$settlement$basis$daysPerYear;
  322.     }    //    function COUPDAYBS()
  323.  
  324.  
  325.     public static function COUPDAYS($settlement$maturity$frequency$basis=0{
  326.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  327.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  328.         $frequency    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);
  329.         $basis        (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  330.  
  331.         if (is_string($settlement PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {
  332.             return PHPExcel_Calculation_Functions::VALUE();
  333.         }
  334.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  335.             return PHPExcel_Calculation_Functions::VALUE();
  336.         }
  337.  
  338.         if (($settlement $maturity||
  339.             (!self::_validFrequency($frequency)) ||
  340.             (($basis 0|| ($basis 4))) {
  341.             return PHPExcel_Calculation_Functions::NaN();
  342.         }
  343.  
  344.         switch ($basis{
  345.             case 3// Actual/365
  346.                     return 365 $frequency;
  347.             case 1// Actual/actual
  348.                     if ($frequency == 1{
  349.                         $daysPerYear self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($maturity),$basis);
  350.                         return ($daysPerYear $frequency);
  351.                     else {
  352.                         $prev self::_coupFirstPeriodDate($settlement$maturity$frequencyFalse);
  353.                         $next self::_coupFirstPeriodDate($settlement$maturity$frequencyTrue);
  354.                         return ($next $prev);
  355.                     }
  356.             default// US (NASD) 30/360, Actual/360 or European 30/360
  357.                     return 360 $frequency;
  358.         }
  359.         return PHPExcel_Calculation_Functions::VALUE();
  360.     }    //    function COUPDAYS()
  361.  
  362.  
  363.     public static function COUPDAYSNC($settlement$maturity$frequency$basis=0{
  364.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  365.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  366.         $frequency    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);
  367.         $basis        (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  368.  
  369.         if (is_string($settlement PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {
  370.             return PHPExcel_Calculation_Functions::VALUE();
  371.         }
  372.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  373.             return PHPExcel_Calculation_Functions::VALUE();
  374.         }
  375.  
  376.         if (($settlement $maturity||
  377.             (!self::_validFrequency($frequency)) ||
  378.             (($basis 0|| ($basis 4))) {
  379.             return PHPExcel_Calculation_Functions::NaN();
  380.         }
  381.  
  382.         $daysPerYear self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);
  383.         $next self::_coupFirstPeriodDate($settlement$maturity$frequencyTrue);
  384.  
  385.         return PHPExcel_Calculation_DateTime::YEARFRAC($settlement$next$basis$daysPerYear;
  386.     }    //    function COUPDAYSNC()
  387.  
  388.  
  389.     public static function COUPNCD($settlement$maturity$frequency$basis=0{
  390.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  391.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  392.         $frequency    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);
  393.         $basis        (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  394.  
  395.         if (is_string($settlement PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {
  396.             return PHPExcel_Calculation_Functions::VALUE();
  397.         }
  398.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  399.             return PHPExcel_Calculation_Functions::VALUE();
  400.         }
  401.  
  402.         if (($settlement $maturity||
  403.             (!self::_validFrequency($frequency)) ||
  404.             (($basis 0|| ($basis 4))) {
  405.             return PHPExcel_Calculation_Functions::NaN();
  406.         }
  407.  
  408.         return self::_coupFirstPeriodDate($settlement$maturity$frequencyTrue);
  409.     }    //    function COUPNCD()
  410.  
  411.  
  412.     public static function COUPNUM($settlement$maturity$frequency$basis=0{
  413.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  414.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  415.         $frequency    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);
  416.         $basis        (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  417.  
  418.         if (is_string($settlement PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {
  419.             return PHPExcel_Calculation_Functions::VALUE();
  420.         }
  421.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  422.             return PHPExcel_Calculation_Functions::VALUE();
  423.         }
  424.  
  425.         if (($settlement $maturity||
  426.             (!self::_validFrequency($frequency)) ||
  427.             (($basis 0|| ($basis 4))) {
  428.             return PHPExcel_Calculation_Functions::NaN();
  429.         }
  430.  
  431.         $settlement self::_coupFirstPeriodDate($settlement$maturity$frequencyTrue);
  432.         $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity$basis365;
  433.  
  434.         switch ($frequency{
  435.             case 1// annual payments
  436.                     return ceil($daysBetweenSettlementAndMaturity 360);
  437.             case 2// half-yearly
  438.                     return ceil($daysBetweenSettlementAndMaturity 180);
  439.             case 4// quarterly
  440.                     return ceil($daysBetweenSettlementAndMaturity 90);
  441.             case 6// bimonthly
  442.                     return ceil($daysBetweenSettlementAndMaturity 60);
  443.             case 12// monthly
  444.                     return ceil($daysBetweenSettlementAndMaturity 30);
  445.         }
  446.         return PHPExcel_Calculation_Functions::VALUE();
  447.     }    //    function COUPNUM()
  448.  
  449.  
  450.     public static function COUPPCD($settlement$maturity$frequency$basis=0{
  451.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  452.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  453.         $frequency    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);
  454.         $basis        (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  455.  
  456.         if (is_string($settlement PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {
  457.             return PHPExcel_Calculation_Functions::VALUE();
  458.         }
  459.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  460.             return PHPExcel_Calculation_Functions::VALUE();
  461.         }
  462.  
  463.         if (($settlement $maturity||
  464.             (!self::_validFrequency($frequency)) ||
  465.             (($basis 0|| ($basis 4))) {
  466.             return PHPExcel_Calculation_Functions::NaN();
  467.         }
  468.  
  469.         return self::_coupFirstPeriodDate($settlement$maturity$frequencyFalse);
  470.     }    //    function COUPPCD()
  471.  
  472.  
  473.     /**
  474.      *    CUMIPMT
  475.      *
  476.      *    Returns the cumulative interest paid on a loan between start_period and end_period.
  477.      *
  478.      *    @param    float    $rate    Interest rate per period
  479.      *    @param    int        $nper    Number of periods
  480.      *    @param    float    $pv        Present Value
  481.      *    @param    int        start    The first period in the calculation.
  482.      *                                 Payment periods are numbered beginning with 1.
  483.      *    @param    int        end        The last period in the calculation.
  484.      *    @param    int        $type    Payment type: 0 = at the end of each period, 1 = at the beginning of each period
  485.      *    @return    float 
  486.      */
  487.     public static function CUMIPMT($rate$nper$pv$start$end$type 0{
  488.         $rate    PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  489.         $nper    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);
  490.         $pv        PHPExcel_Calculation_Functions::flattenSingleValue($pv);
  491.         $start    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start);
  492.         $end    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end);
  493.         $type    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);
  494.  
  495.         // Validate parameters
  496.         if ($type != && $type != 1{
  497.             return PHPExcel_Calculation_Functions::NaN();
  498.         }
  499.         if ($start || $start $end{
  500.             return PHPExcel_Calculation_Functions::VALUE();
  501.         }
  502.  
  503.         // Calculate
  504.         $interest 0;
  505.         for ($per $start$per <= $end++$per{
  506.             $interest += self::IPMT($rate$per$nper$pv0$type);
  507.         }
  508.  
  509.         return $interest;
  510.     }    //    function CUMIPMT()
  511.  
  512.  
  513.     /**
  514.      *    CUMPRINC
  515.      *
  516.      *    Returns the cumulative principal paid on a loan between start_period and end_period.
  517.      *
  518.      *    @param    float    $rate    Interest rate per period
  519.      *    @param    int        $nper    Number of periods
  520.      *    @param    float    $pv        Present Value
  521.      *    @param    int        start    The first period in the calculation.
  522.      *                                 Payment periods are numbered beginning with 1.
  523.      *    @param    int        end        The last period in the calculation.
  524.      *    @param    int        $type    Payment type: 0 = at the end of each period, 1 = at the beginning of each period
  525.      *    @return    float 
  526.      */
  527.     public static function CUMPRINC($rate$nper$pv$start$end$type 0{
  528.         $rate    PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  529.         $nper    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);
  530.         $pv        PHPExcel_Calculation_Functions::flattenSingleValue($pv);
  531.         $start    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start);
  532.         $end    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end);
  533.         $type    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);
  534.  
  535.         // Validate parameters
  536.         if ($type != && $type != 1{
  537.             return PHPExcel_Calculation_Functions::NaN();
  538.         }
  539.         if ($start || $start $end{
  540.             return PHPExcel_Calculation_Functions::VALUE();
  541.         }
  542.  
  543.         // Calculate
  544.         $principal 0;
  545.         for ($per $start$per <= $end++$per{
  546.             $principal += self::PPMT($rate$per$nper$pv0$type);
  547.         }
  548.  
  549.         return $principal;
  550.     }    //    function CUMPRINC()
  551.  
  552.  
  553.     /**
  554.      *    DB
  555.      *
  556.      *    Returns the depreciation of an asset for a specified period using the fixed-declining balance method.
  557.      *    This form of depreciation is used if you want to get a higher depreciation value at the beginning of the depreciation
  558.      *        (as opposed to linear depreciation). The depreciation value is reduced with every depreciation period by the
  559.      *        depreciation already deducted from the initial cost.
  560.      *
  561.      *    @param    float    cost        Initial cost of the asset.
  562.      *    @param    float    salvage        Value at the end of the depreciation. (Sometimes called the salvage value of the asset)
  563.      *    @param    int        life        Number of periods over which the asset is depreciated. (Sometimes called the useful life of the asset)
  564.      *    @param    int        period        The period for which you want to calculate the depreciation. Period must use the same units as life.
  565.      *    @param    float    month        Number of months in the first year. If month is omitted, it defaults to 12.
  566.      *    @return    float 
  567.      */
  568.     public static function DB($cost$salvage$life$period$month=12{
  569.         $cost        = (float) PHPExcel_Calculation_Functions::flattenSingleValue($cost);
  570.         $salvage    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($salvage);
  571.         $life        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($life);
  572.         $period        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($period);
  573.         $month        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($month);
  574.  
  575.         //    Validate
  576.         if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($month))) {
  577.             if ($cost == 0{
  578.                 return 0.0;
  579.             elseif (($cost 0|| (($salvage $cost0|| ($life <= 0|| ($period 1|| ($month 1)) {
  580.                 return PHPExcel_Calculation_Functions::NaN();
  581.             }
  582.             //    Set Fixed Depreciation Rate
  583.             $fixedDepreciationRate pow(($salvage $cost)($life));
  584.             $fixedDepreciationRate round($fixedDepreciationRate3);
  585.  
  586.             //    Loop through each period calculating the depreciation
  587.             $previousDepreciation 0;
  588.             for ($per 1$per <= $period++$per{
  589.                 if ($per == 1{
  590.                     $depreciation $cost $fixedDepreciationRate $month 12;
  591.                 elseif ($per == ($life 1)) {
  592.                     $depreciation ($cost $previousDepreciation$fixedDepreciationRate (12 $month12;
  593.                 else {
  594.                     $depreciation ($cost $previousDepreciation$fixedDepreciationRate;
  595.                 }
  596.                 $previousDepreciation += $depreciation;
  597.             }
  598.             if (PHPExcel_Calculation_Functions::getCompatibilityMode(== PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC{
  599.                 $depreciation round($depreciation,2);
  600.             }
  601.             return $depreciation;
  602.         }
  603.         return PHPExcel_Calculation_Functions::VALUE();
  604.     }    //    function DB()
  605.  
  606.  
  607.     /**
  608.      *    DDB
  609.      *
  610.      *    Returns the depreciation of an asset for a specified period using the double-declining balance method or some other method you specify.
  611.      *
  612.      *    @param    float    cost        Initial cost of the asset.
  613.      *    @param    float    salvage        Value at the end of the depreciation. (Sometimes called the salvage value of the asset)
  614.      *    @param    int        life        Number of periods over which the asset is depreciated. (Sometimes called the useful life of the asset)
  615.      *    @param    int        period        The period for which you want to calculate the depreciation. Period must use the same units as life.
  616.      *    @param    float    factor        The rate at which the balance declines.
  617.      *                                 If factor is omitted, it is assumed to be 2 (the double-declining balance method).
  618.      *    @return    float 
  619.      */
  620.     public static function DDB($cost$salvage$life$period$factor=2.0{
  621.         $cost        = (float) PHPExcel_Calculation_Functions::flattenSingleValue($cost);
  622.         $salvage    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($salvage);
  623.         $life        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($life);
  624.         $period        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($period);
  625.         $factor        = (float) PHPExcel_Calculation_Functions::flattenSingleValue($factor);
  626.  
  627.         //    Validate
  628.         if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($factor))) {
  629.             if (($cost <= 0|| (($salvage $cost0|| ($life <= 0|| ($period 1|| ($factor <= 0.0|| ($period $life)) {
  630.                 return PHPExcel_Calculation_Functions::NaN();
  631.             }
  632.             //    Set Fixed Depreciation Rate
  633.             $fixedDepreciationRate pow(($salvage $cost)($life));
  634.             $fixedDepreciationRate round($fixedDepreciationRate3);
  635.  
  636.             //    Loop through each period calculating the depreciation
  637.             $previousDepreciation 0;
  638.             for ($per 1$per <= $period++$per{
  639.                 $depreciation min( ($cost $previousDepreciation($factor $life)($cost $salvage $previousDepreciation) );
  640.                 $previousDepreciation += $depreciation;
  641.             }
  642.             if (PHPExcel_Calculation_Functions::getCompatibilityMode(== PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC{
  643.                 $depreciation round($depreciation,2);
  644.             }
  645.             return $depreciation;
  646.         }
  647.         return PHPExcel_Calculation_Functions::VALUE();
  648.     }    //    function DDB()
  649.  
  650.  
  651.     /**
  652.      *    DISC
  653.      *
  654.      *    Returns the discount rate for a security.
  655.      *
  656.      *    @param    mixed    settlement    The security's settlement date.
  657.      *                                 The security settlement date is the date after the issue date when the security is traded to the buyer.
  658.      *    @param    mixed    maturity    The security's maturity date.
  659.      *                                 The maturity date is the date when the security expires.
  660.      *    @param    int        price        The security's price per $100 face value.
  661.      *    @param    int        redemption    the security's redemption value per $100 face value.
  662.      *    @param    int        basis        The type of day count to use.
  663.      *                                         0 or omitted    US (NASD) 30/360
  664.      *                                         1                Actual/actual
  665.      *                                         2                Actual/360
  666.      *                                         3                Actual/365
  667.      *                                         4                European 30/360
  668.      *    @return    float 
  669.      */
  670.     public static function DISC($settlement$maturity$price$redemption$basis=0{
  671.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  672.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  673.         $price        = (float) PHPExcel_Calculation_Functions::flattenSingleValue($price);
  674.         $redemption    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption);
  675.         $basis        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  676.  
  677.         //    Validate
  678.         if ((is_numeric($price)) && (is_numeric($redemption)) && (is_numeric($basis))) {
  679.             if (($price <= 0|| ($redemption <= 0)) {
  680.                 return PHPExcel_Calculation_Functions::NaN();
  681.             }
  682.             $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity$basis);
  683.             if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  684.                 //    return date error
  685.                 return $daysBetweenSettlementAndMaturity;
  686.             }
  687.  
  688.             return (($price $redemption$daysBetweenSettlementAndMaturity);
  689.         }
  690.         return PHPExcel_Calculation_Functions::VALUE();
  691.     }    //    function DISC()
  692.  
  693.  
  694.     /**
  695.      * DOLLARDE
  696.      *
  697.      * Converts a dollar price expressed as an integer part and a fraction part into a dollar price expressed as a decimal number.
  698.      * Fractional dollar numbers are sometimes used for security prices.
  699.      *
  700.      * @param    float    $fractional_dollar    Fractional Dollar
  701.      * @param    int        $fraction            Fraction
  702.      * @return    float 
  703.      */
  704.     public static function DOLLARDE($fractional_dollar Null$fraction 0{
  705.         $fractional_dollar    PHPExcel_Calculation_Functions::flattenSingleValue($fractional_dollar);
  706.         $fraction            = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction);
  707.  
  708.         // Validate parameters
  709.         if (is_null($fractional_dollar|| $fraction 0{
  710.             return PHPExcel_Calculation_Functions::NaN();
  711.         }
  712.         if ($fraction == 0{
  713.             return PHPExcel_Calculation_Functions::DIV0();
  714.         }
  715.  
  716.         $dollars floor($fractional_dollar);
  717.         $cents fmod($fractional_dollar,1);
  718.         $cents /= $fraction;
  719.         $cents *= pow(10,ceil(log10($fraction)));
  720.         return $dollars $cents;
  721.     }    //    function DOLLARDE()
  722.  
  723.  
  724.     /**
  725.      * DOLLARFR
  726.      *
  727.      * Converts a dollar price expressed as a decimal number into a dollar price expressed as a fraction.
  728.      * Fractional dollar numbers are sometimes used for security prices.
  729.      *
  730.      * @param    float    $decimal_dollar        Decimal Dollar
  731.      * @param    int        $fraction            Fraction
  732.      * @return    float 
  733.      */
  734.     public static function DOLLARFR($decimal_dollar Null$fraction 0{
  735.         $decimal_dollar    PHPExcel_Calculation_Functions::flattenSingleValue($decimal_dollar);
  736.         $fraction        = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction);
  737.  
  738.         // Validate parameters
  739.         if (is_null($decimal_dollar|| $fraction 0{
  740.             return PHPExcel_Calculation_Functions::NaN();
  741.         }
  742.         if ($fraction == 0{
  743.             return PHPExcel_Calculation_Functions::DIV0();
  744.         }
  745.  
  746.         $dollars floor($decimal_dollar);
  747.         $cents fmod($decimal_dollar,1);
  748.         $cents *= $fraction;
  749.         $cents *= pow(10,-ceil(log10($fraction)));
  750.         return $dollars $cents;
  751.     }    //    function DOLLARFR()
  752.  
  753.  
  754.     /**
  755.      * EFFECT
  756.      *
  757.      * Returns the effective interest rate given the nominal rate and the number of compounding payments per year.
  758.      *
  759.      * @param    float    $nominal_rate        Nominal interest rate
  760.      * @param    int        $npery                Number of compounding payments per year
  761.      * @return    float 
  762.      */
  763.     public static function EFFECT($nominal_rate 0$npery 0{
  764.         $nominal_rate    PHPExcel_Calculation_Functions::flattenSingleValue($nominal_rate);
  765.         $npery            = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery);
  766.  
  767.         // Validate parameters
  768.         if ($nominal_rate <= || $npery 1{
  769.             return PHPExcel_Calculation_Functions::NaN();
  770.         }
  771.  
  772.         return pow(($nominal_rate $npery)$npery1;
  773.     }    //    function EFFECT()
  774.  
  775.  
  776.     /**
  777.      * FV
  778.      *
  779.      * Returns the Future Value of a cash flow with constant payments and interest rate (annuities).
  780.      *
  781.      * @param    float    $rate    Interest rate per period
  782.      * @param    int        $nper    Number of periods
  783.      * @param    float    $pmt    Periodic payment (annuity)
  784.      * @param    float    $pv        Present Value
  785.      * @param    int        $type    Payment type: 0 = at the end of each period, 1 = at the beginning of each period
  786.      * @return    float 
  787.      */
  788.     public static function FV($rate 0$nper 0$pmt 0$pv 0$type 0{
  789.         $rate    PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  790.         $nper    PHPExcel_Calculation_Functions::flattenSingleValue($nper);
  791.         $pmt    PHPExcel_Calculation_Functions::flattenSingleValue($pmt);
  792.         $pv        PHPExcel_Calculation_Functions::flattenSingleValue($pv);
  793.         $type    PHPExcel_Calculation_Functions::flattenSingleValue($type);
  794.  
  795.         // Validate parameters
  796.         if ($type != && $type != 1{
  797.             return PHPExcel_Calculation_Functions::NaN();
  798.         }
  799.  
  800.         // Calculate
  801.         if (!is_null($rate&& $rate != 0{
  802.             return -$pv pow($rate$nper$pmt ($rate $type(pow($rate$nper1$rate;
  803.         else {
  804.             return -$pv $pmt $nper;
  805.         }
  806.     }    //    function FV()
  807.  
  808.  
  809.     /**
  810.      * FVSCHEDULE
  811.      *
  812.      */
  813.     public static function FVSCHEDULE($principal$schedule{
  814.         $principal    PHPExcel_Calculation_Functions::flattenSingleValue($principal);
  815.         $schedule    PHPExcel_Calculation_Functions::flattenArray($schedule);
  816.  
  817.         foreach($schedule as $n{
  818.             $principal *= $n;
  819.         }
  820.  
  821.         return $principal;
  822.     }    //    function FVSCHEDULE()
  823.  
  824.  
  825.     /**
  826.      *    INTRATE
  827.      *
  828.      *    Returns the interest rate for a fully invested security.
  829.      *
  830.      *    @param    mixed    settlement    The security's settlement date.
  831.      *                                 The security settlement date is the date after the issue date when the security is traded to the buyer.
  832.      *    @param    mixed    maturity    The security's maturity date.
  833.      *                                 The maturity date is the date when the security expires.
  834.      *    @param    int        investment    The amount invested in the security.
  835.      *    @param    int        redemption    The amount to be received at maturity.
  836.      *    @param    int        basis        The type of day count to use.
  837.      *                                         0 or omitted    US (NASD) 30/360
  838.      *                                         1                Actual/actual
  839.      *                                         2                Actual/360
  840.      *                                         3                Actual/365
  841.      *                                         4                European 30/360
  842.      *    @return    float 
  843.      */
  844.     public static function INTRATE($settlement$maturity$investment$redemption$basis=0{
  845.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  846.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  847.         $investment    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($investment);
  848.         $redemption    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption);
  849.         $basis        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  850.  
  851.         //    Validate
  852.         if ((is_numeric($investment)) && (is_numeric($redemption)) && (is_numeric($basis))) {
  853.             if (($investment <= 0|| ($redemption <= 0)) {
  854.                 return PHPExcel_Calculation_Functions::NaN();
  855.             }
  856.             $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity$basis);
  857.             if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  858.                 //    return date error
  859.                 return $daysBetweenSettlementAndMaturity;
  860.             }
  861.  
  862.             return (($redemption $investment1($daysBetweenSettlementAndMaturity);
  863.         }
  864.         return PHPExcel_Calculation_Functions::VALUE();
  865.     }    //    function INTRATE()
  866.  
  867.  
  868.     /**
  869.      *    IPMT
  870.      *
  871.      *    Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate.
  872.      *
  873.      *    @param    float    $rate    Interest rate per period
  874.      *    @param    int        $per    Period for which we want to find the interest
  875.      *    @param    int        $nper    Number of periods
  876.      *    @param    float    $pv        Present Value
  877.      *    @param    float    $fv        Future Value
  878.      *    @param    int        $type    Payment type: 0 = at the end of each period, 1 = at the beginning of each period
  879.      *    @return    float 
  880.      */
  881.     public static function IPMT($rate$per$nper$pv$fv 0$type 0{
  882.         $rate    PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  883.         $per    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per);
  884.         $nper    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);
  885.         $pv        PHPExcel_Calculation_Functions::flattenSingleValue($pv);
  886.         $fv        PHPExcel_Calculation_Functions::flattenSingleValue($fv);
  887.         $type    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);
  888.  
  889.         // Validate parameters
  890.         if ($type != && $type != 1{
  891.             return PHPExcel_Calculation_Functions::NaN();
  892.         }
  893.         if ($per <= || $per $nper{
  894.             return PHPExcel_Calculation_Functions::VALUE();
  895.         }
  896.  
  897.         // Calculate
  898.         $interestAndPrincipal self::_interestAndPrincipal($rate$per$nper$pv$fv$type);
  899.         return $interestAndPrincipal[0];
  900.     }    //    function IPMT()
  901.  
  902.  
  903.     public static function IRR($values$guess 0.1{
  904.         if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE();
  905.         $values PHPExcel_Calculation_Functions::flattenArray($values);
  906.         $guess PHPExcel_Calculation_Functions::flattenSingleValue($guess);
  907.  
  908.         // create an initial range, with a root somewhere between 0 and guess
  909.         $x1 0.0;
  910.         $x2 $guess;
  911.         $f1 self::NPV($x1$values);
  912.         $f2 self::NPV($x2$values);
  913.         for ($i 0$i FINANCIAL_MAX_ITERATIONS++$i{
  914.             if (($f1 $f20.0break;
  915.             if (abs($f1abs($f2)) {
  916.                 $f1 self::NPV($x1 += 1.6 ($x1 $x2)$values);
  917.             else {
  918.                 $f2 self::NPV($x2 += 1.6 ($x2 $x1)$values);
  919.             }
  920.         }
  921.         if (($f1 $f20.0return PHPExcel_Calculation_Functions::VALUE();
  922.  
  923.         $f self::NPV($x1$values);
  924.         if ($f 0.0{
  925.             $rtb $x1;
  926.             $dx $x2 $x1;
  927.         else {
  928.             $rtb $x2;
  929.             $dx $x1 $x2;
  930.         }
  931.  
  932.         for ($i 0;  $i FINANCIAL_MAX_ITERATIONS++$i{
  933.             $dx *= 0.5;
  934.             $x_mid $rtb $dx;
  935.             $f_mid self::NPV($x_mid$values);
  936.             if ($f_mid <= 0.0$rtb $x_mid;
  937.             if ((abs($f_midFINANCIAL_PRECISION|| (abs($dxFINANCIAL_PRECISION)) return $x_mid;
  938.         }
  939.         return PHPExcel_Calculation_Functions::VALUE();
  940.     }    //    function IRR()
  941.  
  942.  
  943.     /**
  944.      *      ISPMT
  945.      *
  946.      *      Returns the interest payment for an investment based on an interest rate and a constant payment schedule.
  947.      *
  948.      *      Excel Function:
  949.      *          =ISPMT(interest_rate, period, number_payments, PV)
  950.      *
  951.      *      interest_rate is the interest rate for the investment
  952.      *
  953.      *      period is the period to calculate the interest rate.  It must be betweeen 1 and number_payments.
  954.      *
  955.      *      number_payments is the number of payments for the annuity
  956.      *
  957.      *      PV is the loan amount or present value of the payments
  958.      */
  959.     public static function ISPMT({
  960.         // Return value
  961.         $returnValue 0;
  962.  
  963.         // Get the parameters
  964.         $interestRate array_shift($aArgs);
  965.         $period array_shift($aArgs);
  966.         $numberPeriods array_shift($aArgs);
  967.         $principleRemaining array_shift($aArgs);
  968.  
  969.         // Calculate
  970.         $principlePayment ($principleRemaining 1.0($numberPeriods 1.0);
  971.         for($i=0$i <= $period++$i{
  972.             $returnValue $interestRate $principleRemaining * -1;
  973.             $principleRemaining -= $principlePayment;
  974.             // principle needs to be 0 after the last payment, don't let floating point screw it up
  975.             if($i == $numberPeriods{
  976.                 $returnValue 0;
  977.             }
  978.         }
  979.         return($returnValue);
  980.     }    //    function ISPMT()
  981.  
  982.  
  983.     public static function MIRR($values$finance_rate$reinvestment_rate{
  984.         if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE();
  985.         $values                PHPExcel_Calculation_Functions::flattenArray($values);
  986.         $finance_rate        PHPExcel_Calculation_Functions::flattenSingleValue($finance_rate);
  987.         $reinvestment_rate    PHPExcel_Calculation_Functions::flattenSingleValue($reinvestment_rate);
  988.         $n count($values);
  989.  
  990.         $rr 1.0 $reinvestment_rate;
  991.         $fr 1.0 $finance_rate;
  992.  
  993.         $npv_pos $npv_neg 0.0;
  994.         foreach($values as $i => $v{
  995.             if ($v >= 0{
  996.                 $npv_pos += $v pow($rr$i);
  997.             else {
  998.                 $npv_neg += $v pow($fr$i);
  999.             }
  1000.         }
  1001.  
  1002.         if (($npv_neg == 0|| ($npv_pos == 0|| ($reinvestment_rate <= -1)) {
  1003.             return PHPExcel_Calculation_Functions::VALUE();
  1004.         }
  1005.  
  1006.         $mirr pow((-$npv_pos pow($rr$n))
  1007.                 / ($npv_neg ($rr))(1.0 ($n 1))) 1.0;
  1008.  
  1009.         return (is_finite($mirr$mirr PHPExcel_Calculation_Functions::VALUE());
  1010.     }    //    function MIRR()
  1011.  
  1012.  
  1013.     /**
  1014.      * NOMINAL
  1015.      *
  1016.      * Returns the nominal interest rate given the effective rate and the number of compounding payments per year.
  1017.      *
  1018.      * @param    float    $effect_rate    Effective interest rate
  1019.      * @param    int        $npery            Number of compounding payments per year
  1020.      * @return    float 
  1021.      */
  1022.     public static function NOMINAL($effect_rate 0$npery 0{
  1023.         $effect_rate    PHPExcel_Calculation_Functions::flattenSingleValue($effect_rate);
  1024.         $npery            = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery);
  1025.  
  1026.         // Validate parameters
  1027.         if ($effect_rate <= || $npery 1{
  1028.             return PHPExcel_Calculation_Functions::NaN();
  1029.         }
  1030.  
  1031.         // Calculate
  1032.         return $npery (pow($effect_rate 1$npery1);
  1033.     }    //    function NOMINAL()
  1034.  
  1035.  
  1036.     /**
  1037.      * NPER
  1038.      *
  1039.      * Returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate.
  1040.      *
  1041.      *    @param    float    $rate    Interest rate per period
  1042.      *    @param    int        $pmt    Periodic payment (annuity)
  1043.      *    @param    float    $pv        Present Value
  1044.      *    @param    float    $fv        Future Value
  1045.      *    @param    int        $type    Payment type: 0 = at the end of each period, 1 = at the beginning of each period
  1046.      *    @return    float 
  1047.      */
  1048.     public static function NPER($rate 0$pmt 0$pv 0$fv 0$type 0{
  1049.         $rate    PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  1050.         $pmt    PHPExcel_Calculation_Functions::flattenSingleValue($pmt);
  1051.         $pv        PHPExcel_Calculation_Functions::flattenSingleValue($pv);
  1052.         $fv        PHPExcel_Calculation_Functions::flattenSingleValue($fv);
  1053.         $type    PHPExcel_Calculation_Functions::flattenSingleValue($type);
  1054.  
  1055.         // Validate parameters
  1056.         if ($type != && $type != 1{
  1057.             return PHPExcel_Calculation_Functions::NaN();
  1058.         }
  1059.  
  1060.         // Calculate
  1061.         if (!is_null($rate&& $rate != 0{
  1062.             if ($pmt == && $pv == 0{
  1063.                 return PHPExcel_Calculation_Functions::NaN();
  1064.             }
  1065.             return log(($pmt ($rate $type$rate $fv($pv $pmt ($rate $type$rate)) log($rate);
  1066.         else {
  1067.             if ($pmt == 0{
  1068.                 return PHPExcel_Calculation_Functions::NaN();
  1069.             }
  1070.             return (-$pv -$fv$pmt;
  1071.         }
  1072.     }    //    function NPER()
  1073.  
  1074.  
  1075.     /**
  1076.      * NPV
  1077.      *
  1078.      * Returns the Net Present Value of a cash flow series given a discount rate.
  1079.      *
  1080.      * @param    float    Discount interest rate
  1081.      * @param    array    Cash flow series
  1082.      * @return    float 
  1083.      */
  1084.     public static function NPV({
  1085.         // Return value
  1086.         $returnValue 0;
  1087.  
  1088.         // Loop through arguments
  1089.  
  1090.         // Calculate
  1091.         $rate array_shift($aArgs);
  1092.         for ($i 1$i <= count($aArgs)++$i{
  1093.             // Is it a numeric value?
  1094.             if (is_numeric($aArgs[$i 1])) {
  1095.                 $returnValue += $aArgs[$i 1pow($rate$i);
  1096.             }
  1097.         }
  1098.  
  1099.         // Return
  1100.         return $returnValue;
  1101.     }    //    function NPV()
  1102.  
  1103.  
  1104.     /**
  1105.      * PMT
  1106.      *
  1107.      * Returns the constant payment (annuity) for a cash flow with a constant interest rate.
  1108.      *
  1109.      * @param    float    $rate    Interest rate per period
  1110.      * @param    int        $nper    Number of periods
  1111.      * @param    float    $pv        Present Value
  1112.      * @param    float    $fv        Future Value
  1113.      * @param    int        $type    Payment type: 0 = at the end of each period, 1 = at the beginning of each period
  1114.      * @return    float 
  1115.      */
  1116.     public static function PMT($rate 0$nper 0$pv 0$fv 0$type 0{
  1117.         $rate    PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  1118.         $nper    PHPExcel_Calculation_Functions::flattenSingleValue($nper);
  1119.         $pv        PHPExcel_Calculation_Functions::flattenSingleValue($pv);
  1120.         $fv        PHPExcel_Calculation_Functions::flattenSingleValue($fv);
  1121.         $type    PHPExcel_Calculation_Functions::flattenSingleValue($type);
  1122.  
  1123.         // Validate parameters
  1124.         if ($type != && $type != 1{
  1125.             return PHPExcel_Calculation_Functions::NaN();
  1126.         }
  1127.  
  1128.         // Calculate
  1129.         if (!is_null($rate&& $rate != 0{
  1130.             return (-$fv $pv pow($rate$nper)) ($rate $type((pow($rate$nper1$rate);
  1131.         else {
  1132.             return (-$pv $fv$nper;
  1133.         }
  1134.     }    //    function PMT()
  1135.  
  1136.  
  1137.     /**
  1138.      *    PPMT
  1139.      *
  1140.      *    Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate.
  1141.      *
  1142.      *    @param    float    $rate    Interest rate per period
  1143.      *    @param    int        $per    Period for which we want to find the interest
  1144.      *    @param    int        $nper    Number of periods
  1145.      *    @param    float    $pv        Present Value
  1146.      *    @param    float    $fv        Future Value
  1147.      *    @param    int        $type    Payment type: 0 = at the end of each period, 1 = at the beginning of each period
  1148.      *    @return    float 
  1149.      */
  1150.     public static function PPMT($rate$per$nper$pv$fv 0$type 0{
  1151.         $rate    PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  1152.         $per    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per);
  1153.         $nper    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);
  1154.         $pv        PHPExcel_Calculation_Functions::flattenSingleValue($pv);
  1155.         $fv        PHPExcel_Calculation_Functions::flattenSingleValue($fv);
  1156.         $type    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);
  1157.  
  1158.         // Validate parameters
  1159.         if ($type != && $type != 1{
  1160.             return PHPExcel_Calculation_Functions::NaN();
  1161.         }
  1162.         if ($per <= || $per $nper{
  1163.             return PHPExcel_Calculation_Functions::VALUE();
  1164.         }
  1165.  
  1166.         // Calculate
  1167.         $interestAndPrincipal self::_interestAndPrincipal($rate$per$nper$pv$fv$type);
  1168.         return $interestAndPrincipal[1];
  1169.     }    //    function PPMT()
  1170.  
  1171.  
  1172.     public static function PRICE($settlement$maturity$rate$yield$redemption$frequency$basis=0{
  1173.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1174.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1175.         $rate        = (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  1176.         $yield        = (float) PHPExcel_Calculation_Functions::flattenSingleValue($yield);
  1177.         $redemption    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption);
  1178.         $frequency    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);
  1179.         $basis        (is_null($basis))    :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  1180.  
  1181.         if (is_string($settlement PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {
  1182.             return PHPExcel_Calculation_Functions::VALUE();
  1183.         }
  1184.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  1185.             return PHPExcel_Calculation_Functions::VALUE();
  1186.         }
  1187.  
  1188.         if (($settlement $maturity||
  1189.             (!self::_validFrequency($frequency)) ||
  1190.             (($basis 0|| ($basis 4))) {
  1191.             return PHPExcel_Calculation_Functions::NaN();
  1192.         }
  1193.  
  1194.         $dsc self::COUPDAYSNC($settlement$maturity$frequency$basis);
  1195.         $e self::COUPDAYS($settlement$maturity$frequency$basis);
  1196.         $n self::COUPNUM($settlement$maturity$frequency$basis);
  1197.         $a self::COUPDAYBS($settlement$maturity$frequency$basis);
  1198.  
  1199.         $baseYF    1.0 ($yield $frequency);
  1200.         $rfp    100 ($rate $frequency);
  1201.         $de    $dsc $e;
  1202.  
  1203.         $result $redemption pow($baseYF(--$n $de));
  1204.         for($k 0$k <= $n++$k{
  1205.             $result += $rfp (pow($baseYF($k $de)));
  1206.         }
  1207.         $result -= $rfp ($a $e);
  1208.  
  1209.         return $result;
  1210.     }    //    function PRICE()
  1211.  
  1212.  
  1213.     /**
  1214.      *    PRICEDISC
  1215.      *
  1216.      *    Returns the price per $100 face value of a discounted security.
  1217.      *
  1218.      *    @param    mixed    settlement    The security's settlement date.
  1219.      *                                 The security settlement date is the date after the issue date when the security is traded to the buyer.
  1220.      *    @param    mixed    maturity    The security's maturity date.
  1221.      *                                 The maturity date is the date when the security expires.
  1222.      *    @param    int        discount    The security's discount rate.
  1223.      *    @param    int        redemption    The security's redemption value per $100 face value.
  1224.      *    @param    int        basis        The type of day count to use.
  1225.      *                                         0 or omitted    US (NASD) 30/360
  1226.      *                                         1                Actual/actual
  1227.      *                                         2                Actual/360
  1228.      *                                         3                Actual/365
  1229.      *                                         4                European 30/360
  1230.      *    @return    float 
  1231.      */
  1232.     public static function PRICEDISC($settlement$maturity$discount$redemption$basis=0{
  1233.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1234.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1235.         $discount    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount);
  1236.         $redemption    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption);
  1237.         $basis        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  1238.  
  1239.         //    Validate
  1240.         if ((is_numeric($discount)) && (is_numeric($redemption)) && (is_numeric($basis))) {
  1241.             if (($discount <= 0|| ($redemption <= 0)) {
  1242.                 return PHPExcel_Calculation_Functions::NaN();
  1243.             }
  1244.             $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity$basis);
  1245.             if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  1246.                 //    return date error
  1247.                 return $daysBetweenSettlementAndMaturity;
  1248.             }
  1249.  
  1250.             return $redemption ($discount $daysBetweenSettlementAndMaturity);
  1251.         }
  1252.         return PHPExcel_Calculation_Functions::VALUE();
  1253.     }    //    function PRICEDISC()
  1254.  
  1255.  
  1256.     /**
  1257.      *    PRICEMAT
  1258.      *
  1259.      *    Returns the price per $100 face value of a security that pays interest at maturity.
  1260.      *
  1261.      *    @param    mixed    settlement    The security's settlement date.
  1262.      *                                 The security's settlement date is the date after the issue date when the security is traded to the buyer.
  1263.      *    @param    mixed    maturity    The security's maturity date.
  1264.      *                                 The maturity date is the date when the security expires.
  1265.      *    @param    mixed    issue        The security's issue date.
  1266.      *    @param    int        rate        The security's interest rate at date of issue.
  1267.      *    @param    int        yield        The security's annual yield.
  1268.      *    @param    int        basis        The type of day count to use.
  1269.      *                                         0 or omitted    US (NASD) 30/360
  1270.      *                                         1                Actual/actual
  1271.      *                                         2                Actual/360
  1272.      *                                         3                Actual/365
  1273.      *                                         4                European 30/360
  1274.      *    @return    float 
  1275.      */
  1276.     public static function PRICEMAT($settlement$maturity$issue$rate$yield$basis=0{
  1277.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1278.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1279.         $issue        PHPExcel_Calculation_Functions::flattenSingleValue($issue);
  1280.         $rate        PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  1281.         $yield        PHPExcel_Calculation_Functions::flattenSingleValue($yield);
  1282.         $basis        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  1283.  
  1284.         //    Validate
  1285.         if (is_numeric($rate&& is_numeric($yield)) {
  1286.             if (($rate <= 0|| ($yield <= 0)) {
  1287.                 return PHPExcel_Calculation_Functions::NaN();
  1288.             }
  1289.             $daysPerYear self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);
  1290.             if (!is_numeric($daysPerYear)) {
  1291.                 return $daysPerYear;
  1292.             }
  1293.             $daysBetweenIssueAndSettlement PHPExcel_Calculation_DateTime::YEARFRAC($issue$settlement$basis);
  1294.             if (!is_numeric($daysBetweenIssueAndSettlement)) {
  1295.                 //    return date error
  1296.                 return $daysBetweenIssueAndSettlement;
  1297.             }
  1298.             $daysBetweenIssueAndSettlement *= $daysPerYear;
  1299.             $daysBetweenIssueAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($issue$maturity$basis);
  1300.             if (!is_numeric($daysBetweenIssueAndMaturity)) {
  1301.                 //    return date error
  1302.                 return $daysBetweenIssueAndMaturity;
  1303.             }
  1304.             $daysBetweenIssueAndMaturity *= $daysPerYear;
  1305.             $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity$basis);
  1306.             if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  1307.                 //    return date error
  1308.                 return $daysBetweenSettlementAndMaturity;
  1309.             }
  1310.             $daysBetweenSettlementAndMaturity *= $daysPerYear;
  1311.  
  1312.             return ((100 (($daysBetweenIssueAndMaturity $daysPerYear$rate 100)) /
  1313.                    ((($daysBetweenSettlementAndMaturity $daysPerYear$yield)) -
  1314.                    (($daysBetweenIssueAndSettlement $daysPerYear$rate 100));
  1315.         }
  1316.         return PHPExcel_Calculation_Functions::VALUE();
  1317.     }    //    function PRICEMAT()
  1318.  
  1319.  
  1320.     /**
  1321.      * PV
  1322.      *
  1323.      * Returns the Present Value of a cash flow with constant payments and interest rate (annuities).
  1324.      *
  1325.      * @param    float    $rate    Interest rate per period
  1326.      * @param    int        $nper    Number of periods
  1327.      * @param    float    $pmt    Periodic payment (annuity)
  1328.      * @param    float    $fv        Future Value
  1329.      * @param    int        $type    Payment type: 0 = at the end of each period, 1 = at the beginning of each period
  1330.      * @return    float 
  1331.      */
  1332.     public static function PV($rate 0$nper 0$pmt 0$fv 0$type 0{
  1333.         $rate    PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  1334.         $nper    PHPExcel_Calculation_Functions::flattenSingleValue($nper);
  1335.         $pmt    PHPExcel_Calculation_Functions::flattenSingleValue($pmt);
  1336.         $fv        PHPExcel_Calculation_Functions::flattenSingleValue($fv);
  1337.         $type    PHPExcel_Calculation_Functions::flattenSingleValue($type);
  1338.  
  1339.         // Validate parameters
  1340.         if ($type != && $type != 1{
  1341.             return PHPExcel_Calculation_Functions::NaN();
  1342.         }
  1343.  
  1344.         // Calculate
  1345.         if (!is_null($rate&& $rate != 0{
  1346.             return (-$pmt ($rate $type((pow($rate$nper1$rate$fvpow($rate$nper);
  1347.         else {
  1348.             return -$fv $pmt $nper;
  1349.         }
  1350.     }    //    function PV()
  1351.  
  1352.  
  1353.     /**
  1354.      * RATE
  1355.      *
  1356.      **/
  1357.  
  1358.     public static function RATE($nper$pmt$pv$fv 0.0$type 0$guess 0.1{
  1359.         $nper    = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);
  1360.         $pmt    PHPExcel_Calculation_Functions::flattenSingleValue($pmt);
  1361.         $pv        PHPExcel_Calculation_Functions::flattenSingleValue($pv);
  1362.         $fv        (is_null($fv))    0.0    :    PHPExcel_Calculation_Functions::flattenSingleValue($fv);
  1363.         $type    (is_null($type))    0        :    (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);
  1364.         $guess    (is_null($guess))    0.1    :    PHPExcel_Calculation_Functions::flattenSingleValue($guess);
  1365.  
  1366.         $rate $guess;
  1367.         if (abs($rateFINANCIAL_PRECISION{
  1368.             $y $pv ($nper $rate$pmt ($rate $type$nper $fv;
  1369.         else {
  1370.             $f exp($nper log($rate));
  1371.             $y $pv $f $pmt ($rate $type($f 1$fv;
  1372.         }
  1373.         $y0 $pv $pmt $nper $fv;
  1374.         $y1 $pv $f $pmt ($rate $type($f 1$fv;
  1375.  
  1376.         // find root by secant method
  1377.         $i  $x0 0.0;
  1378.         $x1 $rate;
  1379.         while ((abs($y0 $y1FINANCIAL_PRECISION&& ($i FINANCIAL_MAX_ITERATIONS)) {
  1380.             $rate ($y1 $x0 $y0 $x1($y1 $y0);
  1381.             $x0 $x1;
  1382.             $x1 $rate;
  1383.  
  1384.             if (abs($rateFINANCIAL_PRECISION{
  1385.                 $y $pv ($nper $rate$pmt ($rate $type$nper $fv;
  1386.             else {
  1387.                 $f exp($nper log($rate));
  1388.                 $y $pv $f $pmt ($rate $type($f 1$fv;
  1389.             }
  1390.  
  1391.             $y0 $y1;
  1392.             $y1 $y;
  1393.             ++$i;
  1394.         }
  1395.         return $rate;
  1396.     }    //    function RATE()
  1397.  
  1398.  
  1399.     /**
  1400.      *    RECEIVED
  1401.      *
  1402.      *    Returns the price per $100 face value of a discounted security.
  1403.      *
  1404.      *    @param    mixed    settlement    The security's settlement date.
  1405.      *                                 The security settlement date is the date after the issue date when the security is traded to the buyer.
  1406.      *    @param    mixed    maturity    The security's maturity date.
  1407.      *                                 The maturity date is the date when the security expires.
  1408.      *    @param    int        investment    The amount invested in the security.
  1409.      *    @param    int        discount    The security's discount rate.
  1410.      *    @param    int        basis        The type of day count to use.
  1411.      *                                         0 or omitted    US (NASD) 30/360
  1412.      *                                         1                Actual/actual
  1413.      *                                         2                Actual/360
  1414.      *                                         3                Actual/365
  1415.      *                                         4                European 30/360
  1416.      *    @return    float 
  1417.      */
  1418.     public static function RECEIVED($settlement$maturity$investment$discount$basis=0{
  1419.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1420.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1421.         $investment    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($investment);
  1422.         $discount    = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount);
  1423.         $basis        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  1424.  
  1425.         //    Validate
  1426.         if ((is_numeric($investment)) && (is_numeric($discount)) && (is_numeric($basis))) {
  1427.             if (($investment <= 0|| ($discount <= 0)) {
  1428.                 return PHPExcel_Calculation_Functions::NaN();
  1429.             }
  1430.             $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity$basis);
  1431.             if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  1432.                 //    return date error
  1433.                 return $daysBetweenSettlementAndMaturity;
  1434.             }
  1435.  
  1436.             return $investment ($discount $daysBetweenSettlementAndMaturity));
  1437.         }
  1438.         return PHPExcel_Calculation_Functions::VALUE();
  1439.     }    //    function RECEIVED()
  1440.  
  1441.  
  1442.     /**
  1443.      * SLN
  1444.      *
  1445.      * Returns the straight-line depreciation of an asset for one period
  1446.      *
  1447.      * @param    cost        Initial cost of the asset
  1448.      * @param    salvage        Value at the end of the depreciation
  1449.      * @param    life        Number of periods over which the asset is depreciated
  1450.      * @return    float 
  1451.      */
  1452.     public static function SLN($cost$salvage$life{
  1453.         $cost        PHPExcel_Calculation_Functions::flattenSingleValue($cost);
  1454.         $salvage    PHPExcel_Calculation_Functions::flattenSingleValue($salvage);
  1455.         $life        PHPExcel_Calculation_Functions::flattenSingleValue($life);
  1456.  
  1457.         // Calculate
  1458.         if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life))) {
  1459.             if ($life 0{
  1460.                 return PHPExcel_Calculation_Functions::NaN();
  1461.             }
  1462.             return ($cost $salvage$life;
  1463.         }
  1464.         return PHPExcel_Calculation_Functions::VALUE();
  1465.     }    //    function SLN()
  1466.  
  1467.  
  1468.     /**
  1469.      * SYD
  1470.      *
  1471.      * Returns the sum-of-years' digits depreciation of an asset for a specified period.
  1472.      *
  1473.      * @param    cost        Initial cost of the asset
  1474.      * @param    salvage        Value at the end of the depreciation
  1475.      * @param    life        Number of periods over which the asset is depreciated
  1476.      * @param    period        Period
  1477.      * @return    float 
  1478.      */
  1479.     public static function SYD($cost$salvage$life$period{
  1480.         $cost        PHPExcel_Calculation_Functions::flattenSingleValue($cost);
  1481.         $salvage    PHPExcel_Calculation_Functions::flattenSingleValue($salvage);
  1482.         $life        PHPExcel_Calculation_Functions::flattenSingleValue($life);
  1483.         $period        PHPExcel_Calculation_Functions::flattenSingleValue($period);
  1484.  
  1485.         // Calculate
  1486.         if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period))) {
  1487.             if (($life 1|| ($period $life)) {
  1488.                 return PHPExcel_Calculation_Functions::NaN();
  1489.             }
  1490.             return (($cost $salvage($life $period 12($life ($life 1));
  1491.         }
  1492.         return PHPExcel_Calculation_Functions::VALUE();
  1493.     }    //    function SYD()
  1494.  
  1495.  
  1496.     /**
  1497.      *    TBILLEQ
  1498.      *
  1499.      *    Returns the bond-equivalent yield for a Treasury bill.
  1500.      *
  1501.      *    @param    mixed    settlement    The Treasury bill's settlement date.
  1502.      *                                 The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.
  1503.      *    @param    mixed    maturity    The Treasury bill's maturity date.
  1504.      *                                 The maturity date is the date when the Treasury bill expires.
  1505.      *    @param    int        discount    The Treasury bill's discount rate.
  1506.      *    @return    float 
  1507.      */
  1508.     public static function TBILLEQ($settlement$maturity$discount{
  1509.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1510.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1511.         $discount    PHPExcel_Calculation_Functions::flattenSingleValue($discount);
  1512.  
  1513.         //    Use TBILLPRICE for validation
  1514.         $testValue self::TBILLPRICE($settlement$maturity$discount);
  1515.         if (is_string($testValue)) {
  1516.             return $testValue;
  1517.         }
  1518.  
  1519.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  1520.             return PHPExcel_Calculation_Functions::VALUE();
  1521.         }
  1522.  
  1523.         if (PHPExcel_Calculation_Functions::getCompatibilityMode(== PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE{
  1524.             ++$maturity;
  1525.             $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity360;
  1526.         else {
  1527.             $daysBetweenSettlementAndMaturity (PHPExcel_Calculation_DateTime::_getDateValue($maturityPHPExcel_Calculation_DateTime::_getDateValue($settlement));
  1528.         }
  1529.  
  1530.         return (365 $discount(360 $discount $daysBetweenSettlementAndMaturity);
  1531.     }    //    function TBILLEQ()
  1532.  
  1533.  
  1534.     /**
  1535.      *    TBILLPRICE
  1536.      *
  1537.      *    Returns the yield for a Treasury bill.
  1538.      *
  1539.      *    @param    mixed    settlement    The Treasury bill's settlement date.
  1540.      *                                 The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.
  1541.      *    @param    mixed    maturity    The Treasury bill's maturity date.
  1542.      *                                 The maturity date is the date when the Treasury bill expires.
  1543.      *    @param    int        discount    The Treasury bill's discount rate.
  1544.      *    @return    float 
  1545.      */
  1546.     public static function TBILLPRICE($settlement$maturity$discount{
  1547.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1548.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1549.         $discount    PHPExcel_Calculation_Functions::flattenSingleValue($discount);
  1550.  
  1551.         if (is_string($maturity PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {
  1552.             return PHPExcel_Calculation_Functions::VALUE();
  1553.         }
  1554.  
  1555.         //    Validate
  1556.         if (is_numeric($discount)) {
  1557.             if ($discount <= 0{
  1558.                 return PHPExcel_Calculation_Functions::NaN();
  1559.             }
  1560.  
  1561.             if (PHPExcel_Calculation_Functions::getCompatibilityMode(== PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE{
  1562.                 ++$maturity;
  1563.                 $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity360;
  1564.                 if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  1565.                     //    return date error
  1566.                     return $daysBetweenSettlementAndMaturity;
  1567.                 }
  1568.             else {
  1569.                 $daysBetweenSettlementAndMaturity (PHPExcel_Calculation_DateTime::_getDateValue($maturityPHPExcel_Calculation_DateTime::_getDateValue($settlement));
  1570.             }
  1571.  
  1572.             if ($daysBetweenSettlementAndMaturity 360{
  1573.                 return PHPExcel_Calculation_Functions::NaN();
  1574.             }
  1575.  
  1576.             $price 100 ((($discount $daysBetweenSettlementAndMaturity360));
  1577.             if ($price <= 0{
  1578.                 return PHPExcel_Calculation_Functions::NaN();
  1579.             }
  1580.             return $price;
  1581.         }
  1582.         return PHPExcel_Calculation_Functions::VALUE();
  1583.     }    //    function TBILLPRICE()
  1584.  
  1585.  
  1586.     /**
  1587.      *    TBILLYIELD
  1588.      *
  1589.      *    Returns the yield for a Treasury bill.
  1590.      *
  1591.      *    @param    mixed    settlement    The Treasury bill's settlement date.
  1592.      *                                 The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.
  1593.      *    @param    mixed    maturity    The Treasury bill's maturity date.
  1594.      *                                 The maturity date is the date when the Treasury bill expires.
  1595.      *    @param    int        price        The Treasury bill's price per $100 face value.
  1596.      *    @return    float 
  1597.      */
  1598.     public static function TBILLYIELD($settlement$maturity$price{
  1599.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1600.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1601.         $price        PHPExcel_Calculation_Functions::flattenSingleValue($price);
  1602.  
  1603.         //    Validate
  1604.         if (is_numeric($price)) {
  1605.             if ($price <= 0{
  1606.                 return PHPExcel_Calculation_Functions::NaN();
  1607.             }
  1608.  
  1609.             if (PHPExcel_Calculation_Functions::getCompatibilityMode(== PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE{
  1610.                 ++$maturity;
  1611.                 $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity360;
  1612.                 if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  1613.                     //    return date error
  1614.                     return $daysBetweenSettlementAndMaturity;
  1615.                 }
  1616.             else {
  1617.                 $daysBetweenSettlementAndMaturity (PHPExcel_Calculation_DateTime::_getDateValue($maturityPHPExcel_Calculation_DateTime::_getDateValue($settlement));
  1618.             }
  1619.  
  1620.             if ($daysBetweenSettlementAndMaturity 360{
  1621.                 return PHPExcel_Calculation_Functions::NaN();
  1622.             }
  1623.  
  1624.             return ((100 $price$price(360 $daysBetweenSettlementAndMaturity);
  1625.         }
  1626.         return PHPExcel_Calculation_Functions::VALUE();
  1627.     }    //    function TBILLYIELD()
  1628.  
  1629.  
  1630.     public static function XIRR($values$dates$guess 0.1{
  1631.         if ((!is_array($values)) && (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE();
  1632.         $values    PHPExcel_Calculation_Functions::flattenArray($values);
  1633.         $dates    PHPExcel_Calculation_Functions::flattenArray($dates);
  1634.         $guess PHPExcel_Calculation_Functions::flattenSingleValue($guess);
  1635.         if (count($values!= count($dates)) return PHPExcel_Calculation_Functions::NaN();
  1636.  
  1637.         // create an initial range, with a root somewhere between 0 and guess
  1638.         $x1 0.0;
  1639.         $x2 $guess;
  1640.         $f1 self::XNPV($x1$values$dates);
  1641.         $f2 self::XNPV($x2$values$dates);
  1642.         for ($i 0$i FINANCIAL_MAX_ITERATIONS++$i{
  1643.             if (($f1 $f20.0break;
  1644.             if (abs($f1abs($f2)) {
  1645.                 $f1 self::XNPV($x1 += 1.6 ($x1 $x2)$values$dates);
  1646.             else {
  1647.                 $f2 self::XNPV($x2 += 1.6 ($x2 $x1)$values$dates);
  1648.             }
  1649.         }
  1650.         if (($f1 $f20.0return PHPExcel_Calculation_Functions::VALUE();
  1651.  
  1652.         $f self::XNPV($x1$values$dates);
  1653.         if ($f 0.0{
  1654.             $rtb $x1;
  1655.             $dx $x2 $x1;
  1656.         else {
  1657.             $rtb $x2;
  1658.             $dx $x1 $x2;
  1659.         }
  1660.  
  1661.         for ($i 0;  $i FINANCIAL_MAX_ITERATIONS++$i{
  1662.             $dx *= 0.5;
  1663.             $x_mid $rtb $dx;
  1664.             $f_mid self::XNPV($x_mid$values$dates);
  1665.             if ($f_mid <= 0.0$rtb $x_mid;
  1666.             if ((abs($f_midFINANCIAL_PRECISION|| (abs($dxFINANCIAL_PRECISION)) return $x_mid;
  1667.         }
  1668.         return PHPExcel_Calculation_Functions::VALUE();
  1669.     }
  1670.  
  1671.  
  1672.     /**
  1673.      *    XNPV
  1674.      *
  1675.      *    Returns the net present value for a schedule of cash flows that is not necessarily periodic.
  1676.      *    To calculate the net present value for a series of cash flows that is periodic, use the NPV function.
  1677.      *
  1678.      *    Excel Function:
  1679.      *        =XNPV(rate,values,dates)
  1680.      *
  1681.      *    @param    float            $rate        The discount rate to apply to the cash flows.
  1682.      *    @param    array of float    $values        A series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive value and one negative value.
  1683.      *    @param    array of mixed    $dates        A schedule of payment dates that corresponds to the cash flow payments. The first payment date indicates the beginning of the schedule of payments. All other dates must be later than this date, but they may occur in any order.
  1684.      *    @return    float 
  1685.      */
  1686.     public static function XNPV($rate$values$dates{
  1687.         $rate PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  1688.         if (!is_numeric($rate)) return PHPExcel_Calculation_Functions::VALUE();
  1689.         if ((!is_array($values)) || (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE();
  1690.         $values    PHPExcel_Calculation_Functions::flattenArray($values);
  1691.         $dates    PHPExcel_Calculation_Functions::flattenArray($dates);
  1692.         $valCount count($values);
  1693.         if ($valCount != count($dates)) return PHPExcel_Calculation_Functions::NaN();
  1694.         if ((min($values0|| (max($values0)) return PHPExcel_Calculation_Functions::VALUE();
  1695.  
  1696.         $xnpv 0.0;
  1697.         for ($i 0$i $valCount++$i{
  1698.             if (!is_numeric($values[$i])) return PHPExcel_Calculation_Functions::VALUE();
  1699.             $xnpv += $values[$ipow($ratePHPExcel_Calculation_DateTime::DATEDIF($dates[0],$dates[$i],'d'365);
  1700.         }
  1701.         return (is_finite($xnpv)) $xnpv PHPExcel_Calculation_Functions::VALUE();
  1702.     }    //    function XNPV()
  1703.  
  1704.  
  1705.     /**
  1706.      *    YIELDDISC
  1707.      *
  1708.      *    Returns the annual yield of a security that pays interest at maturity.
  1709.      *
  1710.      *    @param    mixed    settlement    The security's settlement date.
  1711.      *                                 The security's settlement date is the date after the issue date when the security is traded to the buyer.
  1712.      *    @param    mixed    maturity    The security's maturity date.
  1713.      *                                 The maturity date is the date when the security expires.
  1714.      *    @param    int        price        The security's price per $100 face value.
  1715.      *    @param    int        redemption    The security's redemption value per $100 face value.
  1716.      *    @param    int        basis        The type of day count to use.
  1717.      *                                         0 or omitted    US (NASD) 30/360
  1718.      *                                         1                Actual/actual
  1719.      *                                         2                Actual/360
  1720.      *                                         3                Actual/365
  1721.      *                                         4                European 30/360
  1722.      *    @return    float 
  1723.      */
  1724.     public static function YIELDDISC($settlement$maturity$price$redemption$basis=0{
  1725.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1726.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1727.         $price        PHPExcel_Calculation_Functions::flattenSingleValue($price);
  1728.         $redemption    PHPExcel_Calculation_Functions::flattenSingleValue($redemption);
  1729.         $basis        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  1730.  
  1731.         //    Validate
  1732.         if (is_numeric($price&& is_numeric($redemption)) {
  1733.             if (($price <= 0|| ($redemption <= 0)) {
  1734.                 return PHPExcel_Calculation_Functions::NaN();
  1735.             }
  1736.             $daysPerYear self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);
  1737.             if (!is_numeric($daysPerYear)) {
  1738.                 return $daysPerYear;
  1739.             }
  1740.             $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity,$basis);
  1741.             if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  1742.                 //    return date error
  1743.                 return $daysBetweenSettlementAndMaturity;
  1744.             }
  1745.             $daysBetweenSettlementAndMaturity *= $daysPerYear;
  1746.  
  1747.             return (($redemption $price$price($daysPerYear $daysBetweenSettlementAndMaturity);
  1748.         }
  1749.         return PHPExcel_Calculation_Functions::VALUE();
  1750.     }    //    function YIELDDISC()
  1751.  
  1752.  
  1753.     /**
  1754.      *    YIELDMAT
  1755.      *
  1756.      *    Returns the annual yield of a security that pays interest at maturity.
  1757.      *
  1758.      *    @param    mixed    settlement    The security's settlement date.
  1759.      *                                 The security's settlement date is the date after the issue date when the security is traded to the buyer.
  1760.      *    @param    mixed    maturity    The security's maturity date.
  1761.      *                                 The maturity date is the date when the security expires.
  1762.      *    @param    mixed    issue        The security's issue date.
  1763.      *    @param    int        rate        The security's interest rate at date of issue.
  1764.      *    @param    int        price        The security's price per $100 face value.
  1765.      *    @param    int        basis        The type of day count to use.
  1766.      *                                         0 or omitted    US (NASD) 30/360
  1767.      *                                         1                Actual/actual
  1768.      *                                         2                Actual/360
  1769.      *                                         3                Actual/365
  1770.      *                                         4                European 30/360
  1771.      *    @return    float 
  1772.      */
  1773.     public static function YIELDMAT($settlement$maturity$issue$rate$price$basis=0{
  1774.         $settlement    PHPExcel_Calculation_Functions::flattenSingleValue($settlement);
  1775.         $maturity    PHPExcel_Calculation_Functions::flattenSingleValue($maturity);
  1776.         $issue        PHPExcel_Calculation_Functions::flattenSingleValue($issue);
  1777.         $rate        PHPExcel_Calculation_Functions::flattenSingleValue($rate);
  1778.         $price        PHPExcel_Calculation_Functions::flattenSingleValue($price);
  1779.         $basis        = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);
  1780.  
  1781.         //    Validate
  1782.         if (is_numeric($rate&& is_numeric($price)) {
  1783.             if (($rate <= 0|| ($price <= 0)) {
  1784.                 return PHPExcel_Calculation_Functions::NaN();
  1785.             }
  1786.             $daysPerYear self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);
  1787.             if (!is_numeric($daysPerYear)) {
  1788.                 return $daysPerYear;
  1789.             }
  1790.             $daysBetweenIssueAndSettlement PHPExcel_Calculation_DateTime::YEARFRAC($issue$settlement$basis);
  1791.             if (!is_numeric($daysBetweenIssueAndSettlement)) {
  1792.                 //    return date error
  1793.                 return $daysBetweenIssueAndSettlement;
  1794.             }
  1795.             $daysBetweenIssueAndSettlement *= $daysPerYear;
  1796.             $daysBetweenIssueAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($issue$maturity$basis);
  1797.             if (!is_numeric($daysBetweenIssueAndMaturity)) {
  1798.                 //    return date error
  1799.                 return $daysBetweenIssueAndMaturity;
  1800.             }
  1801.             $daysBetweenIssueAndMaturity *= $daysPerYear;
  1802.             $daysBetweenSettlementAndMaturity PHPExcel_Calculation_DateTime::YEARFRAC($settlement$maturity$basis);
  1803.             if (!is_numeric($daysBetweenSettlementAndMaturity)) {
  1804.                 //    return date error
  1805.                 return $daysBetweenSettlementAndMaturity;
  1806.             }
  1807.             $daysBetweenSettlementAndMaturity *= $daysPerYear;
  1808.  
  1809.             return (((($daysBetweenIssueAndMaturity $daysPerYear$rate(($price 100(($daysBetweenIssueAndSettlement $daysPerYear$rate))) /
  1810.                    (($price 100(($daysBetweenIssueAndSettlement $daysPerYear$rate))) *
  1811.                    ($daysPerYear $daysBetweenSettlementAndMaturity);
  1812.         }
  1813.         return PHPExcel_Calculation_Functions::VALUE();
  1814.     }    //    function YIELDMAT()
  1815.  
  1816. }    //    class PHPExcel_Calculation_Financial

Documentation generated on Sun, 27 Feb 2011 16:31:38 -0800 by phpDocumentor 1.4.3