sec-edgar-api 0.2.4 → 0.3.0
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 +1 -0
- package/build/services/ReportParser/ReportParser.d.ts +6 -13
- package/build/services/ReportParser/ReportParser.js +15 -22
- package/build/services/ReportRawBuilder/FactGrouper.d.ts +27 -0
- package/build/services/ReportRawBuilder/FactGrouper.js +206 -0
- package/build/services/{ReportBuilder → ReportRawBuilder}/FactPeriodResolver.d.ts +46 -2
- package/build/services/{ReportBuilder → ReportRawBuilder}/FactPeriodResolver.js +81 -20
- package/build/services/ReportRawBuilder/FactRecordBuilder.d.ts +9 -0
- package/build/services/{ReportBuilder → ReportRawBuilder}/FactRecordBuilder.js +6 -24
- package/build/services/ReportRawBuilder/FactSplitAdjuster.d.ts +43 -0
- package/build/services/ReportRawBuilder/FactSplitAdjuster.js +242 -0
- package/build/services/ReportRawBuilder/ReportRawBuilder.d.ts +39 -0
- package/build/services/ReportRawBuilder/ReportRawBuilder.js +158 -0
- package/build/services/ReportRawBuilder/index.d.ts +2 -0
- package/build/services/ReportRawBuilder/index.js +4 -0
- package/build/services/SecEdgarApi/SecEdgarApi.d.ts +10 -2
- package/build/services/SecEdgarApi/SecEdgarApi.js +29 -11
- package/build/types/common.type.d.ts +41 -0
- package/build/types/company-facts.type.d.ts +29 -2
- package/package.json +1 -1
- package/build/services/ReportBuilder/FactRecordBuilder.d.ts +0 -10
- package/build/services/ReportBuilder/FactSplitAdjuster.d.ts +0 -50
- package/build/services/ReportBuilder/FactSplitAdjuster.js +0 -214
- package/build/services/ReportBuilder/ReportBuilder.d.ts +0 -40
- package/build/services/ReportBuilder/ReportBuilder.js +0 -200
- package/build/services/ReportBuilder/ReportRawResolvable.d.ts +0 -17
- package/build/services/ReportBuilder/ReportRawResolvable.js +0 -114
- package/build/services/ReportBuilder/index.d.ts +0 -2
- package/build/services/ReportBuilder/index.js +0 -4
- package/build/services/ReportParser/ReportRawParser.d.ts +0 -5
- package/build/services/ReportParser/ReportRawParser.js +0 -14
- package/build/util/calculation-map-by-ns.d.ts +0 -6
- package/build/util/calculation-map-by-ns.js +0 -9
- /package/build/services/{ReportBuilder → ReportRawBuilder}/FactFiscalCalculator.d.ts +0 -0
- /package/build/services/{ReportBuilder → ReportRawBuilder}/FactFiscalCalculator.js +0 -0
|
@@ -6,17 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
var FactRecordBuilder = /** @class */ (function () {
|
|
7
7
|
function FactRecordBuilder() {
|
|
8
8
|
}
|
|
9
|
-
FactRecordBuilder.prototype.createFacts = function (data,
|
|
10
|
-
if (
|
|
9
|
+
FactRecordBuilder.prototype.createFacts = function (data, includeNamePrefix) {
|
|
10
|
+
if (includeNamePrefix === void 0) { includeNamePrefix = true; }
|
|
11
11
|
var facts = data.facts, cik = data.cik;
|
|
12
|
-
var
|
|
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
|
-
};
|
|
12
|
+
var factItems = [];
|
|
20
13
|
for (var prefix in facts) {
|
|
21
14
|
var factByPropertyName = facts[prefix];
|
|
22
15
|
for (var propertyName in factByPropertyName) {
|
|
@@ -26,8 +19,7 @@ var FactRecordBuilder = /** @class */ (function () {
|
|
|
26
19
|
for (var _i = 0, factValues_1 = factValues; _i < factValues_1.length; _i++) {
|
|
27
20
|
var factValue = factValues_1[_i];
|
|
28
21
|
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
|
|
30
|
-
var name_1 = "".concat(prefix, ":").concat(propertyName);
|
|
22
|
+
var name_1 = includeNamePrefix ? "".concat(prefix, ":").concat(propertyName) : propertyName;
|
|
31
23
|
var item = {
|
|
32
24
|
cik: cik,
|
|
33
25
|
end: end,
|
|
@@ -49,22 +41,12 @@ var FactRecordBuilder = /** @class */ (function () {
|
|
|
49
41
|
item.frame = frame;
|
|
50
42
|
if (fy)
|
|
51
43
|
item.fy = fy;
|
|
52
|
-
|
|
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
|
-
}
|
|
44
|
+
factItems.push(item);
|
|
63
45
|
}
|
|
64
46
|
}
|
|
65
47
|
}
|
|
66
48
|
}
|
|
67
|
-
return { facts:
|
|
49
|
+
return { facts: factItems };
|
|
68
50
|
};
|
|
69
51
|
return FactRecordBuilder;
|
|
70
52
|
}());
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { CompanyFactListData, FactGroup, FactItem, FactValue, SplitData } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Splits can be filed multiple times throughout different reports. There is no clear
|
|
4
|
+
* indication on when the split is executed or what facts the split has been applied to. This
|
|
5
|
+
* class tries to determine which splits have been applied and which need to be adjusted for
|
|
6
|
+
* each fact.
|
|
7
|
+
*/
|
|
8
|
+
export default class FactSplitAdjuster {
|
|
9
|
+
private readonly keySplit;
|
|
10
|
+
private preferFirstValue;
|
|
11
|
+
private getGroupValue;
|
|
12
|
+
getSplits(params: {
|
|
13
|
+
splitFacts: FactValue[] | FactItem[];
|
|
14
|
+
}): SplitData[];
|
|
15
|
+
filterSplitFacts(params: {
|
|
16
|
+
facts: FactItem[];
|
|
17
|
+
}): FactItem[];
|
|
18
|
+
extractSplitsFromCompanyFacts(params: {
|
|
19
|
+
companyFactList: Pick<CompanyFactListData, 'facts'>;
|
|
20
|
+
}): FactValue[];
|
|
21
|
+
getSplitsFromCompanyFacts(params: {
|
|
22
|
+
companyFactList: Pick<CompanyFactListData, 'facts'>;
|
|
23
|
+
}): SplitData[];
|
|
24
|
+
/**
|
|
25
|
+
* Returns true if the fact value was adjusted, false if it was not,
|
|
26
|
+
* and null if the comparison does not match the split
|
|
27
|
+
*/
|
|
28
|
+
private isAdjustedFromComparedFact;
|
|
29
|
+
/**
|
|
30
|
+
* Splits can be filed multiple times throughout different reports.
|
|
31
|
+
*/
|
|
32
|
+
didApplySplit(params: {
|
|
33
|
+
isShareRatio: boolean;
|
|
34
|
+
split: SplitData;
|
|
35
|
+
factGroup: FactGroup;
|
|
36
|
+
isTrailing: boolean;
|
|
37
|
+
useOppositePeriodFallback?: boolean;
|
|
38
|
+
}): boolean;
|
|
39
|
+
adjustForSplits(params: {
|
|
40
|
+
factGroups: FactGroup[];
|
|
41
|
+
splits: SplitData[];
|
|
42
|
+
}): void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
14
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
15
|
+
if (ar || !(i in from)) {
|
|
16
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
17
|
+
ar[i] = from[i];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
var FactPeriodResolver_1 = require("./FactPeriodResolver");
|
|
24
|
+
/**
|
|
25
|
+
* Splits can be filed multiple times throughout different reports. There is no clear
|
|
26
|
+
* indication on when the split is executed or what facts the split has been applied to. This
|
|
27
|
+
* class tries to determine which splits have been applied and which need to be adjusted for
|
|
28
|
+
* each fact.
|
|
29
|
+
*/
|
|
30
|
+
var FactSplitAdjuster = /** @class */ (function () {
|
|
31
|
+
function FactSplitAdjuster() {
|
|
32
|
+
this.keySplit = 'StockholdersEquityNoteStockSplitConversionRatio1';
|
|
33
|
+
this.preferFirstValue = true;
|
|
34
|
+
}
|
|
35
|
+
FactSplitAdjuster.prototype.getGroupValue = function (factGroup, isTrailing) {
|
|
36
|
+
if (isTrailing) {
|
|
37
|
+
return Number(this.preferFirstValue ? factGroup.valueTrailingFirst : factGroup.valueTrailingLast);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
return Number(this.preferFirstValue ? factGroup.valuePeriodFirst : factGroup.valuePeriodLast);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
FactSplitAdjuster.prototype.getSplits = function (params) {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
var splitFacts = __spreadArray([], params.splitFacts, true).sort(function (a, b) { return (a.end < b.end ? -1 : 1); });
|
|
46
|
+
var YEAR_MS = 31536000000;
|
|
47
|
+
var splits = [];
|
|
48
|
+
var currentSplit = null;
|
|
49
|
+
for (var i = 0; i < splitFacts.length; i++) {
|
|
50
|
+
var prevFact = splitFacts[i - 1];
|
|
51
|
+
var fact = splitFacts[i];
|
|
52
|
+
var factValue = Number((_a = fact.value) !== null && _a !== void 0 ? _a : fact.val);
|
|
53
|
+
var factValuePrev = Number((_b = prevFact === null || prevFact === void 0 ? void 0 : prevFact.value) !== null && _b !== void 0 ? _b : prevFact === null || prevFact === void 0 ? void 0 : prevFact.val);
|
|
54
|
+
var isSameSplitLaterFiling = factValue === factValuePrev && new Date(fact.end).getTime() - new Date(prevFact.end).getTime() < YEAR_MS;
|
|
55
|
+
if (!isSameSplitLaterFiling && currentSplit) {
|
|
56
|
+
splits.push(currentSplit);
|
|
57
|
+
currentSplit = null;
|
|
58
|
+
}
|
|
59
|
+
if (!currentSplit) {
|
|
60
|
+
currentSplit = {
|
|
61
|
+
endFirst: fact.end,
|
|
62
|
+
endLast: fact.end,
|
|
63
|
+
filedFirst: fact.filed,
|
|
64
|
+
filedLast: fact.filed,
|
|
65
|
+
splitRatio: factValue,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
currentSplit.endFirst = fact.end < currentSplit.endFirst ? fact.end : currentSplit.endFirst;
|
|
70
|
+
currentSplit.endLast = fact.end > currentSplit.endLast ? fact.end : currentSplit.endLast;
|
|
71
|
+
currentSplit.filedFirst = fact.filed < currentSplit.filedFirst ? fact.filed : currentSplit.filedFirst;
|
|
72
|
+
currentSplit.filedLast = fact.filed > currentSplit.filedLast ? fact.filed : currentSplit.filedLast;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (currentSplit) {
|
|
76
|
+
splits.push(currentSplit);
|
|
77
|
+
}
|
|
78
|
+
return splits;
|
|
79
|
+
};
|
|
80
|
+
FactSplitAdjuster.prototype.filterSplitFacts = function (params) {
|
|
81
|
+
var _this = this;
|
|
82
|
+
var facts = params.facts;
|
|
83
|
+
return facts.filter(function (f) { return f.name.endsWith(_this.keySplit); });
|
|
84
|
+
};
|
|
85
|
+
FactSplitAdjuster.prototype.extractSplitsFromCompanyFacts = function (params) {
|
|
86
|
+
var _a, _b, _c;
|
|
87
|
+
var companyFactList = params.companyFactList;
|
|
88
|
+
var factsByName = (_a = companyFactList.facts['us-gaap']) !== null && _a !== void 0 ? _a : {};
|
|
89
|
+
return (_c = (_b = factsByName[this.keySplit]) === null || _b === void 0 ? void 0 : _b.units.pure) !== null && _c !== void 0 ? _c : [];
|
|
90
|
+
};
|
|
91
|
+
FactSplitAdjuster.prototype.getSplitsFromCompanyFacts = function (params) {
|
|
92
|
+
var _a, _b, _c;
|
|
93
|
+
var companyFactList = params.companyFactList;
|
|
94
|
+
var factsByName = (_a = companyFactList.facts['us-gaap']) !== null && _a !== void 0 ? _a : {};
|
|
95
|
+
var splitFacts = __spreadArray([], ((_c = (_b = factsByName[this.keySplit]) === null || _b === void 0 ? void 0 : _b.units.pure) !== null && _c !== void 0 ? _c : []), true).sort(function (a, b) { return (a.end < b.end ? -1 : 1); });
|
|
96
|
+
var YEAR_MS = 31536000000;
|
|
97
|
+
var splits = [];
|
|
98
|
+
var currentSplit = null;
|
|
99
|
+
for (var i = 0; i < splitFacts.length; i++) {
|
|
100
|
+
var prevFact = splitFacts[i - 1];
|
|
101
|
+
var fact = splitFacts[i];
|
|
102
|
+
// Assume the split is executed within the first year of the first filing...
|
|
103
|
+
// sometimes a company will file the split fact mentioning that they plan on executing it later in the fiscal year
|
|
104
|
+
// (ex: when Google did their 20:1 split in July of 2020)
|
|
105
|
+
var isSameSplitLaterFiling = fact.val === (prevFact === null || prevFact === void 0 ? void 0 : prevFact.val) && new Date(fact.end).getTime() - new Date(prevFact.end).getTime() < YEAR_MS;
|
|
106
|
+
if (!isSameSplitLaterFiling && currentSplit) {
|
|
107
|
+
splits.push(currentSplit);
|
|
108
|
+
currentSplit = null;
|
|
109
|
+
}
|
|
110
|
+
if (!currentSplit) {
|
|
111
|
+
currentSplit = {
|
|
112
|
+
endFirst: fact.end,
|
|
113
|
+
endLast: fact.end,
|
|
114
|
+
filedFirst: fact.filed,
|
|
115
|
+
filedLast: fact.filed,
|
|
116
|
+
splitRatio: Number(fact.val),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
currentSplit.endFirst = fact.end < currentSplit.endFirst ? fact.end : currentSplit.endFirst;
|
|
121
|
+
currentSplit.endLast = fact.end > currentSplit.endLast ? fact.end : currentSplit.endLast;
|
|
122
|
+
currentSplit.filedFirst = fact.filed < currentSplit.filedFirst ? fact.filed : currentSplit.filedFirst;
|
|
123
|
+
currentSplit.filedLast = fact.filed > currentSplit.filedLast ? fact.filed : currentSplit.filedLast;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (currentSplit) {
|
|
127
|
+
splits.push(currentSplit);
|
|
128
|
+
}
|
|
129
|
+
return splits;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Returns true if the fact value was adjusted, false if it was not,
|
|
133
|
+
* and null if the comparison does not match the split
|
|
134
|
+
*/
|
|
135
|
+
FactSplitAdjuster.prototype.isAdjustedFromComparedFact = function (params) {
|
|
136
|
+
var _a, _b;
|
|
137
|
+
var factCompare = params.factCompare, factValue = params.factValue, isShareRatio = params.isShareRatio, splitVal = params.splitVal;
|
|
138
|
+
var minValue = Math.min(factValue, Number((_a = factCompare === null || factCompare === void 0 ? void 0 : factCompare.value) !== null && _a !== void 0 ? _a : factValue));
|
|
139
|
+
var maxValue = Math.max(factValue, Number((_b = factCompare === null || factCompare === void 0 ? void 0 : factCompare.value) !== null && _b !== void 0 ? _b : factValue));
|
|
140
|
+
var possiblePreSplitValue = isShareRatio ? maxValue : minValue;
|
|
141
|
+
var possiblePostSplitValue = isShareRatio ? minValue : maxValue;
|
|
142
|
+
var expectedPostSplitValue = isShareRatio
|
|
143
|
+
? possiblePreSplitValue / splitVal
|
|
144
|
+
: possiblePreSplitValue * splitVal;
|
|
145
|
+
var nearnessThreshold = 0.01;
|
|
146
|
+
var isSplitAdjustment = Math.abs(expectedPostSplitValue - possiblePostSplitValue) < nearnessThreshold;
|
|
147
|
+
return isSplitAdjustment ? possiblePostSplitValue === factValue : null;
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Splits can be filed multiple times throughout different reports.
|
|
151
|
+
*/
|
|
152
|
+
FactSplitAdjuster.prototype.didApplySplit = function (params) {
|
|
153
|
+
var isShareRatio = params.isShareRatio, factGroup = params.factGroup, split = params.split, isTrailing = params.isTrailing, _a = params.useOppositePeriodFallback, useOppositePeriodFallback = _a === void 0 ? true : _a;
|
|
154
|
+
var splitVal = split.splitRatio;
|
|
155
|
+
if (!splitVal)
|
|
156
|
+
return true;
|
|
157
|
+
// these first two criteria will take care of the majority of cases...
|
|
158
|
+
if (factGroup.filedFirst > split.filedLast) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
if (factGroup.filedLast < split.filedFirst) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
var resolvedFact = factGroup.facts.find(function (f) {
|
|
165
|
+
return isTrailing ? f.value === factGroup.valueTrailingFirst : f.value === factGroup.valuePeriodFirst;
|
|
166
|
+
});
|
|
167
|
+
if (!resolvedFact && useOppositePeriodFallback) {
|
|
168
|
+
return this.didApplySplit(__assign(__assign({}, params), { isTrailing: !isTrailing, useOppositePeriodFallback: false }));
|
|
169
|
+
}
|
|
170
|
+
var refiledFacts = factGroup.facts.filter(function (f) {
|
|
171
|
+
var period = FactPeriodResolver_1.default.getPeriod(f);
|
|
172
|
+
var isSamePeriod = isTrailing ? period === 0 || period > 3 : period <= 3;
|
|
173
|
+
return f !== resolvedFact && isSamePeriod;
|
|
174
|
+
});
|
|
175
|
+
// check if one of the filed facts is the split adjustment
|
|
176
|
+
for (var _i = 0, refiledFacts_1 = refiledFacts; _i < refiledFacts_1.length; _i++) {
|
|
177
|
+
var fact = refiledFacts_1[_i];
|
|
178
|
+
var isAdjusted = this.isAdjustedFromComparedFact({
|
|
179
|
+
factCompare: fact,
|
|
180
|
+
factValue: Number(resolvedFact === null || resolvedFact === void 0 ? void 0 : resolvedFact.value),
|
|
181
|
+
isShareRatio: isShareRatio,
|
|
182
|
+
splitVal: splitVal,
|
|
183
|
+
});
|
|
184
|
+
if (isAdjusted !== null) {
|
|
185
|
+
return isAdjusted;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if ((resolvedFact === null || resolvedFact === void 0 ? void 0 : resolvedFact.filed) > split.filedLast) {
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
if ((resolvedFact === null || resolvedFact === void 0 ? void 0 : resolvedFact.filed) < split.filedFirst) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
// // if the filed date of the fact overlaps with the filed date of the split, try comparing the end dates
|
|
195
|
+
if (factGroup.endLast < split.endFirst && factGroup.values.length === 1) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
// if we still don't know, see if the split value puts us closer to the last known value or further
|
|
199
|
+
if (factGroup.valuePeriodLast !== null) {
|
|
200
|
+
var val = this.getGroupValue(factGroup, isTrailing);
|
|
201
|
+
var valueWithSplit = isShareRatio ? val / splitVal : val * splitVal;
|
|
202
|
+
return Math.abs(factGroup.valuePeriodLast - val) < Math.abs(factGroup.valuePeriodLast - valueWithSplit);
|
|
203
|
+
}
|
|
204
|
+
if (factGroup.valueTrailingLast !== null) {
|
|
205
|
+
var val = this.getGroupValue(factGroup, isTrailing);
|
|
206
|
+
var valueWithSplit = isShareRatio ? val / splitVal : val * splitVal;
|
|
207
|
+
return Math.abs(factGroup.valueTrailingLast - val) < Math.abs(factGroup.valueTrailingLast - valueWithSplit);
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
};
|
|
211
|
+
FactSplitAdjuster.prototype.adjustForSplits = function (params) {
|
|
212
|
+
var factGroups = params.factGroups, splits = params.splits;
|
|
213
|
+
for (var _i = 0, factGroups_1 = factGroups; _i < factGroups_1.length; _i++) {
|
|
214
|
+
var factGroup = factGroups_1[_i];
|
|
215
|
+
var unitLower = factGroup.unit.toLowerCase();
|
|
216
|
+
if (!unitLower.includes('share'))
|
|
217
|
+
continue;
|
|
218
|
+
var isShareRatio = unitLower !== 'shares';
|
|
219
|
+
for (var _a = 0, splits_1 = splits; _a < splits_1.length; _a++) {
|
|
220
|
+
var split = splits_1[_a];
|
|
221
|
+
var factValuePeriod = this.getGroupValue(factGroup, false);
|
|
222
|
+
var factValueTrailing = this.getGroupValue(factGroup, true);
|
|
223
|
+
var splitValue = split.splitRatio;
|
|
224
|
+
if (!splitValue)
|
|
225
|
+
continue;
|
|
226
|
+
// ratios (like EPS) get divided by splits, share counts get multiplied (like shares outstanding).
|
|
227
|
+
if (!this.didApplySplit({ factGroup: factGroup, split: split, isShareRatio: isShareRatio, isTrailing: false })) {
|
|
228
|
+
factGroup.valueSplitAdjustedPeriod = isShareRatio
|
|
229
|
+
? factValuePeriod / splitValue
|
|
230
|
+
: factValuePeriod * splitValue;
|
|
231
|
+
}
|
|
232
|
+
if (!this.didApplySplit({ factGroup: factGroup, split: split, isShareRatio: isShareRatio, isTrailing: true })) {
|
|
233
|
+
factGroup.valueSplitAdjustedTrailing = isShareRatio
|
|
234
|
+
? factValueTrailing / splitValue
|
|
235
|
+
: factValueTrailing * splitValue;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
return FactSplitAdjuster;
|
|
241
|
+
}());
|
|
242
|
+
exports.default = FactSplitAdjuster;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { CompanyFactListData, FactGroup, FactItem, ReportRaw, SplitData } from '../../types';
|
|
2
|
+
import FactFiscalCalculator, { SetReportDatesParams } from './FactFiscalCalculator';
|
|
3
|
+
interface BuildReportsParams {
|
|
4
|
+
facts: FactItem[];
|
|
5
|
+
/**
|
|
6
|
+
* for more accurate dates, add this. Otherwise, dates will be inferred
|
|
7
|
+
* using the fact periods. The filing and report dates can be found in the SubmissionList (segEdgarApi.getSubmissions)
|
|
8
|
+
*/
|
|
9
|
+
reportDates?: SetReportDatesParams[];
|
|
10
|
+
/**
|
|
11
|
+
* Splits will be extracted from facts if not provided.
|
|
12
|
+
*/
|
|
13
|
+
splits?: SplitData[];
|
|
14
|
+
resolvePeriodValues?: boolean;
|
|
15
|
+
adjustForSplits?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds ReportRaw objects from company facts. Adjusts for splits and resolves period values.
|
|
19
|
+
*/
|
|
20
|
+
export default class ReportRawBuilder {
|
|
21
|
+
private readonly factRecordBuilder;
|
|
22
|
+
createFacts(companyFacts: CompanyFactListData, includeNamePrefix?: boolean): {
|
|
23
|
+
facts: FactItem[];
|
|
24
|
+
};
|
|
25
|
+
private createFiscalCalculator;
|
|
26
|
+
buildReports(params: BuildReportsParams): ReportRaw[];
|
|
27
|
+
private createReportKey;
|
|
28
|
+
private createReport;
|
|
29
|
+
private round;
|
|
30
|
+
buildReportsFromGroups(params: {
|
|
31
|
+
factGroupsByReportKey: Map<string, FactGroup[]>;
|
|
32
|
+
fiscalCalculator: FactFiscalCalculator;
|
|
33
|
+
splits?: SplitData[];
|
|
34
|
+
minYear: number;
|
|
35
|
+
maxYear: number;
|
|
36
|
+
cik: number;
|
|
37
|
+
}): ReportRaw[];
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var FactFiscalCalculator_1 = require("./FactFiscalCalculator");
|
|
4
|
+
var FactGrouper_1 = require("./FactGrouper");
|
|
5
|
+
var FactRecordBuilder_1 = require("./FactRecordBuilder");
|
|
6
|
+
var FactSplitAdjuster_1 = require("./FactSplitAdjuster");
|
|
7
|
+
/**
|
|
8
|
+
* Builds ReportRaw objects from company facts. Adjusts for splits and resolves period values.
|
|
9
|
+
*/
|
|
10
|
+
var ReportRawBuilder = /** @class */ (function () {
|
|
11
|
+
function ReportRawBuilder() {
|
|
12
|
+
this.factRecordBuilder = new FactRecordBuilder_1.default();
|
|
13
|
+
}
|
|
14
|
+
ReportRawBuilder.prototype.createFacts = function (companyFacts, includeNamePrefix) {
|
|
15
|
+
if (includeNamePrefix === void 0) { includeNamePrefix = false; }
|
|
16
|
+
return this.factRecordBuilder.createFacts(companyFacts, includeNamePrefix);
|
|
17
|
+
};
|
|
18
|
+
ReportRawBuilder.prototype.createFiscalCalculator = function (params) {
|
|
19
|
+
var facts = params.facts;
|
|
20
|
+
var fiscalCalculator = new FactFiscalCalculator_1.default();
|
|
21
|
+
for (var _i = 0, facts_1 = facts; _i < facts_1.length; _i++) {
|
|
22
|
+
var fact = facts_1[_i];
|
|
23
|
+
fiscalCalculator.add(fact);
|
|
24
|
+
}
|
|
25
|
+
return fiscalCalculator;
|
|
26
|
+
};
|
|
27
|
+
ReportRawBuilder.prototype.buildReports = function (params) {
|
|
28
|
+
var facts = params.facts, reportDates = params.reportDates, splitsProp = params.splits, _a = params.resolvePeriodValues, resolvePeriodValues = _a === void 0 ? true : _a, _b = params.adjustForSplits, adjustForSplits = _b === void 0 ? true : _b;
|
|
29
|
+
if (facts.length === 0) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
var accessionByYearQuarter = new Map();
|
|
33
|
+
reportDates === null || reportDates === void 0 ? void 0 : reportDates.forEach(function (params) {
|
|
34
|
+
var year = params.year, quarter = params.quarter, accn = params.accn;
|
|
35
|
+
if (accn)
|
|
36
|
+
accessionByYearQuarter.set("".concat(year, "_").concat(quarter), accn);
|
|
37
|
+
});
|
|
38
|
+
var reportsCik = Number(facts[0].cik);
|
|
39
|
+
var fiscalCalculator = this.createFiscalCalculator({ facts: facts });
|
|
40
|
+
var factGrouper = new FactGrouper_1.default();
|
|
41
|
+
var factSplitAdjuster = new FactSplitAdjuster_1.default();
|
|
42
|
+
// if splits not included in params and need to adjust, extract from facts
|
|
43
|
+
var splits = adjustForSplits
|
|
44
|
+
? splitsProp !== null && splitsProp !== void 0 ? splitsProp : factSplitAdjuster.getSplits({ splitFacts: factSplitAdjuster.filterSplitFacts({ facts: facts }) })
|
|
45
|
+
: splitsProp;
|
|
46
|
+
var _c = factGrouper.buildFactGroupsByReportKey({
|
|
47
|
+
facts: facts,
|
|
48
|
+
cik: reportsCik,
|
|
49
|
+
fiscalCalculator: fiscalCalculator,
|
|
50
|
+
resolvePeriodValues: resolvePeriodValues,
|
|
51
|
+
generateMissingGroups: false,
|
|
52
|
+
splits: splits,
|
|
53
|
+
}), factGroupsByReportKey = _c.factGroupsByReportKey, maxYear = _c.maxYear, minYear = _c.minYear;
|
|
54
|
+
return this.buildReportsFromGroups({
|
|
55
|
+
factGroupsByReportKey: factGroupsByReportKey,
|
|
56
|
+
fiscalCalculator: fiscalCalculator,
|
|
57
|
+
splits: splits,
|
|
58
|
+
minYear: minYear,
|
|
59
|
+
maxYear: maxYear,
|
|
60
|
+
cik: reportsCik,
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
ReportRawBuilder.prototype.createReportKey = function (params) {
|
|
64
|
+
var year = params.year, quarter = params.quarter, isAnnual = params.isAnnual;
|
|
65
|
+
return "".concat(year, "_").concat(isAnnual ? 'FY' : "Q".concat(quarter));
|
|
66
|
+
};
|
|
67
|
+
ReportRawBuilder.prototype.createReport = function (params) {
|
|
68
|
+
var _a;
|
|
69
|
+
var group = params.group, isAnnual = params.isAnnual, splitDate = params.splitDate, splitRatio = params.splitRatio, cik = params.cik;
|
|
70
|
+
var fiscalPeriod = isAnnual ? 'FY' : "Q".concat(group.quarter);
|
|
71
|
+
var accessionNoHyphen = (_a = group.accn) === null || _a === void 0 ? void 0 : _a.replace(/-/g, '');
|
|
72
|
+
var url = group.accn
|
|
73
|
+
? "https://www.sec.gov/Archives/edgar/data/".concat(cik, "/").concat(accessionNoHyphen, "/").concat(group.accn, ".txt")
|
|
74
|
+
: null;
|
|
75
|
+
return {
|
|
76
|
+
cik: cik,
|
|
77
|
+
url: url,
|
|
78
|
+
dateFiled: group.reportFiled,
|
|
79
|
+
dateReport: group.reportEnd,
|
|
80
|
+
fiscalPeriod: fiscalPeriod,
|
|
81
|
+
fiscalYear: group.fiscalYear,
|
|
82
|
+
splitDate: splitDate !== null && splitDate !== void 0 ? splitDate : null,
|
|
83
|
+
splitRatio: splitRatio !== null && splitRatio !== void 0 ? splitRatio : null,
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
ReportRawBuilder.prototype.round = function (value) {
|
|
87
|
+
var multiplier = 1000000;
|
|
88
|
+
return typeof value === 'number' ? Math.round(value * multiplier) / multiplier : value;
|
|
89
|
+
};
|
|
90
|
+
ReportRawBuilder.prototype.buildReportsFromGroups = function (params) {
|
|
91
|
+
var _this = this;
|
|
92
|
+
var factGroupsByReportKey = params.factGroupsByReportKey, minYear = params.minYear, maxYear = params.maxYear, cik = params.cik, splits = params.splits, fiscalCalculator = params.fiscalCalculator;
|
|
93
|
+
var splitByFiscals = new Map();
|
|
94
|
+
var reportByKey = new Map();
|
|
95
|
+
splits === null || splits === void 0 ? void 0 : splits.forEach(function (split) {
|
|
96
|
+
var _a = fiscalCalculator.getFiscalYearQuarter({ dateStr: split.endLast }), quarter = _a.quarter, year = _a.year;
|
|
97
|
+
splitByFiscals.set("".concat(year, "_").concat(quarter), split);
|
|
98
|
+
});
|
|
99
|
+
factGroupsByReportKey.forEach(function (groups) {
|
|
100
|
+
var _a, _b, _c, _d, _e, _f;
|
|
101
|
+
var groupWithDates = groups.find(function (g) { return g.reportEnd; });
|
|
102
|
+
if (!groupWithDates)
|
|
103
|
+
return;
|
|
104
|
+
var split = splitByFiscals.get("".concat(groupWithDates.fiscalYear, "_").concat(groupWithDates.quarter));
|
|
105
|
+
var splitDate = (_a = split === null || split === void 0 ? void 0 : split.endLast) !== null && _a !== void 0 ? _a : null;
|
|
106
|
+
var splitRatio = (_b = split === null || split === void 0 ? void 0 : split.splitRatio) !== null && _b !== void 0 ? _b : null;
|
|
107
|
+
var quarter = groupWithDates.quarter;
|
|
108
|
+
var reportPeriod = _this.createReport({
|
|
109
|
+
group: groupWithDates,
|
|
110
|
+
cik: cik,
|
|
111
|
+
isAnnual: false,
|
|
112
|
+
splitDate: splitDate,
|
|
113
|
+
splitRatio: splitRatio,
|
|
114
|
+
});
|
|
115
|
+
var reportKeyPeriod = _this.createReportKey({
|
|
116
|
+
year: reportPeriod.fiscalYear,
|
|
117
|
+
quarter: quarter,
|
|
118
|
+
isAnnual: false,
|
|
119
|
+
});
|
|
120
|
+
for (var _i = 0, groups_1 = groups; _i < groups_1.length; _i++) {
|
|
121
|
+
var group = groups_1[_i];
|
|
122
|
+
var value = (_d = (_c = group.valuePeriodResolved) !== null && _c !== void 0 ? _c : group.valuePeriodFirst) !== null && _d !== void 0 ? _d : 0;
|
|
123
|
+
reportPeriod[group.name] = _this.round(value);
|
|
124
|
+
}
|
|
125
|
+
reportByKey.set(reportKeyPeriod, reportPeriod);
|
|
126
|
+
if (quarter !== 4)
|
|
127
|
+
return;
|
|
128
|
+
var reportAnnual = _this.createReport({
|
|
129
|
+
group: groupWithDates,
|
|
130
|
+
cik: cik,
|
|
131
|
+
isAnnual: true,
|
|
132
|
+
splitDate: splitDate,
|
|
133
|
+
splitRatio: splitRatio,
|
|
134
|
+
});
|
|
135
|
+
var reportKeyAnnual = "".concat(reportAnnual.fiscalYear, "_").concat(reportAnnual.fiscalPeriod);
|
|
136
|
+
for (var _g = 0, groups_2 = groups; _g < groups_2.length; _g++) {
|
|
137
|
+
var group = groups_2[_g];
|
|
138
|
+
var value = (_f = (_e = group.valueTrailingResolved) !== null && _e !== void 0 ? _e : group.valueTrailingFirst) !== null && _f !== void 0 ? _f : 0;
|
|
139
|
+
reportAnnual[group.name] = _this.round(value);
|
|
140
|
+
}
|
|
141
|
+
reportByKey.set(reportKeyAnnual, reportAnnual);
|
|
142
|
+
});
|
|
143
|
+
var reports = [];
|
|
144
|
+
for (var year = minYear; year <= maxYear; year++) {
|
|
145
|
+
for (var quarter = 1; quarter <= 5; quarter++) {
|
|
146
|
+
var isAnnual = quarter === 5;
|
|
147
|
+
var reportKey = this.createReportKey({ year: year, quarter: isAnnual ? 4 : quarter, isAnnual: isAnnual });
|
|
148
|
+
var report = reportByKey.get(reportKey);
|
|
149
|
+
if (report) {
|
|
150
|
+
reports.push(report);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return reports;
|
|
155
|
+
};
|
|
156
|
+
return ReportRawBuilder;
|
|
157
|
+
}());
|
|
158
|
+
exports.default = ReportRawBuilder;
|
|
@@ -25,11 +25,19 @@ export interface GetSymbolParams {
|
|
|
25
25
|
/** symbol or cik */
|
|
26
26
|
symbol: string | number;
|
|
27
27
|
}
|
|
28
|
-
export interface
|
|
28
|
+
export interface GetReportsRawParams {
|
|
29
|
+
symbol: string | number;
|
|
30
|
+
includeNamePrefix?: boolean;
|
|
31
|
+
adjustForSplits?: boolean;
|
|
32
|
+
resolvePeriodValues?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface GetReportsParams extends Omit<GetReportsRawParams, 'includeNamePrefix'> {
|
|
29
35
|
/** symbol or cik */
|
|
30
36
|
symbol: string | number;
|
|
31
37
|
withWrapper?: boolean;
|
|
32
38
|
usePropertyResolver?: boolean;
|
|
39
|
+
adjustForSplits?: boolean;
|
|
40
|
+
resolvePeriodValues?: boolean;
|
|
33
41
|
}
|
|
34
42
|
export interface GetFactParams {
|
|
35
43
|
/** symbol or cik */
|
|
@@ -138,7 +146,7 @@ export default class SecEdgarApi {
|
|
|
138
146
|
* Parses reports from company facts. Calculates missing properties and uses a single interface
|
|
139
147
|
* for all reports.
|
|
140
148
|
*/
|
|
141
|
-
getReportsRaw(params:
|
|
149
|
+
getReportsRaw(params: GetReportsRawParams): Promise<ReportRaw[]>;
|
|
142
150
|
/**
|
|
143
151
|
* Gets a list of all tickers and CIKs from `https://www.sec.gov/files/company_tickers.json`
|
|
144
152
|
*
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
2
13
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
14
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
15
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -251,15 +262,15 @@ var SecEdgarApi = /** @class */ (function () {
|
|
|
251
262
|
*/
|
|
252
263
|
SecEdgarApi.prototype.getReports = function (params) {
|
|
253
264
|
return __awaiter(this, void 0, void 0, function () {
|
|
254
|
-
var
|
|
265
|
+
var _a, withWrapper, _b, usePropertyResolver, reportsRaw, reports;
|
|
255
266
|
return __generator(this, function (_c) {
|
|
256
267
|
switch (_c.label) {
|
|
257
268
|
case 0:
|
|
258
|
-
|
|
259
|
-
return [4 /*yield*/, this.
|
|
269
|
+
_a = params.withWrapper, withWrapper = _a === void 0 ? false : _a, _b = params.usePropertyResolver, usePropertyResolver = _b === void 0 ? true : _b;
|
|
270
|
+
return [4 /*yield*/, this.getReportsRaw(__assign(__assign({}, params), { includeNamePrefix: false }))];
|
|
260
271
|
case 1:
|
|
261
|
-
|
|
262
|
-
reports = this.reportParser.
|
|
272
|
+
reportsRaw = _c.sent();
|
|
273
|
+
reports = this.reportParser.parseReportsFromRaw(reportsRaw, usePropertyResolver);
|
|
263
274
|
return [2 /*return*/, withWrapper ? reports : reports.map(function (report) { return report.getReport(); })];
|
|
264
275
|
}
|
|
265
276
|
});
|
|
@@ -271,13 +282,20 @@ var SecEdgarApi = /** @class */ (function () {
|
|
|
271
282
|
*/
|
|
272
283
|
SecEdgarApi.prototype.getReportsRaw = function (params) {
|
|
273
284
|
return __awaiter(this, void 0, void 0, function () {
|
|
274
|
-
var
|
|
275
|
-
return __generator(this, function (
|
|
276
|
-
switch (
|
|
277
|
-
case 0:
|
|
285
|
+
var symbol, _a, includeNamePrefix, _b, adjustForSplits, _c, resolvePeriodValues, companyFacts, reports;
|
|
286
|
+
return __generator(this, function (_d) {
|
|
287
|
+
switch (_d.label) {
|
|
288
|
+
case 0:
|
|
289
|
+
symbol = params.symbol, _a = params.includeNamePrefix, includeNamePrefix = _a === void 0 ? false : _a, _b = params.adjustForSplits, adjustForSplits = _b === void 0 ? true : _b, _c = params.resolvePeriodValues, resolvePeriodValues = _c === void 0 ? true : _c;
|
|
290
|
+
return [4 /*yield*/, this.getFacts({ symbol: symbol })];
|
|
278
291
|
case 1:
|
|
279
|
-
|
|
280
|
-
|
|
292
|
+
companyFacts = _d.sent();
|
|
293
|
+
reports = this.reportParser.parseReportsRaw(companyFacts, {
|
|
294
|
+
adjustForSplits: adjustForSplits,
|
|
295
|
+
resolvePeriodValues: resolvePeriodValues,
|
|
296
|
+
includeNamePrefix: includeNamePrefix,
|
|
297
|
+
});
|
|
298
|
+
return [2 /*return*/, reports];
|
|
281
299
|
}
|
|
282
300
|
});
|
|
283
301
|
});
|