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+});