sec-edgar-api 0.2.3 → 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.
Files changed (35) hide show
  1. package/README.md +1 -0
  2. package/build/services/ReportParser/ReportParser.d.ts +6 -13
  3. package/build/services/ReportParser/ReportParser.js +15 -22
  4. package/build/services/ReportRawBuilder/FactGrouper.d.ts +27 -0
  5. package/build/services/ReportRawBuilder/FactGrouper.js +206 -0
  6. package/build/services/{ReportBuilder → ReportRawBuilder}/FactPeriodResolver.d.ts +46 -2
  7. package/build/services/{ReportBuilder → ReportRawBuilder}/FactPeriodResolver.js +81 -20
  8. package/build/services/ReportRawBuilder/FactRecordBuilder.d.ts +9 -0
  9. package/build/services/{ReportBuilder → ReportRawBuilder}/FactRecordBuilder.js +6 -24
  10. package/build/services/ReportRawBuilder/FactSplitAdjuster.d.ts +43 -0
  11. package/build/services/ReportRawBuilder/FactSplitAdjuster.js +242 -0
  12. package/build/services/ReportRawBuilder/ReportRawBuilder.d.ts +39 -0
  13. package/build/services/ReportRawBuilder/ReportRawBuilder.js +158 -0
  14. package/build/services/ReportRawBuilder/index.d.ts +2 -0
  15. package/build/services/ReportRawBuilder/index.js +4 -0
  16. package/build/services/SecEdgarApi/SecEdgarApi.d.ts +10 -2
  17. package/build/services/SecEdgarApi/SecEdgarApi.js +29 -11
  18. package/build/types/common.type.d.ts +41 -0
  19. package/build/types/company-facts.type.d.ts +29 -2
  20. package/package.json +1 -1
  21. package/build/services/ReportBuilder/FactRecordBuilder.d.ts +0 -10
  22. package/build/services/ReportBuilder/FactSplitAdjuster.d.ts +0 -46
  23. package/build/services/ReportBuilder/FactSplitAdjuster.js +0 -203
  24. package/build/services/ReportBuilder/ReportBuilder.d.ts +0 -40
  25. package/build/services/ReportBuilder/ReportBuilder.js +0 -186
  26. package/build/services/ReportBuilder/ReportRawResolvable.d.ts +0 -17
  27. package/build/services/ReportBuilder/ReportRawResolvable.js +0 -114
  28. package/build/services/ReportBuilder/index.d.ts +0 -2
  29. package/build/services/ReportBuilder/index.js +0 -4
  30. package/build/services/ReportParser/ReportRawParser.d.ts +0 -5
  31. package/build/services/ReportParser/ReportRawParser.js +0 -14
  32. package/build/util/calculation-map-by-ns.d.ts +0 -6
  33. package/build/util/calculation-map-by-ns.js +0 -9
  34. /package/build/services/{ReportBuilder → ReportRawBuilder}/FactFiscalCalculator.d.ts +0 -0
  35. /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, filterDuplicates) {
10
- if (filterDuplicates === void 0) { filterDuplicates = true; }
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 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
- };
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 mapKey = createKey({ propertyName: propertyName, end: end, filed: filed, start: start });
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
- 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
- }
44
+ factItems.push(item);
63
45
  }
64
46
  }
65
47
  }
66
48
  }
67
- return { facts: Array.from(factsByKey.values()) };
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;
@@ -0,0 +1,2 @@
1
+ import ReportRawBuilder from './ReportRawBuilder';
2
+ export default ReportRawBuilder;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var ReportRawBuilder_1 = require("./ReportRawBuilder");
4
+ exports.default = ReportRawBuilder_1.default;
@@ -25,11 +25,19 @@ export interface GetSymbolParams {
25
25
  /** symbol or cik */
26
26
  symbol: string | number;
27
27
  }
28
- export interface GetReportsParams {
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: GetSymbolParams): Promise<ReportRaw[]>;
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 symbol, _a, withWrapper, _b, usePropertyResolver, facts, reports;
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
- symbol = params.symbol, _a = params.withWrapper, withWrapper = _a === void 0 ? false : _a, _b = params.usePropertyResolver, usePropertyResolver = _b === void 0 ? true : _b;
259
- return [4 /*yield*/, this.getFacts({ symbol: symbol })];
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
- facts = _c.sent();
262
- reports = this.reportParser.parseReports(facts, usePropertyResolver);
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 facts;
275
- return __generator(this, function (_a) {
276
- switch (_a.label) {
277
- case 0: return [4 /*yield*/, this.getFacts(params)];
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
- facts = _a.sent();
280
- return [2 /*return*/, this.reportParser.parseReportsRaw(facts)];
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
  });