sec-edgar-api 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/build/services/DocumentParser/XMLParser.d.ts +5 -20
- package/build/services/DocumentParser/XMLParser.js +118 -122
- package/build/services/DocumentParser/parsers/index.d.ts +3 -5
- package/build/services/DocumentParser/parsers/index.js +3 -5
- package/build/services/DocumentParser/parsers/parse-form-13g.js +2 -2
- package/build/services/DocumentParser/parsers/parse-form-4.d.ts +1 -6
- package/build/services/DocumentParser/parsers/parse-form-4.js +204 -134
- package/build/services/DocumentParser/parsers/parse-form-def14a.d.ts +2 -1
- package/build/services/DocumentParser/parsers/parse-form-def14a.js +106 -157
- package/build/services/ReportBuilder/FactFiscalCalculator.d.ts +4 -0
- package/build/services/ReportBuilder/FactFiscalCalculator.js +4 -0
- package/build/services/ReportBuilder/FactPeriodResolver.d.ts +6 -2
- package/build/services/ReportBuilder/FactPeriodResolver.js +6 -1
- package/build/services/ReportBuilder/FactRecordBuilder.d.ts +4 -1
- package/build/services/ReportBuilder/FactRecordBuilder.js +26 -4
- package/build/services/ReportBuilder/FactSplitAdjuster.d.ts +12 -1
- package/build/services/ReportBuilder/FactSplitAdjuster.js +41 -19
- package/build/services/ReportBuilder/ReportBuilder.d.ts +3 -0
- package/build/services/ReportBuilder/ReportBuilder.js +33 -13
- package/build/services/ReportParser/ReportParser.d.ts +3 -3
- package/build/services/ReportParser/ReportParser.js +7 -4
- package/build/services/ReportParser/ReportRawParser.d.ts +3 -9
- package/build/services/ReportParser/ReportRawParser.js +5 -33
- package/build/services/ReportParser/ReportWrapper.js +2 -0
- package/build/services/ReportParser/resolvers/resolve-fiscal-year-cumulative-properties.js +2 -1
- package/build/services/SecEdgarApi/SecEdgarApi.d.ts +45 -84
- package/build/services/SecEdgarApi/SecEdgarApi.js +108 -246
- package/build/types/index.d.ts +2 -2
- package/build/types/index.js +2 -2
- package/build/types/parsed-filings.type.d.ts +5 -144
- package/build/types/report-raw.type.d.ts +3 -1
- package/build/types/report-translated.type.d.ts +4 -1
- package/build/types/submission.type.d.ts +2 -3
- package/build/util/key-translations.js +5 -1
- package/package.json +2 -5
- package/build/services/DocumentParser/HtmlTableExtractor.d.ts +0 -41
- package/build/services/DocumentParser/HtmlTableExtractor.js +0 -408
- package/build/services/DocumentParser/parsers/parse-current-filings.d.ts +0 -3
- package/build/services/DocumentParser/parsers/parse-current-filings.js +0 -98
- package/build/services/DocumentParser/parsers/parse-form-13f.d.ts +0 -6
- package/build/services/DocumentParser/parsers/parse-form-13f.js +0 -91
- package/build/services/ReportParser/FactItem.d.ts +0 -66
- package/build/services/ReportParser/FactItem.js +0 -50
- package/build/services/ReportParser/FactItemFactory.d.ts +0 -22
- package/build/services/ReportParser/FactItemFactory.js +0 -150
- package/build/services/ReportParser/FactIterator.d.ts +0 -18
- package/build/services/ReportParser/FactIterator.js +0 -35
- package/build/services/ReportParser/FactSplitMap.d.ts +0 -16
- package/build/services/ReportParser/FactSplitMap.js +0 -101
- package/build/types/current-filings-xml.type.d.ts +0 -74
- package/build/types/current-filings-xml.type.js +0 -6
- package/build/types/current-filings.type.d.ts +0 -44
- package/build/types/current-filings.type.js +0 -2
- package/build/types/form-13f-xml.type.d.ts +0 -105
- package/build/types/form-13f-xml.type.js +0 -2
- package/build/types/form-4-xml.type.d.ts +0 -132
- package/build/types/form-4-xml.type.js +0 -2
|
@@ -1,177 +1,126 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseFormDef14a = void 0;
|
|
4
|
-
var
|
|
4
|
+
var XMLParser_1 = require("../XMLParser");
|
|
5
5
|
/**
|
|
6
6
|
* Form DEF 14a - Proxy Statement
|
|
7
7
|
*
|
|
8
8
|
* example at https://www.sec.gov/Archives/edgar/data/320193/000130817923000019/laap2023_def14a.htm
|
|
9
9
|
*/
|
|
10
|
-
function parseFormDef14a(params) {
|
|
11
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
10
|
+
function parseFormDef14a(params, xmlParser) {
|
|
11
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
12
|
+
if (xmlParser === void 0) { xmlParser = new XMLParser_1.default(); }
|
|
12
13
|
var xml = params.xml;
|
|
13
|
-
var
|
|
14
|
-
var tables =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return
|
|
14
|
+
var doc = xmlParser.getDocumentNode({ xml: xml });
|
|
15
|
+
var tables = doc.parseTables();
|
|
16
|
+
var usedTables = [];
|
|
17
|
+
var compensationArr = [];
|
|
18
|
+
var holderArr = [];
|
|
19
|
+
var findCompensationTables = function (type) {
|
|
20
|
+
var tablesFound = tables.filter(function (table) {
|
|
21
|
+
var _a, _b, _c, _d, _e;
|
|
22
|
+
var hasNameRow = (_a = table.rows[0]) === null || _a === void 0 ? void 0 : _a.some(function (col) { return "".concat(col).toLowerCase().includes('name'); });
|
|
23
|
+
var hasTotalRow = (_b = table.rows[0]) === null || _b === void 0 ? void 0 : _b.some(function (col) { return "".concat(col).toLowerCase().includes('total'); });
|
|
24
|
+
var hasAwardRow = (_c = table.rows[0]) === null || _c === void 0 ? void 0 : _c.some(function (col) { return "".concat(col).toLowerCase().includes('award'); });
|
|
25
|
+
var titleLower = table.title.toLowerCase();
|
|
26
|
+
var textLower = (_e = (_d = table.textBefore) === null || _d === void 0 ? void 0 : _d.toLowerCase()) !== null && _e !== void 0 ? _e : '';
|
|
27
|
+
var isTitleMatch = titleLower.includes(type) && titleLower.includes('compensation');
|
|
28
|
+
var isTextMatch = hasNameRow && hasTotalRow && hasAwardRow && textLower.includes(type);
|
|
29
|
+
return (isTitleMatch || isTextMatch) && !usedTables.includes(table);
|
|
29
30
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
31
|
+
tablesFound.forEach(function (t) { return usedTables.push(t); });
|
|
32
|
+
return tablesFound;
|
|
33
|
+
};
|
|
34
|
+
var tablesHolder = tables.filter(function (table) {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
var hasNameRow = (_a = table.rows[0]) === null || _a === void 0 ? void 0 : _a.some(function (col) { return "".concat(col).toLowerCase().includes('name'); });
|
|
37
|
+
var hasPercent = (_b = table.rows[0]) === null || _b === void 0 ? void 0 : _b.some(function (col) { return "".concat(col).toLowerCase().includes('percent'); });
|
|
38
|
+
var titleLower = table.title.toLowerCase();
|
|
39
|
+
var isTitleMatch = titleLower.includes('security') && titleLower.includes('owner') && titleLower.includes('beneficial');
|
|
40
|
+
return isTitleMatch && hasNameRow && hasPercent;
|
|
41
|
+
});
|
|
42
|
+
var foundHoldersKeys = new Set();
|
|
43
|
+
var _loop_1 = function (table) {
|
|
44
|
+
var header = table.rows[0];
|
|
45
|
+
var getIndex = function (search) { return header.findIndex(function (col) { return "".concat(col).toLowerCase().includes(search); }); };
|
|
46
|
+
var indexName = getIndex('name');
|
|
47
|
+
var indexPercent = getIndex('percent');
|
|
48
|
+
var indexShares = (_b = (_a = table.rows[1]) === null || _a === void 0 ? void 0 : _a.findIndex(function (col) { return typeof col === 'number' && !isNaN(col); })) !== null && _b !== void 0 ? _b : -1;
|
|
49
|
+
for (var i = 1; i < table.rows.length; i++) {
|
|
50
|
+
for (var i_1 = 1; i_1 < table.rows.length; i_1++) {
|
|
51
|
+
var nameVal = (_d = (_c = table.rows[i_1]) === null || _c === void 0 ? void 0 : _c[indexName]) !== null && _d !== void 0 ? _d : null;
|
|
52
|
+
if (typeof nameVal !== 'string')
|
|
53
|
+
continue;
|
|
54
|
+
var nameParts = nameVal.split('}}');
|
|
55
|
+
var namePartsSpaces = nameVal.split(' ');
|
|
56
|
+
var position = (_e = nameParts[1]) !== null && _e !== void 0 ? _e : namePartsSpaces.slice(2, namePartsSpaces.length).join(' ');
|
|
57
|
+
var name_1 = nameParts[1] ? nameParts[0] : namePartsSpaces.slice(0, 2).join(' ');
|
|
58
|
+
var holder = {
|
|
59
|
+
name: name_1.replace(/{{/g, '').replace(/}}/g, '').trim(),
|
|
60
|
+
position: position.replace(/{{/g, '').replace(/}}/g, '').trim() || null,
|
|
61
|
+
shares: Number((_f = table.rows[i_1]) === null || _f === void 0 ? void 0 : _f[indexShares]) || null,
|
|
62
|
+
percentOfClass: String((_g = table.rows[i_1]) === null || _g === void 0 ? void 0 : _g[indexPercent]) || null,
|
|
63
|
+
};
|
|
64
|
+
var key = "".concat(holder.name).concat(holder.position).concat(holder.shares).concat(holder.percentOfClass);
|
|
65
|
+
if (!foundHoldersKeys.has(key))
|
|
66
|
+
holderArr.push(holder);
|
|
67
|
+
foundHoldersKeys.add(key);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
for (var _i = 0, tablesHolder_1 = tablesHolder; _i < tablesHolder_1.length; _i++) {
|
|
72
|
+
var table = tablesHolder_1[_i];
|
|
73
|
+
_loop_1(table);
|
|
74
|
+
}
|
|
75
|
+
for (var _t = 0, _u = ['director', 'executive', 'summary']; _t < _u.length; _t++) {
|
|
76
|
+
var type = _u[_t];
|
|
77
|
+
var _loop_2 = function (table) {
|
|
78
|
+
if (!table)
|
|
79
|
+
return "continue";
|
|
80
|
+
var header = table.rows[0];
|
|
81
|
+
var getIndex = function (search) { return header.findIndex(function (col) { return "".concat(col).toLowerCase().includes(search); }); };
|
|
82
|
+
var indexName = getIndex('name');
|
|
83
|
+
var indexYear = getIndex('year');
|
|
53
84
|
var indexSalary = getIndex('salary') === -1 ? getIndex('cash') : getIndex('salary');
|
|
54
85
|
var indexBonus = getIndex('bonus');
|
|
55
86
|
var indexStock = getIndex('stock');
|
|
56
|
-
var
|
|
87
|
+
var indexNonEquity = getIndex('non-equity') === -1 ? getIndex('option') : getIndex('non-equity');
|
|
57
88
|
var indexOther = getIndex('other');
|
|
58
89
|
var indexTotal = getIndex('total');
|
|
59
|
-
var
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
90
|
+
var defaultPosition = {
|
|
91
|
+
director: 'Director',
|
|
92
|
+
executive: 'Executive',
|
|
93
|
+
summary: null,
|
|
94
|
+
}[type];
|
|
95
|
+
for (var i = 1; i < table.rows.length; i++) {
|
|
96
|
+
var nameVal = (_j = (_h = table.rows[i]) === null || _h === void 0 ? void 0 : _h[indexName]) !== null && _j !== void 0 ? _j : null;
|
|
97
|
+
if (typeof nameVal !== 'string')
|
|
98
|
+
continue;
|
|
99
|
+
var nameParts = nameVal.split('}}');
|
|
100
|
+
var namePartsSpaces = nameVal.split(' ');
|
|
101
|
+
var position = (_k = nameParts[1]) !== null && _k !== void 0 ? _k : namePartsSpaces.slice(2, namePartsSpaces.length).join(' ');
|
|
102
|
+
var name_2 = nameParts[1] ? nameParts[0] : namePartsSpaces.slice(0, 2).join(' ');
|
|
103
|
+
var compensation = {
|
|
104
|
+
name: name_2.replace(/{{/g, '').replace(/}}/g, '').trim(),
|
|
105
|
+
position: position.replace(/{{/g, '').replace(/}}/g, '').trim() || (defaultPosition !== null && defaultPosition !== void 0 ? defaultPosition : null),
|
|
106
|
+
year: Number((_l = table.rows[i]) === null || _l === void 0 ? void 0 : _l[indexYear]) || null,
|
|
107
|
+
salaryDollars: Number((_m = table.rows[i]) === null || _m === void 0 ? void 0 : _m[indexSalary]) || null,
|
|
108
|
+
bonusDollars: Number((_o = table.rows[i]) === null || _o === void 0 ? void 0 : _o[indexBonus]) || null,
|
|
109
|
+
stockAwardDollars: Number((_p = table.rows[i]) === null || _p === void 0 ? void 0 : _p[indexStock]) || null,
|
|
110
|
+
nonEquityDollars: Number((_q = table.rows[i]) === null || _q === void 0 ? void 0 : _q[indexNonEquity]) || null,
|
|
111
|
+
otherDollars: Number((_r = table.rows[i]) === null || _r === void 0 ? void 0 : _r[indexOther]) || null,
|
|
112
|
+
totalDollars: Number((_s = table.rows[i]) === null || _s === void 0 ? void 0 : _s[indexTotal]) || null,
|
|
113
|
+
};
|
|
114
|
+
if (compensation.totalDollars !== null) {
|
|
115
|
+
compensationArr.push(compensation);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
87
118
|
};
|
|
88
|
-
for (var
|
|
89
|
-
|
|
119
|
+
for (var _v = 0, _w = findCompensationTables(type); _v < _w.length; _v++) {
|
|
120
|
+
var table = _w[_v];
|
|
121
|
+
_loop_2(table);
|
|
90
122
|
}
|
|
91
|
-
compensationTables.push(compensationRows);
|
|
92
123
|
}
|
|
93
|
-
|
|
94
|
-
var tablesFlat = flattenTables(compensationTables);
|
|
95
|
-
return { executiveCompensation: tablesFlat };
|
|
124
|
+
return { executiveCompensation: compensationArr, holders: holderArr };
|
|
96
125
|
}
|
|
97
126
|
exports.parseFormDef14a = parseFormDef14a;
|
|
98
|
-
function flattenTables(tables) {
|
|
99
|
-
var isDefaultPosition = function (position) { return position === 'Director' || position === 'Executive'; };
|
|
100
|
-
var compensationByNameYear = new Map();
|
|
101
|
-
var resolveProperty = function (a, b) {
|
|
102
|
-
if (a === null && b === null)
|
|
103
|
-
return null;
|
|
104
|
-
if (a === null && b !== null)
|
|
105
|
-
return b;
|
|
106
|
-
if (a !== null && b === null)
|
|
107
|
-
return a;
|
|
108
|
-
if (typeof a === 'number' && typeof b === 'number') {
|
|
109
|
-
return Math.max(a, b);
|
|
110
|
-
}
|
|
111
|
-
if (typeof a === 'string' && typeof b === 'string') {
|
|
112
|
-
return isDefaultPosition(a) ? b : a;
|
|
113
|
-
}
|
|
114
|
-
return b;
|
|
115
|
-
};
|
|
116
|
-
for (var _i = 0, tables_2 = tables; _i < tables_2.length; _i++) {
|
|
117
|
-
var table = tables_2[_i];
|
|
118
|
-
for (var _a = 0, table_1 = table; _a < table_1.length; _a++) {
|
|
119
|
-
var row = table_1[_a];
|
|
120
|
-
var key = "".concat(row.name, "_").concat(row.year);
|
|
121
|
-
var curRow = compensationByNameYear.get(key) || row;
|
|
122
|
-
compensationByNameYear.set(key, curRow);
|
|
123
|
-
for (var key_1 in row) {
|
|
124
|
-
var k = key_1;
|
|
125
|
-
curRow[k] = resolveProperty(curRow[k], row[k]);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return Array.from(compensationByNameYear.values());
|
|
130
|
-
}
|
|
131
|
-
function mergeYearRows(compensationTables) {
|
|
132
|
-
var _a;
|
|
133
|
-
var isDefaultPosition = function (position) { return position === 'Director' || position === 'Executive'; };
|
|
134
|
-
var positionByName = new Map();
|
|
135
|
-
for (var _i = 0, compensationTables_1 = compensationTables; _i < compensationTables_1.length; _i++) {
|
|
136
|
-
var table = compensationTables_1[_i];
|
|
137
|
-
var uniqueYears = Array.from(new Set(table.map(function (row) { return row.year; }))).filter(Boolean);
|
|
138
|
-
if (uniqueYears.length <= 1)
|
|
139
|
-
continue;
|
|
140
|
-
var isDesc = uniqueYears[0] > uniqueYears[1];
|
|
141
|
-
for (var i = 1; i < table.length; i++) {
|
|
142
|
-
var row = table[i];
|
|
143
|
-
var rowPrev = table[i - 1];
|
|
144
|
-
var year = Number(row.year);
|
|
145
|
-
var yearPrev = Number(rowPrev.year);
|
|
146
|
-
if (yearPrev && !year) {
|
|
147
|
-
year = isDesc ? yearPrev - 1 : yearPrev + 1;
|
|
148
|
-
row.year = year;
|
|
149
|
-
}
|
|
150
|
-
else if (!yearPrev && year) {
|
|
151
|
-
yearPrev = isDesc ? year - 1 : year + 1;
|
|
152
|
-
rowPrev.year = yearPrev;
|
|
153
|
-
}
|
|
154
|
-
var isIncrementYear = isDesc ? year < yearPrev : year > yearPrev;
|
|
155
|
-
var isSamePersonDiffYear = isIncrementYear && year && yearPrev;
|
|
156
|
-
var isSameName = row.name === rowPrev.name;
|
|
157
|
-
var isSamePosition = row.position === rowPrev.position;
|
|
158
|
-
var mergedNamePosition = "".concat(isSameName ? '' : row.name || '', " ").concat(isDefaultPosition(row.position) || isSamePosition ? '' : row.position || '').trim();
|
|
159
|
-
var mergedPosition = isDefaultPosition(rowPrev.position)
|
|
160
|
-
? mergedNamePosition
|
|
161
|
-
: "".concat(rowPrev.position || '', " ").concat(mergedNamePosition).trim();
|
|
162
|
-
var nameNew = rowPrev.name || row.name;
|
|
163
|
-
var positionNew = ((_a = rowPrev.position) === null || _a === void 0 ? void 0 : _a.includes(mergedNamePosition)) ? rowPrev.position : mergedPosition;
|
|
164
|
-
if (isSamePersonDiffYear) {
|
|
165
|
-
rowPrev.position = positionNew;
|
|
166
|
-
row.position = positionNew;
|
|
167
|
-
rowPrev.name = nameNew;
|
|
168
|
-
row.name = nameNew;
|
|
169
|
-
}
|
|
170
|
-
positionByName.set(row.name, String(row.position));
|
|
171
|
-
}
|
|
172
|
-
for (var _b = 0, table_2 = table; _b < table_2.length; _b++) {
|
|
173
|
-
var row = table_2[_b];
|
|
174
|
-
row.position = positionByName.get(row.name) || row.position;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
@@ -6,6 +6,10 @@ export interface SetReportDatesParams {
|
|
|
6
6
|
isAnnual: boolean;
|
|
7
7
|
accn: string;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Gets the fiscal period for a given date. does this by checking when the FY end periods are,
|
|
11
|
+
* Then measures the offset from the end date to the next/previous fiscal year end.
|
|
12
|
+
*/
|
|
9
13
|
export default class FactFiscalCalculator {
|
|
10
14
|
private readonly endDateByYear;
|
|
11
15
|
private readonly fiscalsByEndDate;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Gets the fiscal period for a given date. does this by checking when the FY end periods are,
|
|
5
|
+
* Then measures the offset from the end date to the next/previous fiscal year end.
|
|
6
|
+
*/
|
|
3
7
|
var FactFiscalCalculator = /** @class */ (function () {
|
|
4
8
|
function FactFiscalCalculator() {
|
|
5
9
|
this.endDateByYear = new Map();
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { FiscalPeriod } from '../../types/report-raw.type';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves quarterly and annual values for a property. This is because filers provide total values for the
|
|
4
|
+
* current fiscal year, rather than values for the individual quarters
|
|
5
|
+
* ex: Net income for Q2 will give 6 months revenue, not 3 month.
|
|
6
|
+
*/
|
|
2
7
|
export default class FactPeriodResolver {
|
|
3
8
|
/** Values for each quarter [numQ1, numQ2, numQ3, numQ4] */
|
|
4
9
|
private readonly valueByQuarterByPropertyByYear;
|
|
@@ -30,8 +35,7 @@ export default class FactPeriodResolver {
|
|
|
30
35
|
end: string;
|
|
31
36
|
value: number | string;
|
|
32
37
|
name: string;
|
|
33
|
-
|
|
34
|
-
dateFiled: string;
|
|
38
|
+
filed: string;
|
|
35
39
|
}): void;
|
|
36
40
|
private readonly unresolvedReports;
|
|
37
41
|
private buildUnresolvedReports;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
var ReportRawResolvable_1 = require("./ReportRawResolvable");
|
|
4
|
+
/**
|
|
5
|
+
* Resolves quarterly and annual values for a property. This is because filers provide total values for the
|
|
6
|
+
* current fiscal year, rather than values for the individual quarters
|
|
7
|
+
* ex: Net income for Q2 will give 6 months revenue, not 3 month.
|
|
8
|
+
*/
|
|
4
9
|
var FactPeriodResolver = /** @class */ (function () {
|
|
5
10
|
function FactPeriodResolver(args) {
|
|
6
11
|
/** Values for each quarter [numQ1, numQ2, numQ3, numQ4] */
|
|
@@ -111,7 +116,7 @@ var FactPeriodResolver = /** @class */ (function () {
|
|
|
111
116
|
return report;
|
|
112
117
|
};
|
|
113
118
|
FactPeriodResolver.prototype.add = function (params) {
|
|
114
|
-
var year = params.year, value = params.value, propertyName = params.name, quarter = params.quarter, start = params.start, end = params.end,
|
|
119
|
+
var year = params.year, value = params.value, propertyName = params.name, quarter = params.quarter, start = params.start, end = params.end, filed = params.filed;
|
|
115
120
|
var period = this.getPeriod({ start: start, end: end });
|
|
116
121
|
this.addPropertyByYear(this.propertiesByYear, year, propertyName);
|
|
117
122
|
if (typeof value === 'string') {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { FactItem } from './ReportBuilder';
|
|
2
2
|
import { CompanyFactListData } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Builds an array of fact records.
|
|
5
|
+
*/
|
|
3
6
|
export default class FactRecordBuilder {
|
|
4
|
-
createFacts(data: CompanyFactListData): {
|
|
7
|
+
createFacts(data: CompanyFactListData, filterDuplicates?: boolean): {
|
|
5
8
|
facts: FactItem[];
|
|
6
9
|
};
|
|
7
10
|
}
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Builds an array of fact records.
|
|
5
|
+
*/
|
|
3
6
|
var FactRecordBuilder = /** @class */ (function () {
|
|
4
7
|
function FactRecordBuilder() {
|
|
5
8
|
}
|
|
6
|
-
FactRecordBuilder.prototype.createFacts = function (data) {
|
|
9
|
+
FactRecordBuilder.prototype.createFacts = function (data, filterDuplicates) {
|
|
10
|
+
if (filterDuplicates === void 0) { filterDuplicates = false; }
|
|
7
11
|
var facts = data.facts, cik = data.cik;
|
|
8
|
-
var
|
|
12
|
+
var factsByKey = new Map();
|
|
13
|
+
var keyIndex = 0;
|
|
14
|
+
var createKey = function (params) {
|
|
15
|
+
if (!filterDuplicates)
|
|
16
|
+
return keyIndex++;
|
|
17
|
+
var start = params.start, end = params.end, filed = params.filed, propertyName = params.propertyName;
|
|
18
|
+
return "".concat(start !== null && start !== void 0 ? start : '', "_").concat(end, "_").concat(filed, "_").concat(propertyName);
|
|
19
|
+
};
|
|
9
20
|
for (var prefix in facts) {
|
|
10
21
|
var factByPropertyName = facts[prefix];
|
|
11
22
|
for (var propertyName in factByPropertyName) {
|
|
@@ -15,6 +26,7 @@ var FactRecordBuilder = /** @class */ (function () {
|
|
|
15
26
|
for (var _i = 0, factValues_1 = factValues; _i < factValues_1.length; _i++) {
|
|
16
27
|
var factValue = factValues_1[_i];
|
|
17
28
|
var end = factValue.end, start = factValue.start, val = factValue.val, filed = factValue.filed, accn = factValue.accn, form = factValue.form, fp = factValue.fp, frame = factValue.frame, fy = factValue.fy;
|
|
29
|
+
var mapKey = createKey({ propertyName: propertyName, end: end, filed: filed, start: start });
|
|
18
30
|
var name_1 = "".concat(prefix, ":").concat(propertyName);
|
|
19
31
|
var item = {
|
|
20
32
|
cik: cik,
|
|
@@ -37,12 +49,22 @@ var FactRecordBuilder = /** @class */ (function () {
|
|
|
37
49
|
item.frame = frame;
|
|
38
50
|
if (fy)
|
|
39
51
|
item.fy = fy;
|
|
40
|
-
|
|
52
|
+
var prevFact = factsByKey.get(mapKey);
|
|
53
|
+
if (!prevFact) {
|
|
54
|
+
factsByKey.set(mapKey, item);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
// use whichever is closer to the report end date
|
|
58
|
+
var shouldPush = new Date(item.filed).getTime() - new Date(item.end).getTime() <
|
|
59
|
+
new Date(prevFact.filed).getTime() - new Date(prevFact.end).getTime();
|
|
60
|
+
if (shouldPush) {
|
|
61
|
+
factsByKey.set(mapKey, item);
|
|
62
|
+
}
|
|
41
63
|
}
|
|
42
64
|
}
|
|
43
65
|
}
|
|
44
66
|
}
|
|
45
|
-
return { facts:
|
|
67
|
+
return { facts: Array.from(factsByKey.values()) };
|
|
46
68
|
};
|
|
47
69
|
return FactRecordBuilder;
|
|
48
70
|
}());
|
|
@@ -6,10 +6,15 @@ interface SplitData {
|
|
|
6
6
|
value: number;
|
|
7
7
|
firstFiled: string;
|
|
8
8
|
fiscalYear: number;
|
|
9
|
+
fiscalPeriod: FiscalPeriod;
|
|
9
10
|
}
|
|
10
11
|
type FactItemWithFiscalsNumeric = Omit<FactItemWithFiscals, 'cik' | 'value'> & {
|
|
11
12
|
value: number;
|
|
12
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* Adjust share-based property values for splits. Checks where the split was applied,
|
|
16
|
+
* and adjusts all previously filed share facts accordingly.
|
|
17
|
+
*/
|
|
13
18
|
export default class FactSplitAdjuster {
|
|
14
19
|
private readonly splitKey;
|
|
15
20
|
private readonly splitByFiscalYearAmount;
|
|
@@ -18,10 +23,16 @@ export default class FactSplitAdjuster {
|
|
|
18
23
|
private readonly resolvedProperties;
|
|
19
24
|
private sortedSplits;
|
|
20
25
|
private getMap;
|
|
21
|
-
|
|
26
|
+
private filedFirstLastBySplitKey;
|
|
27
|
+
add(fact: FactItemWithFiscalsNumeric & {
|
|
28
|
+
filedLast?: string;
|
|
29
|
+
}): void;
|
|
22
30
|
getSplitsAsc(): SplitData[];
|
|
23
31
|
isSplitProperty(propertyName: string): boolean;
|
|
24
32
|
addSplitData(data: Omit<SplitData, 'firstFiled'>): void;
|
|
33
|
+
/**
|
|
34
|
+
* TODO: Find a more reliable way of checking if the split has already been applied.
|
|
35
|
+
*/
|
|
25
36
|
private didApplySplit;
|
|
26
37
|
isSplitAdjustableUnit(unit: string): boolean;
|
|
27
38
|
isShareRatioUnit(unit: string): boolean;
|
|
@@ -11,6 +11,10 @@ var __assign = (this && this.__assign) || function () {
|
|
|
11
11
|
return __assign.apply(this, arguments);
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
/**
|
|
15
|
+
* Adjust share-based property values for splits. Checks where the split was applied,
|
|
16
|
+
* and adjusts all previously filed share facts accordingly.
|
|
17
|
+
*/
|
|
14
18
|
var FactSplitAdjuster = /** @class */ (function () {
|
|
15
19
|
function FactSplitAdjuster() {
|
|
16
20
|
this.splitKey = 'StockholdersEquityNoteStockSplitConversionRatio1';
|
|
@@ -19,15 +23,17 @@ var FactSplitAdjuster = /** @class */ (function () {
|
|
|
19
23
|
this.factsAnnaulByYearByPropertyName = new Map();
|
|
20
24
|
this.resolvedProperties = new Set();
|
|
21
25
|
this.sortedSplits = null;
|
|
26
|
+
this.filedFirstLastBySplitKey = new Map();
|
|
22
27
|
}
|
|
23
28
|
FactSplitAdjuster.prototype.getMap = function (map, propertyName) {
|
|
24
29
|
var _a;
|
|
25
30
|
return (_a = map.get(propertyName)) !== null && _a !== void 0 ? _a : map.set(propertyName, new Map()).get(propertyName);
|
|
26
31
|
};
|
|
27
32
|
FactSplitAdjuster.prototype.add = function (fact) {
|
|
33
|
+
var _a;
|
|
28
34
|
var propertyName = fact.name, year = fact.year, fiscalPeriod = fact.fiscalPeriod, unit = fact.unit, filed = fact.filed, value = fact.value, end = fact.end;
|
|
29
35
|
if (this.isSplitProperty(propertyName)) {
|
|
30
|
-
this.addSplitData({ end: end, filed: filed, fiscalYear: year, value: Number(value) });
|
|
36
|
+
this.addSplitData({ end: end, filed: filed, fiscalYear: year, value: Number(value), fiscalPeriod: fiscalPeriod });
|
|
31
37
|
return;
|
|
32
38
|
}
|
|
33
39
|
if (!this.isSplitAdjustableUnit(unit))
|
|
@@ -40,6 +46,10 @@ var FactSplitAdjuster = /** @class */ (function () {
|
|
|
40
46
|
? this.getMap(this.factsAnnaulByYearByPropertyName, propertyName)
|
|
41
47
|
: this.getMap(this.factsByYearQuarterByPropertyName, propertyName);
|
|
42
48
|
var key = "".concat(year, "_").concat(fiscalPeriod);
|
|
49
|
+
this.filedFirstLastBySplitKey.set(key, {
|
|
50
|
+
firstFiled: filed,
|
|
51
|
+
lastFiled: (_a = fact.filedLast) !== null && _a !== void 0 ? _a : filed,
|
|
52
|
+
});
|
|
43
53
|
map.set(key, fact);
|
|
44
54
|
};
|
|
45
55
|
FactSplitAdjuster.prototype.getSplitsAsc = function () {
|
|
@@ -84,23 +94,30 @@ var FactSplitAdjuster = /** @class */ (function () {
|
|
|
84
94
|
this.sortedSplits = null;
|
|
85
95
|
}
|
|
86
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* TODO: Find a more reliable way of checking if the split has already been applied.
|
|
99
|
+
*/
|
|
87
100
|
FactSplitAdjuster.prototype.didApplySplit = function (params) {
|
|
88
|
-
var
|
|
89
|
-
|
|
101
|
+
var _a;
|
|
102
|
+
var isShareRatio = params.isShareRatio, nextFact = params.nextFact, prevFact = params.prevFact, fact = params.fact, split = params.split;
|
|
103
|
+
var _b = (_a = this.filedFirstLastBySplitKey.get("".concat(split.fiscalYear, "_").concat(split.fiscalPeriod))) !== null && _a !== void 0 ? _a : {}, firstFiled = _b.firstFiled, lastFiled = _b.lastFiled;
|
|
104
|
+
if (fact.filed > lastFiled) {
|
|
90
105
|
return true;
|
|
91
106
|
}
|
|
92
|
-
if (filed <
|
|
107
|
+
if (fact.filed < firstFiled) {
|
|
93
108
|
return false;
|
|
94
109
|
}
|
|
95
|
-
var
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
110
|
+
var val = fact.value;
|
|
111
|
+
var splitVal = split.value;
|
|
112
|
+
var valWithSplit = isShareRatio ? splitVal * val : val / splitVal;
|
|
113
|
+
if (nextFact) {
|
|
114
|
+
var difference = Math.abs(nextFact.value - val);
|
|
115
|
+
var differenceSplit = Math.abs(nextFact.value - valWithSplit);
|
|
99
116
|
return difference < differenceSplit;
|
|
100
117
|
}
|
|
101
|
-
if (
|
|
102
|
-
var difference = Math.abs(
|
|
103
|
-
var differenceSplit = Math.abs(
|
|
118
|
+
if (prevFact) {
|
|
119
|
+
var difference = Math.abs(prevFact.value - val);
|
|
120
|
+
var differenceSplit = Math.abs(prevFact.value - valWithSplit);
|
|
104
121
|
return difference < differenceSplit;
|
|
105
122
|
}
|
|
106
123
|
return false;
|
|
@@ -154,7 +171,7 @@ var FactSplitAdjuster = /** @class */ (function () {
|
|
|
154
171
|
});
|
|
155
172
|
};
|
|
156
173
|
FactSplitAdjuster.prototype.adjustValuesForSplits = function (params) {
|
|
157
|
-
var _a, _b
|
|
174
|
+
var _a, _b;
|
|
158
175
|
var facts = params.facts;
|
|
159
176
|
var splits = this.getSplitsAsc();
|
|
160
177
|
if (facts.length === 0 || splits.length === 0)
|
|
@@ -165,17 +182,22 @@ var FactSplitAdjuster = /** @class */ (function () {
|
|
|
165
182
|
for (var factIndex = facts.length - 1; factIndex >= 0; factIndex--) {
|
|
166
183
|
var fact = facts[factIndex];
|
|
167
184
|
var value = fact.value, filed = fact.filed;
|
|
168
|
-
var
|
|
169
|
-
var
|
|
185
|
+
var nextFact = (_a = facts[factIndex + 1]) !== null && _a !== void 0 ? _a : null;
|
|
186
|
+
var prevFact = (_b = facts[factIndex - 1]) !== null && _b !== void 0 ? _b : null;
|
|
187
|
+
// const nextValue = facts[factIndex + 1]?.value ?? null
|
|
188
|
+
// const prevValue = facts[factIndex - 1]?.value ?? null
|
|
170
189
|
var didApplySplit = this.didApplySplit({
|
|
171
|
-
|
|
190
|
+
// filed,
|
|
172
191
|
isShareRatio: isShareRatio,
|
|
173
|
-
|
|
174
|
-
|
|
192
|
+
// nextValue,
|
|
193
|
+
// prevValue,
|
|
194
|
+
fact: fact,
|
|
195
|
+
nextFact: nextFact,
|
|
196
|
+
prevFact: prevFact,
|
|
175
197
|
split: split,
|
|
176
|
-
|
|
198
|
+
// value,
|
|
177
199
|
});
|
|
178
|
-
if (didApplySplit) {
|
|
200
|
+
if (didApplySplit || !split.value) {
|
|
179
201
|
continue;
|
|
180
202
|
}
|
|
181
203
|
if (isShareRatio) {
|
|
@@ -25,6 +25,9 @@ export interface FactItemWithFiscals extends FactItem {
|
|
|
25
25
|
fiscalPeriod: FiscalPeriod;
|
|
26
26
|
year: number;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds ReportRaw objects from facts. also applies splits and adjusts for fiscal periods.
|
|
30
|
+
*/
|
|
28
31
|
export default class ReportBuilder {
|
|
29
32
|
private readonly factRecordBuilder;
|
|
30
33
|
createFacts(companyFacts: CompanyFactListData): {
|