spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
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);