spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[NPV] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-06-27 02:46:30
stats
7 file(s) changed, 93 insertions(+), 6 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Financial.js
src/Formulas/AllFormulas.ts
src/Formulas/Financial.ts
tests/Formulas/FinancialTest.ts
  1diff --git a/DOCS.md b/DOCS.md
  2index 62111bc..3f5aa20 100644
  3--- a/DOCS.md
  4+++ b/DOCS.md
  5@@ -459,6 +459,16 @@
  6 @returns {number} 
  7 @constructor
  8 ```
  9+
 10+### NPV 
 11+
 12+```
 13+  Returns the net present value of an investment based on a series of periodic cash flows and a discount rate. 
 14+@param rate - The discount rate for a period. 
 15+@param values - The values representing deposits or withdrawals. 
 16+@returns {number} 
 17+@constructor TODO: This function can return results that are prone to floating point precision errors.
 18+```
 19 ## Info
 20 
 21 
 22diff --git a/TODO.md b/TODO.md
 23index 1679a09..c8e65a1 100644
 24--- a/TODO.md
 25+++ b/TODO.md
 26@@ -145,7 +145,6 @@ For example 64 tbs to a qt.
 27 * MIRR
 28 * NOMINAL
 29 * NPER
 30-* NPV
 31 * PPMT - Similar to PMT, which is already written.
 32 * PRICE
 33 * PRICEDISC
 34diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
 35index 725c4e3..f4836ab 100644
 36--- a/dist/Formulas/AllFormulas.js
 37+++ b/dist/Formulas/AllFormulas.js
 38@@ -112,6 +112,7 @@ exports.DOLLARFR = Financial_1.DOLLARFR;
 39 exports.EFFECT = Financial_1.EFFECT;
 40 exports.SYD = Financial_1.SYD;
 41 exports.SLN = Financial_1.SLN;
 42+exports.NPV = Financial_1.NPV;
 43 var Statistical_1 = require("./Statistical");
 44 exports.AVERAGE = Statistical_1.AVERAGE;
 45 exports.AVERAGEA = Statistical_1.AVERAGEA;
 46diff --git a/dist/Formulas/Financial.js b/dist/Formulas/Financial.js
 47index ff726c0..34699bb 100644
 48--- a/dist/Formulas/Financial.js
 49+++ b/dist/Formulas/Financial.js
 50@@ -4,6 +4,7 @@ var ArgsChecker_1 = require("../Utilities/ArgsChecker");
 51 var TypeConverter_1 = require("../Utilities/TypeConverter");
 52 var Errors_1 = require("../Errors");
 53 var Date_1 = require("./Date");
 54+var Filter_1 = require("../Utilities/Filter");
 55 /**
 56  * Calculates the depreciation of an asset for a specified period using the double-declining balance method.
 57  * @param cost - The initial cost of the asset.
 58@@ -463,3 +464,33 @@ var SLN = function (cost, salvage, life) {
 59     return (cost - salvage) / life;
 60 };
 61 exports.SLN = SLN;
 62+/**
 63+ * Returns the net present value of an investment based on a series of periodic cash flows and a discount rate.
 64+ * @param rate - The discount rate for a period.
 65+ * @param values - The values representing deposits or withdrawals.
 66+ * @returns {number}
 67+ * @constructor
 68+ * TODO: This function can return results that are prone to floating point precision errors.
 69+ */
 70+var NPV = function (rate) {
 71+    var values = [];
 72+    for (var _i = 1; _i < arguments.length; _i++) {
 73+        values[_i - 1] = arguments[_i];
 74+    }
 75+    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 2, "SYD");
 76+    var range = Filter_1.Filter.flattenAndThrow(values).map(function (value) {
 77+        try {
 78+            return TypeConverter_1.TypeConverter.valueToNumber(value);
 79+        }
 80+        catch (e) {
 81+            throw new Errors_1.ValueError("Function NPV parameter 8 expects number values. But '" + value + "' is " + (typeof value)
 82+                + " and cannot be coerced to a number.");
 83+        }
 84+    });
 85+    var value = 0;
 86+    for (var j = 0; j < range.length; j++) {
 87+        value += range[j] / Math.pow(1 + rate, j);
 88+    }
 89+    return value;
 90+};
 91+exports.NPV = NPV;
 92diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
 93index a38810e..35b048d 100644
 94--- a/src/Formulas/AllFormulas.ts
 95+++ b/src/Formulas/AllFormulas.ts
 96@@ -115,7 +115,8 @@ import {
 97   DOLLARFR,
 98   EFFECT,
 99   SYD,
100-  SLN
101+  SLN,
102+  NPV
103 } from "./Financial";
104 import {
105   AVERAGE,
106@@ -369,5 +370,6 @@ export {
107   INTERCEPT,
108   FORECAST,
109   SYD,
110-  SLN
111+  SLN,
112+  NPV
113 }
114\ No newline at end of file
115diff --git a/src/Formulas/Financial.ts b/src/Formulas/Financial.ts
116index 87b9f9f..448f1c4 100644
117--- a/src/Formulas/Financial.ts
118+++ b/src/Formulas/Financial.ts
119@@ -7,11 +7,12 @@ import {
120 } from "../Utilities/TypeConverter";
121 import {
122   NumError,
123-  DivZeroError
124+  DivZeroError, ValueError
125 } from "../Errors"
126 import {
127   YEARFRAC
128 } from "./Date";
129+import {Filter} from "../Utilities/Filter";
130 
131 
132 /**
133@@ -477,6 +478,32 @@ var SLN = function (cost, salvage, life) {
134 };
135 
136 
137+/**
138+ * Returns the net present value of an investment based on a series of periodic cash flows and a discount rate.
139+ * @param rate - The discount rate for a period.
140+ * @param values - The values representing deposits or withdrawals.
141+ * @returns {number}
142+ * @constructor
143+ * TODO: This function can return results that are prone to floating point precision errors.
144+ */
145+var NPV = function (rate, ...values) {
146+  ArgsChecker.checkAtLeastLength(arguments, 2, "SYD");
147+  var range = Filter.flattenAndThrow(values).map(function (value) {
148+    try {
149+      return TypeConverter.valueToNumber(value);
150+    } catch (e) {
151+      throw new ValueError("Function NPV parameter 8 expects number values. But '" + value + "' is " + (typeof value)
152+          + " and cannot be coerced to a number.")
153+    }
154+  });
155+  var value = 0;
156+  for (var j = 0; j < range.length; j++) {
157+    value += range[j] / Math.pow(1 + rate, j);
158+  }
159+  return value;
160+};
161+
162+
163 export {
164   ACCRINT,
165   CUMPRINC,
166@@ -489,5 +516,6 @@ export {
167   EFFECT,
168   PMT,
169   SYD,
170-  SLN
171+  SLN,
172+  NPV
173 }
174\ No newline at end of file
175diff --git a/tests/Formulas/FinancialTest.ts b/tests/Formulas/FinancialTest.ts
176index b4fce60..222f1a9 100644
177--- a/tests/Formulas/FinancialTest.ts
178+++ b/tests/Formulas/FinancialTest.ts
179@@ -10,7 +10,8 @@ import {
180   EFFECT,
181   PMT,
182   SYD,
183-  SLN
184+  SLN,
185+  NPV
186 } from "../../src/Formulas/Financial";
187 import {
188   DATE
189@@ -306,3 +307,17 @@ test("SLN", function() {
190     SLN.apply(this, [10, 10, 10, 10]);
191   }, ERRORS.NA_ERROR);
192 });
193+
194+
195+test("NPV", function() {
196+  assertEquals(NPV(0.01, 200, 100, 22, 99.1), 416.7618977366809);
197+  assertEquals(NPV(0.01, 200, -100, 1.4, -100.2, 22, 99.1, "100"), 214.7457214025921);
198+  assertEquals(NPV(0.01, 200, -100, 1.4, -100.2, 22, 99.1), 120.54119787717146);
199+  assertEquals(NPV(0.01, 200, 100, 22, 99000), 96409.00105891385);
200+  catchAndAssertEquals(function() {
201+    NPV.apply(this, [10]);
202+  }, ERRORS.NA_ERROR);
203+  catchAndAssertEquals(function() {
204+    NPV.apply(this, [10, 10, 20, "str"]);
205+  }, ERRORS.VALUE_ERROR);
206+});