commit
message
[ACCRINT] Filling out tests, adding documentation.
author
Ben Vogt <[email protected]>
date
2017-04-29 21:37:29
stats
2 file(s) changed,
30 insertions(+),
0 deletions(-)
files
src/RawFormulas/Financial.ts
tests/FormulasTest.ts
1diff --git a/src/RawFormulas/Financial.ts b/src/RawFormulas/Financial.ts
2index c36a319..2823234 100644
3--- a/src/RawFormulas/Financial.ts
4+++ b/src/RawFormulas/Financial.ts
5@@ -364,6 +364,9 @@ var CUMIPMT = function (...values) : number {
6
7 /**
8 * Calculates the accrued interest of a security that has periodic payments.
9+ * WARNING: This function has been implemented to specifications as outlined in Google Spreadsheets, LibreOffice, and
10+ * OpenOffice. It functions much the same as MSExcel's ACCRINT, but there are several key differences. Below are links
11+ * to illustrate the differences. Please see the source code for more information on differences.
12 *
13 * Links:
14 * * https://quant.stackexchange.com/questions/7040/whats-the-algorithm-behind-excels-accrint
15@@ -383,6 +386,8 @@ var CUMIPMT = function (...values) : number {
16 * 0 or omitted = US (NASD) 30/360, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 = European 30/360.
17 * @returns {number}
18 * @constructor
19+ * TODO: This function is based off of the open-source versions I was able to dig up online. We should implement a
20+ * TODO: second version that is closer to what MSExcel does and is named something like `ACCRINT.MS`.
21 */
22 var ACCRINT = function (...values) {
23 ArgsChecker.checkLengthWithin(values, 6, 7);
24@@ -391,7 +396,15 @@ var ACCRINT = function (...values) {
25 // In MSE, there is a 7th (zero-indexed-6th) param that indicates the calculation-method to use, which indicates
26 // weather the total accrued interest starting at the first_intrest date, instead of the issue date.
27 var firstPayment = TypeCaster.firstValueAsExcelDate(values[1]);
28+ if (firstPayment.toNumber() < 0) {
29+ throw new NumError("Function ACCRINT parameter 2 value is " + firstPayment.toNumber()
30+ + ". It should be greater than 0.");
31+ }
32 var settlement = TypeCaster.firstValueAsExcelDate(values[2]);
33+ if (issue.toNumber() > settlement.toNumber()) {
34+ throw new NumError("Function ACCRINT parameter 1 (" + issue.toString()
35+ + ") should be on or before Function ACCRINT parameter 3 (" + settlement.toString() + ").")
36+ }
37 var rate = TypeCaster.firstValueAsNumber(values[3]);
38 var redemption = TypeCaster.firstValueAsNumber(values[4]);// "par"
39 // The frequency parameter also does not affect the resulting value of the formula in the GS implementation.
40diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
41index 10793c2..6f38207 100644
42--- a/tests/FormulasTest.ts
43+++ b/tests/FormulasTest.ts
44@@ -50,11 +50,26 @@ assertEquals(ACCRINT(10000, 1, 20000, 0.1, 1000, 4, 1), 2737.8507871321012); //
45 assertEquals(ACCRINT(10000, 1, 20000, 0.1, 1000, 4, 2), 2777.777777777778); // ms, gs: 2737.777778 (1.46% err)
46 assertEquals(ACCRINT(10000, 1, 20000, 0.1, 1000, 4, 3), 2739.72602739726); //ms, gs: 2737.60274 (0.077% err)
47 assertEquals(ACCRINT(10000, 1, 20000, 0.1, 1000, 4, 4), 2737.5);
48+assertEquals(ACCRINT(1, 44, "1461", "0.1", [1000], [1]), 400);
49+assertEquals(ACCRINT(1, 2, 1461, 0.1, 1000, 1), 400);
50 assertEquals(ACCRINT(1, 2, 1461, 0.1, 1000, 1, 0), 400);
51 assertEquals(ACCRINT(1, 2, 1461, 0.1, 1000, 1, 1), 400);
52 assertEquals(ACCRINT(1, 2, 1461, 0.1, 1000, 1, 2), 405.55555555555554); // gs: 400
53 assertEquals(ACCRINT(1, 2, 1461, 0.1, 1000, 1, 3), 400); // gs: 399.6575342
54 assertEquals(ACCRINT(1, 2, 1461, 0.1, 1000, 1, 4), 400);
55+catchAndAssertEquals(function() {
56+ ACCRINT(1, -1, 100, 0.1, 1000, 1, 4);
57+}, ERRORS.NUM_ERROR);
58+catchAndAssertEquals(function() {
59+ ACCRINT(100, 2, 1, 0.1, 1000, 1, 4);
60+}, ERRORS.NUM_ERROR);
61+catchAndAssertEquals(function() {
62+ ACCRINT(100, 2, 1, 0.1, 1000);
63+}, ERRORS.NA_ERROR);
64+catchAndAssertEquals(function() {
65+ ACCRINT(1, 2, 1461, 0.1, 1000, 1, 1, 1);
66+}, ERRORS.NA_ERROR);
67+
68
69
70 // Test ACOS