commit
message
[PPMT] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-07-11 03:17:19
stats
8 file(s) changed,
111 insertions(+),
7 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 84b2980..f6cffd6 100644
3--- a/DOCS.md
4+++ b/DOCS.md
5@@ -540,6 +540,20 @@
6 @returns {number}
7 @constructor
8 ```
9+
10+### PPMT
11+
12+```
13+ Returns for a given period the payment on the principal for an investment that is based on periodic and constant payments and a constant interest rate.
14+@param rate - The periodic interest rate.
15+@param period - The amortization period.
16+@param periods - The total number of periods during which the annuity is paid.
17+@param present - The present value in the sequence of payments.
18+@param future - [OPTIONAL] - The desired future value. Defaults to 0.
19+@param type - [OPTIONAL] - Indicates how the year is to be calculated. 0 indicates payments are due at end of period, 1 indicates payments are due at beginning of period. Defaults to 0.
20+@returns {number}
21+@constructor
22+```
23 ## Info
24
25
26diff --git a/TODO.md b/TODO.md
27index 5de4a06..a1779a2 100644
28--- a/TODO.md
29+++ b/TODO.md
30@@ -102,7 +102,6 @@ Many of these formulas can be written by allowing the Sheet and Parser to return
31 * ROMAN
32 * SEARCH
33 * SEARCHB
34-* SPLIT
35 * SUBSTITUTE
36 * TEXT
37 * VALUE
38@@ -124,7 +123,6 @@ Many of these formulas can be written by allowing the Sheet and Parser to return
39 * DURATION
40 * FVSCHEDULE
41 * INTRATE
42-* PPMT - Similar to PMT, which is already written.
43 * PRICE
44 * PRICEDISC
45 * PRICEMAT
46diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
47index 282528e..16a8de3 100644
48--- a/dist/Formulas/AllFormulas.js
49+++ b/dist/Formulas/AllFormulas.js
50@@ -135,6 +135,7 @@ exports.MIRR = Financial_1.MIRR;
51 exports.IRR = Financial_1.IRR;
52 exports.IPMT = Financial_1.IPMT;
53 exports.FV = Financial_1.FV;
54+exports.PPMT = Financial_1.PPMT;
55 var Statistical_1 = require("./Statistical");
56 exports.AVERAGE = Statistical_1.AVERAGE;
57 exports.AVERAGEA = Statistical_1.AVERAGEA;
58diff --git a/dist/Formulas/Financial.js b/dist/Formulas/Financial.js
59index ca58c42..7857908 100644
60--- a/dist/Formulas/Financial.js
61+++ b/dist/Formulas/Financial.js
62@@ -675,3 +675,33 @@ var IPMT = function (rate, period, periods, present, future, type) {
63 return interest * rate;
64 };
65 exports.IPMT = IPMT;
66+/**
67+ * Returns for a given period the payment on the principal for an investment that is based on periodic and constant
68+ * payments and a constant interest rate.
69+ * @param rate - The periodic interest rate.
70+ * @param period - The amortization period.
71+ * @param periods - The total number of periods during which the annuity is paid.
72+ * @param present - The present value in the sequence of payments.
73+ * @param future - [OPTIONAL] - The desired future value. Defaults to 0.
74+ * @param type - [OPTIONAL] - Indicates how the year is to be calculated. 0 indicates payments are due at end of
75+ * period, 1 indicates payments are due at beginning of period. Defaults to 0.
76+ * @returns {number}
77+ * @constructor
78+ */
79+var PPMT = function (rate, period, periods, present, future, type) {
80+ ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 4, 6, "PPMT");
81+ rate = TypeConverter_1.TypeConverter.firstValueAsNumber(rate);
82+ period = TypeConverter_1.TypeConverter.firstValueAsNumber(period);
83+ if (period < 1) {
84+ throw new Errors_1.NumError("Function PPMT parameter 2 value is " + period + ", but should be greater than or equal to 1.");
85+ }
86+ periods = TypeConverter_1.TypeConverter.firstValueAsNumber(periods);
87+ if (periods <= 0) {
88+ throw new Errors_1.NumError("Function PPMT parameter 3 value is " + periods + ", but should be greater than 0.");
89+ }
90+ present = TypeConverter_1.TypeConverter.firstValueAsNumber(present);
91+ future = (typeof future === 'undefined') ? 0 : TypeConverter_1.TypeConverter.firstValueAsNumber(future);
92+ type = (typeof type === 'undefined') ? 0 : TypeConverter_1.TypeConverter.firstValueAsNumber(type);
93+ return PMT(rate, periods, present, future, type) - IPMT(rate, period, periods, present, future, type);
94+};
95+exports.PPMT = PPMT;
96diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
97index 1e65db2..3b4c70a 100644
98--- a/src/Formulas/AllFormulas.ts
99+++ b/src/Formulas/AllFormulas.ts
100@@ -138,7 +138,8 @@ import {
101 MIRR,
102 IRR,
103 IPMT,
104- FV
105+ FV,
106+ PPMT
107 } from "./Financial";
108 import {
109 AVERAGE,
110@@ -447,5 +448,6 @@ export {
111 TYPE,
112 COLUMN,
113 ROW,
114- T
115+ T,
116+ PPMT
117 }
118\ No newline at end of file
119diff --git a/src/Formulas/Financial.ts b/src/Formulas/Financial.ts
120index de4757e..9f826c3 100644
121--- a/src/Formulas/Financial.ts
122+++ b/src/Formulas/Financial.ts
123@@ -685,6 +685,37 @@ var IPMT = function (rate, period, periods, present, future?, type?) {
124 return interest * rate;
125 };
126
127+
128+/**
129+ * Returns for a given period the payment on the principal for an investment that is based on periodic and constant
130+ * payments and a constant interest rate.
131+ * @param rate - The periodic interest rate.
132+ * @param period - The amortization period.
133+ * @param periods - The total number of periods during which the annuity is paid.
134+ * @param present - The present value in the sequence of payments.
135+ * @param future - [OPTIONAL] - The desired future value. Defaults to 0.
136+ * @param type - [OPTIONAL] - Indicates how the year is to be calculated. 0 indicates payments are due at end of
137+ * period, 1 indicates payments are due at beginning of period. Defaults to 0.
138+ * @returns {number}
139+ * @constructor
140+ */
141+var PPMT = function (rate, period, periods, present, future?, type?) {
142+ ArgsChecker.checkLengthWithin(arguments, 4, 6, "PPMT");
143+ rate = TypeConverter.firstValueAsNumber(rate);
144+ period = TypeConverter.firstValueAsNumber(period);
145+ if (period < 1) {
146+ throw new NumError("Function PPMT parameter 2 value is " + period + ", but should be greater than or equal to 1.");
147+ }
148+ periods = TypeConverter.firstValueAsNumber(periods);
149+ if (periods <= 0) {
150+ throw new NumError("Function PPMT parameter 3 value is " + periods + ", but should be greater than 0.");
151+ }
152+ present = TypeConverter.firstValueAsNumber(present);
153+ future = (typeof future === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(future);
154+ type = (typeof type === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(type);
155+ return PMT(rate, periods, present, future, type) - IPMT(rate, period, periods, present, future, type);
156+};
157+
158 export {
159 ACCRINT,
160 CUMPRINC,
161@@ -704,5 +735,6 @@ export {
162 MIRR,
163 IRR,
164 IPMT,
165- FV
166+ FV,
167+ PPMT
168 }
169\ No newline at end of file
170diff --git a/tests/Formulas/FinancialTest.ts b/tests/Formulas/FinancialTest.ts
171index 9ca7207..f15617c 100644
172--- a/tests/Formulas/FinancialTest.ts
173+++ b/tests/Formulas/FinancialTest.ts
174@@ -17,7 +17,8 @@ import {
175 MIRR,
176 IRR,
177 IPMT,
178- FV
179+ FV,
180+ PPMT
181 } from "../../src/Formulas/Financial";
182 import {
183 DATE
184@@ -437,4 +438,25 @@ test("FV", function() {
185 catchAndAssertEquals(function() {
186 FV.apply(this, [0.025, 1]);
187 }, ERRORS.NA_ERROR);
188+});
189+
190+
191+test("PPMT", function() {
192+ assertEquals(PPMT(0.025, 4, 24, 50000, 0, 1), -1623.8890945416422);
193+ assertEquals(PPMT(0.010, 3, 24, 33000, 0, 1), -1235.6588292014105);
194+ assertEquals(PPMT(0, 3, 24, 33000, 0, 1), -1375.00);
195+ assertEquals(PPMT(0, 3, 24, 0, 0, 1), 0);
196+ assertEquals(PPMT(0, 1, 3, 100, -1000, 1), 300);
197+ catchAndAssertEquals(function() {
198+ PPMT(0, 0, 24, 33000, 0, 1)
199+ }, ERRORS.NUM_ERROR);
200+ catchAndAssertEquals(function() {
201+ PPMT(0, 4, 0, 33000, 0, 1)
202+ }, ERRORS.NUM_ERROR);
203+ catchAndAssertEquals(function() {
204+ PPMT.apply(this, [0, 4, 0]);
205+ }, ERRORS.NA_ERROR);
206+ catchAndAssertEquals(function() {
207+ PPMT.apply(this, [0, 4, 0, 4000, 1, 1, 1]);
208+ }, ERRORS.NA_ERROR);
209 });
210\ No newline at end of file
211diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
212index 0087a24..90c9d1c 100644
213--- a/tests/SheetFormulaTest.ts
214+++ b/tests/SheetFormulaTest.ts
215@@ -882,6 +882,10 @@ test("Sheet T", function(){
216 assertFormulaEquals('=T("str")', "str");
217 });
218
219+test("Sheet PPMT", function(){
220+ assertFormulaEquals('=PPMT(0, 3, 24, 33000, 0, 1)', -1375.00);
221+});
222+
223 test("Sheet *", function(){
224 assertFormulaEquals('= 10 * 10', 100);
225 assertFormulaEquals('= 10 * 0', 0);