Calculate Net Present Value (NPV) in PHP

In this guide, we’ll show you how to calculate the Net Present Value (NPV) of a series of future cashflows using a PHP script.

PHP Net Present Value Overview

Using a little financial maths, we find the Net Present Value of a cashflow \(X\) at future time, \(t\), and interest rate \(i\) by: $$NPV=\frac{X}{(1+i)^t}$$

So, for example, the NPV of a payment of $100 in 2 years’ time with an (annually compounding) interest rate of 5% can be found using the above formula with the following values:

  • \(X = 100\)
  • \(t = 2\)
  • \(i = 0.05\)

So we have: $$PV = \frac{100}{1.05^2} = 90.70$$

This reflects the idea of compound interest where:

  • $90.70 invested now would earn interest at 5% in the first year to grow to \(90.70 \times 1.05 = 95.24\) after one year.
  • Then if left invested, both the original amount and the first year’s interest would earn interest in a second year. This causes it to grow to \(95.24 \times 1.05 = 100\).
  • We could also have verified this by: \(90.70 \times 1.05^2 = 100\).

So if we can invest $90.70 now, at 5% interest, it would grow to $100 in 2 years’ time. Thus we say that $90.70 is the present value of $100 in 2 years’ time.

We can implement this in PHP using the following simple script. Note we use the pow(base, exp) function to raise one number (the base) to the power of another (the exponent). For further details see the PHP manual page for the pow function.

<?php
$x = 100;
$i = 0.05;
$t = 2;
$npv = $x / pow(1+$i, $t);
echo $npv; // Output: 90.702947845805
?>

PHP Net Present Value of a series of yearly cashflows

Expanding on the above, suppose we have cashflows \(X_1, X_2, …, X_n\) paid at yearly intervals, starting immediately, and that the interest rate is still 5%. We can calculate the NPV of all cashflows by calculating the present value of each one individually, then adding them all up.
$$NPV = \sum_{t=1}^{n}{\frac{X_t}{(1+i)^t}}$$

We’ll build a function to do this in PHP:

<?php
function npv($cashflows, $intRate)
{
  $npv = 0;
  $year = 0; // First cashflow at time 0
  foreach($cashflows as $cf) {
    $npv += $cf / pow(1 + $intRate, $year);
    $year++;
  }
  return($npv);
}

$test_cf = [-100, 10, 20, 30, 40, 50];
echo npv($test_cf, 0.05); // Output: 25.663934364013
?>

Breaking it down, this function takes arguments $cashflows – an array of cashflows – and $intRate – the interest rate at which to value the cashflows. It does the following calculation steps:

  • Use a variable $npv to keep track of the running total, which we initialise to zero.
  • Loop through the $cashflows array, calculating the present value of each using the formula above, and adding that to the total, $npv.
  • Return the value $npv.

PHP NPV of a series of cashflows at different times

Suppose the cashflows you’re interested in don’t occur at exactly yearly intervals, but at various other points in the future. It’s simple to adjust the above example to cope with this, and we can just add an extra array $times as an argument to the function, and use this when calculating the present value of each cashflow.

We use this function to replicate the result of our npv() function created above, and then to calculate the NPV with different timings.

<?php
function npv_times($cashflows, $times, $intRate)
{
  $npv = 0;
  $i = 0;
  foreach($cashflows as $cf) {
    $year = $times[$i];
    $npv += $cf / pow(1 + $intRate, $year);
    $i++;
  }
  return($npv);
}

$test_cf = [-100, 10, 20, 30, 40, 50];
$test_times = [0, 1, 2, 3, 4, 5];
echo npv_times($test_cf, $test_times, 0.05); // Output: 25.663934364013

$test_times2 = [0, 3, 4, 5, 6, 9];
echo npv_times($test_cf, $test_times2, 0.05); // Output: 10.677272151561
?>

Wrap Up

In this article, we’ve shown you how to calculate net present values using PHP in three cases:

  • A simple case with just two future payments.
  • PHP Net present value of a series of annual cashflows.
  • Net present value of a series of annual cashflows at specified times.

Hope this helps. As always if you have any comments please add them in the comments box below.