commit
message
[FV] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-06-30 14:26:12
stats
8 file(s) changed,
108 insertions(+),
29 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
tests/SheetFormulaTest.ts
1diff --git a/DOCS.md b/DOCS.md
2index 0fbc9b5..6772131 100644
3--- a/DOCS.md
4+++ b/DOCS.md
5@@ -394,6 +394,19 @@
6 @constructor
7 ```
8
9+### FV
10+
11+```
12+ Returns the future value of an investment based on periodic, constant payments and a constant interest rate.
13+@param rate - The rate of periodic interest.
14+@param periods - The total number of periods.
15+@param payment - The annuity paid regularly per period
16+@param value - [OPTIONAL] - The present cash value of an investment.
17+@param type - [OPTIONAL] - Defines whether the payment is due at the beginning (1) or the end (0) of a period.
18+@returns {number}
19+@constructor
20+```
21+
22 ### CUMPRINC
23
24 ```
25diff --git a/TODO.md b/TODO.md
26index fa9c4d7..c381230 100644
27--- a/TODO.md
28+++ b/TODO.md
29@@ -137,7 +137,6 @@ For example 64 tbs to a qt.
30 * COUPPCD
31 * DISC
32 * DURATION
33-* FV - already written as a private function, needs to be re-written.
34 * FVSCHEDULE
35 * INTRATE
36 * PPMT - Similar to PMT, which is already written.
37diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
38index 27a7231..df51afe 100644
39--- a/dist/Formulas/AllFormulas.js
40+++ b/dist/Formulas/AllFormulas.js
41@@ -118,6 +118,7 @@ exports.NOMINAL = Financial_1.NOMINAL;
42 exports.MIRR = Financial_1.MIRR;
43 exports.IRR = Financial_1.IRR;
44 exports.IPMT = Financial_1.IPMT;
45+exports.FV = Financial_1.FV;
46 var Statistical_1 = require("./Statistical");
47 exports.AVERAGE = Statistical_1.AVERAGE;
48 exports.AVERAGEA = Statistical_1.AVERAGEA;
49diff --git a/dist/Formulas/Financial.js b/dist/Formulas/Financial.js
50index 886a6f5..ca58c42 100644
51--- a/dist/Formulas/Financial.js
52+++ b/dist/Formulas/Financial.js
53@@ -241,23 +241,39 @@ var PMT = function (rate, periods, presentValue, futureValue, endOrBeginning) {
54 return -result;
55 };
56 exports.PMT = PMT;
57-// TODO: Convert to real formula FV
58-function fv(rate, periods, payment, value, type) {
59+/**
60+ * Returns the future value of an investment based on periodic, constant payments and a constant interest rate.
61+ * @param rate - The rate of periodic interest.
62+ * @param periods - The total number of periods.
63+ * @param payment - The annuity paid regularly per period
64+ * @param value - [OPTIONAL] - The present cash value of an investment.
65+ * @param type - [OPTIONAL] - Defines whether the payment is due at the beginning (1) or the end (0) of a period.
66+ * @returns {number}
67+ * @constructor
68+ */
69+var FV = function (rate, periods, payment, value, type) {
70+ ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 3, 5, "FV");
71+ rate = TypeConverter_1.TypeConverter.firstValueAsNumber(rate);
72+ periods = TypeConverter_1.TypeConverter.firstValueAsNumber(periods);
73+ payment = TypeConverter_1.TypeConverter.firstValueAsNumber(payment);
74+ value = (typeof value === 'undefined') ? 0 : TypeConverter_1.TypeConverter.firstValueAsNumber(value);
75+ type = (typeof type === 'undefined') ? 0 : TypeConverter_1.TypeConverter.firstValueAsNumber(type);
76 var result;
77 if (rate === 0) {
78 result = value + payment * periods;
79 }
80 else {
81 var term = Math.pow(1 + rate, periods);
82- if (type) {
83- result = value * term + payment * (1 + rate) * (term - 1.0) / rate;
84+ if (type === 0) {
85+ result = value * term + payment * (term - 1) / rate;
86 }
87 else {
88- result = value * term + payment * (term - 1) / rate;
89+ result = value * term + payment * (1 + rate) * (term - 1.0) / rate;
90 }
91 }
92 return -result;
93-}
94+};
95+exports.FV = FV;
96 /**
97 * Calculates the cumulative principal paid over a range of payment periods for an investment based on constant-amount
98 * periodic payments and a constant interest rate.
99@@ -302,10 +318,10 @@ var CUMPRINC = function (rate, numberOfPeriods, presentValue, firstPeriod, lastP
100 }
101 for (var i = start; i <= end; i++) {
102 if (type) {
103- principal += payment - (fv(rate, i - 2, payment, value, 1) - payment) * rate;
104+ principal += payment - (FV(rate, i - 2, payment, value, 1) - payment) * rate;
105 }
106 else {
107- principal += payment - fv(rate, i - 1, payment, value, 0) * rate;
108+ principal += payment - FV(rate, i - 1, payment, value, 0) * rate;
109 }
110 }
111 return principal;
112@@ -355,10 +371,10 @@ var CUMIPMT = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPe
113 }
114 for (var i = start; i <= end; i++) {
115 if (type) {
116- interest += fv(rate, i - 2, payment, value, 1) - payment;
117+ interest += FV(rate, i - 2, payment, value, 1) - payment;
118 }
119 else {
120- interest += fv(rate, i - 1, payment, value, 0);
121+ interest += FV(rate, i - 1, payment, value, 0);
122 }
123 }
124 interest *= rate;
125@@ -650,10 +666,10 @@ var IPMT = function (rate, period, periods, present, future, type) {
126 }
127 else {
128 if (type === 1) {
129- interest = fv(rate, period - 2, payment, present, 1) - payment;
130+ interest = FV(rate, period - 2, payment, present, 1) - payment;
131 }
132 else {
133- interest = fv(rate, period - 1, payment, present, 0);
134+ interest = FV(rate, period - 1, payment, present, 0);
135 }
136 }
137 return interest * rate;
138diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
139index d16b401..b4385c9 100644
140--- a/src/Formulas/AllFormulas.ts
141+++ b/src/Formulas/AllFormulas.ts
142@@ -121,7 +121,8 @@ import {
143 NOMINAL,
144 MIRR,
145 IRR,
146- IPMT
147+ IPMT,
148+ FV
149 } from "./Financial";
150 import {
151 AVERAGE,
152@@ -381,5 +382,6 @@ export {
153 NOMINAL,
154 MIRR,
155 IRR,
156- IPMT
157+ IPMT,
158+ FV
159 }
160\ No newline at end of file
161diff --git a/src/Formulas/Financial.ts b/src/Formulas/Financial.ts
162index 91ebb05..de4757e 100644
163--- a/src/Formulas/Financial.ts
164+++ b/src/Formulas/Financial.ts
165@@ -254,21 +254,37 @@ var PMT = function (rate, periods, presentValue, futureValue?, endOrBeginning?)
166 return -result;
167 };
168
169-// TODO: Convert to real formula FV
170-function fv(rate, periods, payment, value, type) {
171+
172+/**
173+ * Returns the future value of an investment based on periodic, constant payments and a constant interest rate.
174+ * @param rate - The rate of periodic interest.
175+ * @param periods - The total number of periods.
176+ * @param payment - The annuity paid regularly per period
177+ * @param value - [OPTIONAL] - The present cash value of an investment.
178+ * @param type - [OPTIONAL] - Defines whether the payment is due at the beginning (1) or the end (0) of a period.
179+ * @returns {number}
180+ * @constructor
181+ */
182+var FV = function (rate, periods, payment, value?, type?) {
183+ ArgsChecker.checkLengthWithin(arguments, 3, 5, "FV");
184+ rate = TypeConverter.firstValueAsNumber(rate);
185+ periods = TypeConverter.firstValueAsNumber(periods);
186+ payment = TypeConverter.firstValueAsNumber(payment);
187+ value = (typeof value === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(value);
188+ type = (typeof type === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(type);
189 var result;
190 if (rate === 0) {
191 result = value + payment * periods;
192 } else {
193 var term = Math.pow(1 + rate, periods);
194- if (type) {
195- result = value * term + payment * (1 + rate) * (term - 1.0) / rate;
196- } else {
197+ if (type === 0) {
198 result = value * term + payment * (term - 1) / rate;
199+ } else {
200+ result = value * term + payment * (1 + rate) * (term - 1.0) / rate;
201 }
202 }
203 return -result;
204-}
205+};
206
207 /**
208 * Calculates the cumulative principal paid over a range of payment periods for an investment based on constant-amount
209@@ -314,9 +330,9 @@ var CUMPRINC = function (rate, numberOfPeriods, presentValue, firstPeriod, lastP
210 }
211 for (var i = start; i <= end; i++) {
212 if (type) {
213- principal += payment - (fv(rate, i - 2, payment, value, 1) - payment) * rate;
214+ principal += payment - (FV(rate, i - 2, payment, value, 1) - payment) * rate;
215 } else {
216- principal += payment - fv(rate, i - 1, payment, value, 0) * rate;
217+ principal += payment - FV(rate, i - 1, payment, value, 0) * rate;
218 }
219 }
220 return principal;
221@@ -366,9 +382,9 @@ var CUMIPMT = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPe
222 }
223 for (var i = start; i <= end; i++) {
224 if (type) {
225- interest += fv(rate, i - 2, payment, value, 1) - payment;
226+ interest += FV(rate, i - 2, payment, value, 1) - payment;
227 } else {
228- interest += fv(rate, i - 1, payment, value, 0);
229+ interest += FV(rate, i - 1, payment, value, 0);
230 }
231 }
232 interest *= rate;
233@@ -661,9 +677,9 @@ var IPMT = function (rate, period, periods, present, future?, type?) {
234 }
235 } else {
236 if (type === 1) {
237- interest = fv(rate, period - 2, payment, present, 1) - payment;
238+ interest = FV(rate, period - 2, payment, present, 1) - payment;
239 } else {
240- interest = fv(rate, period - 1, payment, present, 0);
241+ interest = FV(rate, period - 1, payment, present, 0);
242 }
243 }
244 return interest * rate;
245@@ -687,5 +703,6 @@ export {
246 NOMINAL,
247 MIRR,
248 IRR,
249- IPMT
250+ IPMT,
251+ FV
252 }
253\ No newline at end of file
254diff --git a/tests/Formulas/FinancialTest.ts b/tests/Formulas/FinancialTest.ts
255index 3cfe383..6153da6 100644
256--- a/tests/Formulas/FinancialTest.ts
257+++ b/tests/Formulas/FinancialTest.ts
258@@ -16,7 +16,8 @@ import {
259 NOMINAL,
260 MIRR,
261 IRR,
262- IPMT
263+ IPMT,
264+ FV
265 } from "../../src/Formulas/Financial";
266 import {
267 DATE
268@@ -410,4 +411,18 @@ test("IPMT", function() {
269 catchAndAssertEquals(function() {
270 IPMT.apply(this, [0.025, 1, 66, 25000, 0, 0, 1]);
271 }, ERRORS.NA_ERROR);
272+});
273+
274+
275+test("FV", function() {
276+ assertEquals(FV(0.025, 1, 66, 25000, 0), -25690.999999999996);
277+ assertEquals(FV(0.025, 1, 66, 25000), -25690.999999999996);
278+ assertEquals(FV(0.05, 1, 66, 25000), -26316);
279+ assertEquals(FV(0.025, 1, 66, 25000, 1), -25692.649999999998);
280+ catchAndAssertEquals(function() {
281+ FV.apply(this, [0.025, 1, 66, 25000, 1, 4]);
282+ }, ERRORS.NA_ERROR);
283+ catchAndAssertEquals(function() {
284+ FV.apply(this, [0.025, 1]);
285+ }, ERRORS.NA_ERROR);
286 });
287\ No newline at end of file
288diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
289index 3180fe6..c1d2efa 100644
290--- a/tests/SheetFormulaTest.ts
291+++ b/tests/SheetFormulaTest.ts
292@@ -751,6 +751,10 @@ test("Sheet IPMT", function(){
293 assertFormulaEquals('=IPMT(0.025, 1, 66, 25000)', -625);
294 });
295
296+test("Sheet FV", function(){
297+ assertFormulaEquals('=FV(0.05, 1, 66, 25000)', -26316);
298+});
299+
300 test("Sheet *", function(){
301 assertFormulaEquals('= 10 * 10', 100);
302 assertFormulaEquals('= 10 * 0', 0);