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.
- 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 -46
- package/build/services/ReportBuilder/FactSplitAdjuster.js +0 -203
- package/build/services/ReportBuilder/ReportBuilder.d.ts +0 -40
- package/build/services/ReportBuilder/ReportBuilder.js +0 -186
- 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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FactItem } from './company-facts.type';
|
|
1
2
|
export interface XMLParams {
|
|
2
3
|
xml: string;
|
|
3
4
|
}
|
|
@@ -10,3 +11,43 @@ export interface FieldDataResponse<Field extends string = string> {
|
|
|
10
11
|
fields: Field[];
|
|
11
12
|
data: (string | number)[][];
|
|
12
13
|
}
|
|
14
|
+
export interface SplitData {
|
|
15
|
+
filedFirst: string;
|
|
16
|
+
filedLast: string;
|
|
17
|
+
endFirst: string;
|
|
18
|
+
endLast: string;
|
|
19
|
+
splitRatio: number;
|
|
20
|
+
}
|
|
21
|
+
export interface FactGroup {
|
|
22
|
+
name: string;
|
|
23
|
+
unit: string;
|
|
24
|
+
accn: string;
|
|
25
|
+
reportEnd: string;
|
|
26
|
+
reportFiled: string;
|
|
27
|
+
isResolverGenerated: boolean;
|
|
28
|
+
filedFirst: string;
|
|
29
|
+
filedLast: string;
|
|
30
|
+
endFirst: string;
|
|
31
|
+
endLast: string;
|
|
32
|
+
values: number[];
|
|
33
|
+
fiscalYear: number;
|
|
34
|
+
quarter: number;
|
|
35
|
+
facts: FactItem[];
|
|
36
|
+
valueSplitAdjustedPeriod: number | null;
|
|
37
|
+
valueSplitAdjustedTrailing: number | null;
|
|
38
|
+
valuePeriodResolved: number | null;
|
|
39
|
+
valueTrailingResolved: number | null;
|
|
40
|
+
valuePeriodFirst: number | null;
|
|
41
|
+
valuePeriodLast: number | null;
|
|
42
|
+
valueTrailingFirst: number | null;
|
|
43
|
+
valueTrailingLast: number | null;
|
|
44
|
+
}
|
|
45
|
+
export interface FactItemExtended extends FactItem {
|
|
46
|
+
period: number;
|
|
47
|
+
year: number;
|
|
48
|
+
quarter: number;
|
|
49
|
+
periodValue: number | null;
|
|
50
|
+
trailingValue: number | null;
|
|
51
|
+
splitValue: number | null;
|
|
52
|
+
splitsApplied: number[];
|
|
53
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FiscalPeriod } from './report-raw.type';
|
|
1
2
|
export interface CompanyFactListData {
|
|
2
3
|
cik: number;
|
|
3
4
|
entityName: string;
|
|
@@ -6,11 +7,12 @@ export interface CompanyFactListData {
|
|
|
6
7
|
export interface CompanyFactList {
|
|
7
8
|
dei: Record<string, CompanyFact>;
|
|
8
9
|
invest?: Record<string, CompanyFact>;
|
|
10
|
+
srt?: Record<string, CompanyFact>;
|
|
9
11
|
'us-gaap'?: Record<string, CompanyFact>;
|
|
10
12
|
}
|
|
11
13
|
export interface CompanyFact {
|
|
12
|
-
label: string;
|
|
13
|
-
description: string;
|
|
14
|
+
label: string | null;
|
|
15
|
+
description: string | null;
|
|
14
16
|
units: Record<string, FactValue[]>;
|
|
15
17
|
}
|
|
16
18
|
export interface FactValue {
|
|
@@ -51,3 +53,28 @@ export interface MultiCompanyFactFrame {
|
|
|
51
53
|
pts: number;
|
|
52
54
|
data: MultiCompanyFactFrameItem[];
|
|
53
55
|
}
|
|
56
|
+
export interface FactItem {
|
|
57
|
+
cik: number | string;
|
|
58
|
+
end: string;
|
|
59
|
+
filed: string;
|
|
60
|
+
name: string;
|
|
61
|
+
unit: string;
|
|
62
|
+
value: number | string;
|
|
63
|
+
start?: string;
|
|
64
|
+
hasSegments?: boolean;
|
|
65
|
+
accn?: string;
|
|
66
|
+
form?: string;
|
|
67
|
+
fp?: string;
|
|
68
|
+
frame?: string;
|
|
69
|
+
fy?: number;
|
|
70
|
+
/** For XBRL reports only */
|
|
71
|
+
segments?: {
|
|
72
|
+
value: string;
|
|
73
|
+
dimension: string;
|
|
74
|
+
}[];
|
|
75
|
+
uuid?: string;
|
|
76
|
+
}
|
|
77
|
+
export interface FactItemWithFiscals extends FactItem {
|
|
78
|
+
fiscalPeriod: FiscalPeriod;
|
|
79
|
+
year: number;
|
|
80
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { FactItem } from './ReportBuilder';
|
|
2
|
-
import { CompanyFactListData } from '../../types';
|
|
3
|
-
/**
|
|
4
|
-
* Builds an array of fact records.
|
|
5
|
-
*/
|
|
6
|
-
export default class FactRecordBuilder {
|
|
7
|
-
createFacts(data: CompanyFactListData, filterDuplicates?: boolean): {
|
|
8
|
-
facts: FactItem[];
|
|
9
|
-
};
|
|
10
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { FiscalPeriod } from '../../types/report-raw.type';
|
|
2
|
-
import { FactItemWithFiscals } from './ReportBuilder';
|
|
3
|
-
interface SplitData {
|
|
4
|
-
end: string;
|
|
5
|
-
filed: string;
|
|
6
|
-
value: number;
|
|
7
|
-
firstFiled: string;
|
|
8
|
-
fiscalYear: number;
|
|
9
|
-
}
|
|
10
|
-
type FactItemWithFiscalsNumeric = Omit<FactItemWithFiscals, 'cik' | 'value'> & {
|
|
11
|
-
value: number;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Adjust share-based property values for splits. Checks where the split was applied,
|
|
15
|
-
* and adjusts all previously filed share facts accordingly.
|
|
16
|
-
*/
|
|
17
|
-
export default class FactSplitAdjuster {
|
|
18
|
-
private readonly splitKey;
|
|
19
|
-
private readonly splitByFiscalYearAmount;
|
|
20
|
-
private readonly factsByYearQuarterByPropertyName;
|
|
21
|
-
private readonly factsAnnaulByYearByPropertyName;
|
|
22
|
-
private readonly resolvedProperties;
|
|
23
|
-
private sortedSplits;
|
|
24
|
-
private getMap;
|
|
25
|
-
add(fact: FactItemWithFiscalsNumeric): void;
|
|
26
|
-
getSplitsAsc(): SplitData[];
|
|
27
|
-
isSplitProperty(propertyName: string): boolean;
|
|
28
|
-
addSplitData(data: Omit<SplitData, 'firstFiled'>): void;
|
|
29
|
-
/**
|
|
30
|
-
* TODO: Find a more reliable way of checking if the split has already been applied.
|
|
31
|
-
*/
|
|
32
|
-
private didApplySplit;
|
|
33
|
-
isSplitAdjustableUnit(unit: string): boolean;
|
|
34
|
-
isShareRatioUnit(unit: string): boolean;
|
|
35
|
-
private getSortedFacts;
|
|
36
|
-
resolveProperty(propertyName: string): void;
|
|
37
|
-
get(propertyName: string, year: number, fiscalPeriod: FiscalPeriod): number | undefined;
|
|
38
|
-
forEach(callback: (params: {
|
|
39
|
-
propertyName: string;
|
|
40
|
-
year: number;
|
|
41
|
-
fiscalPeriod: FiscalPeriod;
|
|
42
|
-
value: number;
|
|
43
|
-
}) => void): void;
|
|
44
|
-
private adjustValuesForSplits;
|
|
45
|
-
}
|
|
46
|
-
export {};
|
|
@@ -1,203 +0,0 @@
|
|
|
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
|
-
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
|
-
*/
|
|
18
|
-
var FactSplitAdjuster = /** @class */ (function () {
|
|
19
|
-
function FactSplitAdjuster() {
|
|
20
|
-
this.splitKey = 'StockholdersEquityNoteStockSplitConversionRatio1';
|
|
21
|
-
this.splitByFiscalYearAmount = new Map();
|
|
22
|
-
this.factsByYearQuarterByPropertyName = new Map();
|
|
23
|
-
this.factsAnnaulByYearByPropertyName = new Map();
|
|
24
|
-
this.resolvedProperties = new Set();
|
|
25
|
-
this.sortedSplits = null;
|
|
26
|
-
}
|
|
27
|
-
FactSplitAdjuster.prototype.getMap = function (map, propertyName) {
|
|
28
|
-
var _a;
|
|
29
|
-
return (_a = map.get(propertyName)) !== null && _a !== void 0 ? _a : map.set(propertyName, new Map()).get(propertyName);
|
|
30
|
-
};
|
|
31
|
-
FactSplitAdjuster.prototype.add = function (fact) {
|
|
32
|
-
var propertyName = fact.name, year = fact.year, fiscalPeriod = fact.fiscalPeriod, unit = fact.unit, filed = fact.filed, value = fact.value, end = fact.end;
|
|
33
|
-
if (this.isSplitProperty(propertyName)) {
|
|
34
|
-
this.addSplitData({ end: end, filed: filed, fiscalYear: year, value: Number(value) });
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (!this.isSplitAdjustableUnit(unit))
|
|
38
|
-
return;
|
|
39
|
-
if (this.resolvedProperties.has(propertyName)) {
|
|
40
|
-
throw new Error("Property ".concat(propertyName, " has already been resolved"));
|
|
41
|
-
}
|
|
42
|
-
var isAnnual = fiscalPeriod === 'FY';
|
|
43
|
-
var map = isAnnual
|
|
44
|
-
? this.getMap(this.factsAnnaulByYearByPropertyName, propertyName)
|
|
45
|
-
: this.getMap(this.factsByYearQuarterByPropertyName, propertyName);
|
|
46
|
-
var key = "".concat(year, "_").concat(fiscalPeriod);
|
|
47
|
-
map.set(key, fact);
|
|
48
|
-
};
|
|
49
|
-
FactSplitAdjuster.prototype.getSplitsAsc = function () {
|
|
50
|
-
if (this.sortedSplits)
|
|
51
|
-
return this.sortedSplits;
|
|
52
|
-
var sortedSplits = Array.from(this.splitByFiscalYearAmount.values()).sort(function (a, b) {
|
|
53
|
-
return a.filed < b.filed ? -1 : 1;
|
|
54
|
-
});
|
|
55
|
-
this.sortedSplits = sortedSplits;
|
|
56
|
-
return sortedSplits;
|
|
57
|
-
};
|
|
58
|
-
FactSplitAdjuster.prototype.isSplitProperty = function (propertyName) {
|
|
59
|
-
return propertyName === this.splitKey;
|
|
60
|
-
};
|
|
61
|
-
FactSplitAdjuster.prototype.addSplitData = function (data) {
|
|
62
|
-
var end = data.end, filed = data.filed, fiscalYear = data.fiscalYear, value = data.value;
|
|
63
|
-
var split = value;
|
|
64
|
-
var key = "".concat(fiscalYear, "-").concat(split);
|
|
65
|
-
var prevSplit = this.splitByFiscalYearAmount.get(key);
|
|
66
|
-
if (!prevSplit) {
|
|
67
|
-
this.splitByFiscalYearAmount.set(key, __assign(__assign({}, data), { firstFiled: filed }));
|
|
68
|
-
this.sortedSplits = null;
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
var curEnd = end;
|
|
72
|
-
var curFiled = filed;
|
|
73
|
-
var prevEnd = prevSplit.end;
|
|
74
|
-
var prevFiled = prevSplit.filed;
|
|
75
|
-
var shouldUpdateFactItem = !prevSplit || prevEnd < curEnd || (prevEnd === curEnd && prevFiled > curFiled);
|
|
76
|
-
var shouldUpdateFirstFiled = prevFiled > curFiled;
|
|
77
|
-
if (shouldUpdateFactItem) {
|
|
78
|
-
var curData = this.splitByFiscalYearAmount.get(key);
|
|
79
|
-
curData.end = end;
|
|
80
|
-
curData.filed = filed;
|
|
81
|
-
curData.value = value;
|
|
82
|
-
curData.fiscalYear = fiscalYear;
|
|
83
|
-
this.sortedSplits = null;
|
|
84
|
-
}
|
|
85
|
-
if (shouldUpdateFirstFiled) {
|
|
86
|
-
var curData = this.splitByFiscalYearAmount.get(key);
|
|
87
|
-
curData.firstFiled = curFiled;
|
|
88
|
-
this.sortedSplits = null;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
/**
|
|
92
|
-
* TODO: Find a more reliable way of checking if the split has already been applied.
|
|
93
|
-
*/
|
|
94
|
-
FactSplitAdjuster.prototype.didApplySplit = function (params) {
|
|
95
|
-
var nextValue = params.nextValue, prevValue = params.prevValue, split = params.split, isShareRatio = params.isShareRatio, value = params.value, filed = params.filed;
|
|
96
|
-
if (filed > split.filed) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
var dateFiled = new Date(filed);
|
|
100
|
-
// TODO: adust by adding a year because sometimes the already adjusted facts are filed within the
|
|
101
|
-
// year before the split. this might be because the split is listed under a different property? Look into this...
|
|
102
|
-
if (dateFiled.setFullYear(dateFiled.getFullYear() + 1) < new Date(split.firstFiled).getTime()) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
var valWithSplit = isShareRatio ? value / split.value : value * split.value;
|
|
106
|
-
// if we still don't know, see if applying the split puts us closer or further from the prev/next quarter value.
|
|
107
|
-
if (prevValue !== null) {
|
|
108
|
-
var difference = Math.abs(prevValue - value);
|
|
109
|
-
var differenceSplit = Math.abs(prevValue - valWithSplit);
|
|
110
|
-
return difference < differenceSplit;
|
|
111
|
-
}
|
|
112
|
-
if (nextValue !== null) {
|
|
113
|
-
var difference = Math.abs(nextValue - value);
|
|
114
|
-
var differenceSplit = Math.abs(nextValue - valWithSplit);
|
|
115
|
-
return difference < differenceSplit;
|
|
116
|
-
}
|
|
117
|
-
return true;
|
|
118
|
-
};
|
|
119
|
-
FactSplitAdjuster.prototype.isSplitAdjustableUnit = function (unit) {
|
|
120
|
-
return unit.toLowerCase().includes('share');
|
|
121
|
-
};
|
|
122
|
-
FactSplitAdjuster.prototype.isShareRatioUnit = function (unit) {
|
|
123
|
-
var unitLower = unit.toLowerCase();
|
|
124
|
-
return unitLower !== 'shares' && unitLower.includes('share'); // ex: USD/shares or USD-per-share
|
|
125
|
-
};
|
|
126
|
-
FactSplitAdjuster.prototype.getSortedFacts = function (propertyName, isAnnual) {
|
|
127
|
-
var _a, _b, _c;
|
|
128
|
-
var bucket = isAnnual ? this.factsAnnaulByYearByPropertyName : this.factsByYearQuarterByPropertyName;
|
|
129
|
-
var facts = Array.from((_b = (_a = bucket.get(propertyName)) === null || _a === void 0 ? void 0 : _a.values()) !== null && _b !== void 0 ? _b : []);
|
|
130
|
-
return (_c = facts.sort(function (a, b) { return (a.filed < b.filed ? -1 : 1); })) !== null && _c !== void 0 ? _c : [];
|
|
131
|
-
};
|
|
132
|
-
FactSplitAdjuster.prototype.resolveProperty = function (propertyName) {
|
|
133
|
-
if (this.resolvedProperties.has(propertyName))
|
|
134
|
-
return;
|
|
135
|
-
var factsAscQuarter = this.getSortedFacts(propertyName, false);
|
|
136
|
-
var factsAscAnnual = this.getSortedFacts(propertyName, true);
|
|
137
|
-
this.adjustValuesForSplits({ facts: factsAscQuarter });
|
|
138
|
-
this.adjustValuesForSplits({ facts: factsAscAnnual });
|
|
139
|
-
this.resolvedProperties.add(propertyName);
|
|
140
|
-
};
|
|
141
|
-
FactSplitAdjuster.prototype.get = function (propertyName, year, fiscalPeriod) {
|
|
142
|
-
var _a;
|
|
143
|
-
this.resolveProperty(propertyName);
|
|
144
|
-
var key = "".concat(year, "_").concat(fiscalPeriod);
|
|
145
|
-
var isAnnual = fiscalPeriod === 'FY';
|
|
146
|
-
var bucket = isAnnual ? this.factsAnnaulByYearByPropertyName : this.factsByYearQuarterByPropertyName;
|
|
147
|
-
var fact = (_a = bucket.get(propertyName)) === null || _a === void 0 ? void 0 : _a.get(key);
|
|
148
|
-
return fact === null || fact === void 0 ? void 0 : fact.value;
|
|
149
|
-
};
|
|
150
|
-
FactSplitAdjuster.prototype.forEach = function (callback) {
|
|
151
|
-
var _this = this;
|
|
152
|
-
this.factsByYearQuarterByPropertyName.forEach(function (factsByYearQuarter, propertyName) {
|
|
153
|
-
_this.resolveProperty(propertyName);
|
|
154
|
-
factsByYearQuarter.forEach(function (fact, key) {
|
|
155
|
-
var _a = key.split('_'), year = _a[0], fiscalPeriod = _a[1];
|
|
156
|
-
callback({ propertyName: propertyName, year: Number(year), fiscalPeriod: fiscalPeriod, value: Number(fact.value) });
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
this.factsAnnaulByYearByPropertyName.forEach(function (factsByYear, propertyName) {
|
|
160
|
-
_this.resolveProperty(propertyName);
|
|
161
|
-
factsByYear.forEach(function (fact, key) {
|
|
162
|
-
var _a = key.split('_'), year = _a[0], fiscalPeriod = _a[1];
|
|
163
|
-
callback({ propertyName: propertyName, year: Number(year), fiscalPeriod: fiscalPeriod, value: Number(fact.value) });
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
};
|
|
167
|
-
FactSplitAdjuster.prototype.adjustValuesForSplits = function (params) {
|
|
168
|
-
var _a, _b, _c, _d;
|
|
169
|
-
var facts = params.facts;
|
|
170
|
-
var splits = this.getSplitsAsc();
|
|
171
|
-
if (facts.length === 0 || splits.length === 0)
|
|
172
|
-
return;
|
|
173
|
-
var isShareRatio = this.isShareRatioUnit(facts[0].unit);
|
|
174
|
-
for (var splitIndex = splits.length - 1; splitIndex >= 0; splitIndex--) {
|
|
175
|
-
var split = splits[splitIndex];
|
|
176
|
-
for (var factIndex = facts.length - 1; factIndex >= 0; factIndex--) {
|
|
177
|
-
var fact = facts[factIndex];
|
|
178
|
-
var value = fact.value, filed = fact.filed;
|
|
179
|
-
var nextValue = (_b = (_a = facts[factIndex + 1]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null;
|
|
180
|
-
var prevValue = (_d = (_c = facts[factIndex - 1]) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : null;
|
|
181
|
-
var didApplySplit = this.didApplySplit({
|
|
182
|
-
filed: filed,
|
|
183
|
-
isShareRatio: isShareRatio,
|
|
184
|
-
nextValue: nextValue,
|
|
185
|
-
prevValue: prevValue,
|
|
186
|
-
split: split,
|
|
187
|
-
value: value,
|
|
188
|
-
});
|
|
189
|
-
if (didApplySplit || !split.value) {
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
if (isShareRatio) {
|
|
193
|
-
fact.value /= split.value;
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
fact.value *= split.value;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
return FactSplitAdjuster;
|
|
202
|
-
}());
|
|
203
|
-
exports.default = FactSplitAdjuster;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { CompanyFactListData, FiscalPeriod, ReportRaw } from '../../types';
|
|
2
|
-
import { SetReportDatesParams } from './FactFiscalCalculator';
|
|
3
|
-
export interface FactItem {
|
|
4
|
-
cik: number | string;
|
|
5
|
-
end: string;
|
|
6
|
-
filed: string;
|
|
7
|
-
name: string;
|
|
8
|
-
unit: string;
|
|
9
|
-
value: number | string;
|
|
10
|
-
start?: string;
|
|
11
|
-
hasSegments?: boolean;
|
|
12
|
-
accn?: string;
|
|
13
|
-
form?: string;
|
|
14
|
-
fp?: string;
|
|
15
|
-
frame?: string;
|
|
16
|
-
fy?: number;
|
|
17
|
-
/** For XBRL reports only */
|
|
18
|
-
segments?: {
|
|
19
|
-
value: string;
|
|
20
|
-
dimension: string;
|
|
21
|
-
}[];
|
|
22
|
-
uuid?: string;
|
|
23
|
-
}
|
|
24
|
-
export interface FactItemWithFiscals extends FactItem {
|
|
25
|
-
fiscalPeriod: FiscalPeriod;
|
|
26
|
-
year: number;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Builds ReportRaw objects from facts. also applies splits and adjusts for fiscal periods.
|
|
30
|
-
*/
|
|
31
|
-
export default class ReportBuilder {
|
|
32
|
-
private readonly factRecordBuilder;
|
|
33
|
-
createFacts(companyFacts: CompanyFactListData): {
|
|
34
|
-
facts: FactItem[];
|
|
35
|
-
};
|
|
36
|
-
buildReports(params: {
|
|
37
|
-
facts: FactItem[];
|
|
38
|
-
reportDates?: SetReportDatesParams[];
|
|
39
|
-
}): ReportRaw[];
|
|
40
|
-
}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var FactFiscalCalculator_1 = require("./FactFiscalCalculator");
|
|
4
|
-
var FactPeriodResolver_1 = require("./FactPeriodResolver");
|
|
5
|
-
var FactRecordBuilder_1 = require("./FactRecordBuilder");
|
|
6
|
-
var FactSplitAdjuster_1 = require("./FactSplitAdjuster");
|
|
7
|
-
/**
|
|
8
|
-
* Builds ReportRaw objects from facts. also applies splits and adjusts for fiscal periods.
|
|
9
|
-
*/
|
|
10
|
-
var ReportBuilder = /** @class */ (function () {
|
|
11
|
-
function ReportBuilder() {
|
|
12
|
-
this.factRecordBuilder = new FactRecordBuilder_1.default();
|
|
13
|
-
}
|
|
14
|
-
ReportBuilder.prototype.createFacts = function (companyFacts) {
|
|
15
|
-
return this.factRecordBuilder.createFacts(companyFacts);
|
|
16
|
-
};
|
|
17
|
-
ReportBuilder.prototype.buildReports = function (params) {
|
|
18
|
-
var _a, _b, _c, _d, _e;
|
|
19
|
-
var facts = params.facts, reportDates = params.reportDates;
|
|
20
|
-
if (facts.length === 0) {
|
|
21
|
-
return [];
|
|
22
|
-
}
|
|
23
|
-
var accessionByYearQuarter = new Map();
|
|
24
|
-
reportDates === null || reportDates === void 0 ? void 0 : reportDates.forEach(function (params) {
|
|
25
|
-
var year = params.year, quarter = params.quarter, accn = params.accn;
|
|
26
|
-
if (accn)
|
|
27
|
-
accessionByYearQuarter.set("".concat(year, "_").concat(quarter), accn);
|
|
28
|
-
});
|
|
29
|
-
var reportsCik = Number(facts[0].cik);
|
|
30
|
-
var factFiscalCalculator = new FactFiscalCalculator_1.default();
|
|
31
|
-
var factPeriodResolver = new FactPeriodResolver_1.default({ cik: reportsCik });
|
|
32
|
-
var factSplitAdjuster = new FactSplitAdjuster_1.default();
|
|
33
|
-
facts.forEach(function (fact) { return factFiscalCalculator.add(fact); });
|
|
34
|
-
reportDates === null || reportDates === void 0 ? void 0 : reportDates.forEach(function (params) { return factFiscalCalculator.setReportDates(params); });
|
|
35
|
-
var unitByPropertyName = new Map();
|
|
36
|
-
var splitDateDataByKey = new Map();
|
|
37
|
-
var minYear = Infinity;
|
|
38
|
-
var maxYear = -Infinity;
|
|
39
|
-
var countByAccnByYearQuarter = new Map();
|
|
40
|
-
var filedByPropertyYearQuarterValue = new Map();
|
|
41
|
-
for (var _i = 0, facts_1 = facts; _i < facts_1.length; _i++) {
|
|
42
|
-
var fact = facts_1[_i];
|
|
43
|
-
var end = fact.end, name_1 = fact.name, unit = fact.unit, segments = fact.segments, start = fact.start, value = fact.value, cik = fact.cik, form = fact.form, filed = fact.filed, accn = fact.accn;
|
|
44
|
-
if (Number(fact.cik) !== Number(reportsCik)) {
|
|
45
|
-
throw new Error("All facts must have the same cik ".concat(reportsCik, " !== ").concat(Number(cik)));
|
|
46
|
-
}
|
|
47
|
-
var segmentValue = segments === null || segments === void 0 ? void 0 : segments.map(function (seg) { return "".concat(seg.dimension, "_").concat(seg.value); }).join('&');
|
|
48
|
-
var propertyName = (_a = name_1.split(':').pop()) !== null && _a !== void 0 ? _a : '';
|
|
49
|
-
var propertyNameWithSegment = propertyName + (segmentValue ? "_".concat(segmentValue) : '');
|
|
50
|
-
var _f = factFiscalCalculator.getFiscalYearQuarter({ dateStr: end }), quarter = _f.quarter, year = _f.year;
|
|
51
|
-
if (year < minYear)
|
|
52
|
-
minYear = year;
|
|
53
|
-
if (year > maxYear)
|
|
54
|
-
maxYear = year;
|
|
55
|
-
var splitKey = "".concat(year, "_").concat(value);
|
|
56
|
-
var factFiledKey = "".concat(year, "_").concat(quarter, "_").concat(propertyNameWithSegment, "_").concat(value);
|
|
57
|
-
var isSplit = factSplitAdjuster.isSplitProperty(propertyName);
|
|
58
|
-
unitByPropertyName.set(propertyNameWithSegment, unit);
|
|
59
|
-
filedByPropertyYearQuarterValue.set(factFiledKey, filed);
|
|
60
|
-
if (isSplit && new Date(end) > new Date((_c = (_b = splitDateDataByKey.get(splitKey)) === null || _b === void 0 ? void 0 : _b.end) !== null && _c !== void 0 ? _c : 0)) {
|
|
61
|
-
splitDateDataByKey.set(splitKey, { end: end, quarter: quarter });
|
|
62
|
-
}
|
|
63
|
-
var accnKey = "".concat(year, "_").concat(quarter);
|
|
64
|
-
var accnGiven = accessionByYearQuarter.get(accnKey);
|
|
65
|
-
var filedDistance = Math.abs(new Date(filed).getTime() - new Date(end !== null && end !== void 0 ? end : 0).getTime()) / 86400000;
|
|
66
|
-
var isFiledRecent = filedDistance < 60;
|
|
67
|
-
if (!accnGiven && isFiledRecent && accn && (!form || form === '10-K' || form === '10-Q')) {
|
|
68
|
-
var countByAccn = (_d = countByAccnByYearQuarter.get(accnKey)) !== null && _d !== void 0 ? _d : new Map();
|
|
69
|
-
countByAccn.set(accn, ((_e = countByAccn.get(accn)) !== null && _e !== void 0 ? _e : 0) + 1);
|
|
70
|
-
countByAccnByYearQuarter.set(accnKey, countByAccn);
|
|
71
|
-
}
|
|
72
|
-
factPeriodResolver.add({
|
|
73
|
-
year: year,
|
|
74
|
-
start: start,
|
|
75
|
-
end: end,
|
|
76
|
-
name: propertyNameWithSegment,
|
|
77
|
-
quarter: quarter,
|
|
78
|
-
value: value,
|
|
79
|
-
filed: filed,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
countByAccnByYearQuarter.forEach(function (countByAccn, yearQuarter) {
|
|
83
|
-
if (accessionByYearQuarter.has(yearQuarter))
|
|
84
|
-
return;
|
|
85
|
-
var maxCount = 0;
|
|
86
|
-
var accessionNumber = '';
|
|
87
|
-
countByAccn.forEach(function (count, accn) {
|
|
88
|
-
if (count > maxCount) {
|
|
89
|
-
maxCount = count;
|
|
90
|
-
accessionNumber = accn;
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
accessionByYearQuarter.set(yearQuarter, accessionNumber);
|
|
94
|
-
});
|
|
95
|
-
minYear = Number.isFinite(minYear) ? minYear : new Date().getFullYear();
|
|
96
|
-
maxYear = Number.isFinite(maxYear) ? maxYear : new Date().getFullYear();
|
|
97
|
-
var reportsByKey = new Map();
|
|
98
|
-
// resolves quarterly and annual properties and creates reports
|
|
99
|
-
factPeriodResolver.forEach(function (data) {
|
|
100
|
-
var _a, _b;
|
|
101
|
-
var fiscalPeriod = data.fiscalPeriod, propertyName = data.propertyName, value = data.value, year = data.year;
|
|
102
|
-
var key = "".concat(year, "_").concat(fiscalPeriod);
|
|
103
|
-
var quarter = fiscalPeriod === 'FY' ? 4 : Number(fiscalPeriod[1]);
|
|
104
|
-
var dates = factFiscalCalculator.getDatesByYearQuarter({ quarter: quarter, year: year });
|
|
105
|
-
var _c = dates !== null && dates !== void 0 ? dates : { filed: '', end: '' }, filed = _c.filed, end = _c.end;
|
|
106
|
-
var accessionNumber = accessionByYearQuarter.get("".concat(year, "_").concat(quarter));
|
|
107
|
-
var accessionNoHyphen = accessionNumber === null || accessionNumber === void 0 ? void 0 : accessionNumber.replace(/-/g, '');
|
|
108
|
-
var url = accessionNumber
|
|
109
|
-
? "https://www.sec.gov/Archives/edgar/data/".concat(reportsCik, "/").concat(accessionNoHyphen, "/").concat(accessionNumber, ".txt")
|
|
110
|
-
: null;
|
|
111
|
-
if (!reportsByKey.has(key)) {
|
|
112
|
-
reportsByKey.set(key, {
|
|
113
|
-
cik: reportsCik,
|
|
114
|
-
url: url,
|
|
115
|
-
dateFiled: filed,
|
|
116
|
-
dateReport: end,
|
|
117
|
-
fiscalPeriod: fiscalPeriod,
|
|
118
|
-
fiscalYear: year,
|
|
119
|
-
splitDate: null,
|
|
120
|
-
splitRatio: null,
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
var filedKey = "".concat(year, "_").concat(quarter, "_").concat(propertyName, "_").concat(value);
|
|
124
|
-
// add facts to adjust for splits
|
|
125
|
-
factSplitAdjuster.add({
|
|
126
|
-
end: end,
|
|
127
|
-
// use the original fact filed date instead of the report filed date to know if the fact has been split.
|
|
128
|
-
filed: (_a = filedByPropertyYearQuarterValue.get(filedKey)) !== null && _a !== void 0 ? _a : filed,
|
|
129
|
-
fiscalPeriod: fiscalPeriod,
|
|
130
|
-
name: propertyName,
|
|
131
|
-
unit: (_b = unitByPropertyName.get(propertyName)) !== null && _b !== void 0 ? _b : '',
|
|
132
|
-
year: year,
|
|
133
|
-
value: Number(value),
|
|
134
|
-
accn: accessionNumber !== null && accessionNumber !== void 0 ? accessionNumber : '',
|
|
135
|
-
});
|
|
136
|
-
var report = reportsByKey.get(key);
|
|
137
|
-
report[propertyName] = value;
|
|
138
|
-
});
|
|
139
|
-
// iterate through facts adjustable for splits and assign values to reports
|
|
140
|
-
factSplitAdjuster.forEach(function (data) {
|
|
141
|
-
var year = data.year, fiscalPeriod = data.fiscalPeriod, propertyName = data.propertyName, value = data.value;
|
|
142
|
-
var key = "".concat(year, "_").concat(fiscalPeriod);
|
|
143
|
-
var report = reportsByKey.get(key);
|
|
144
|
-
if (!report)
|
|
145
|
-
return;
|
|
146
|
-
report[propertyName] = Math.round(value * 10000) / 10000;
|
|
147
|
-
});
|
|
148
|
-
// add split dates and values to reports
|
|
149
|
-
factSplitAdjuster.getSplitsAsc().forEach(function (split) {
|
|
150
|
-
var _a, _b, _c, _d;
|
|
151
|
-
var _e = factFiscalCalculator.getFiscalYearQuarter({ dateStr: split.end }), quarter = _e.quarter, year = _e.year;
|
|
152
|
-
var keySplit = "".concat(year, "_").concat(split.value);
|
|
153
|
-
var splitDateData = (_a = splitDateDataByKey.get(keySplit)) !== null && _a !== void 0 ? _a : { end: null, quarter: null };
|
|
154
|
-
var splitDate = (_b = splitDateData.end) !== null && _b !== void 0 ? _b : split.filed;
|
|
155
|
-
var splitQuarter = (_c = splitDateData.quarter) !== null && _c !== void 0 ? _c : quarter;
|
|
156
|
-
var fiscalPeriod = "Q".concat(splitQuarter);
|
|
157
|
-
var keyReport = "".concat(year, "_").concat(fiscalPeriod);
|
|
158
|
-
var report = reportsByKey.get(keyReport);
|
|
159
|
-
var reportAnnual = splitQuarter === 4 ? (_d = reportsByKey.get("".concat(year, "_FY"))) !== null && _d !== void 0 ? _d : null : null;
|
|
160
|
-
if (report) {
|
|
161
|
-
report.splitRatio = split.value;
|
|
162
|
-
report.splitDate = splitDate;
|
|
163
|
-
}
|
|
164
|
-
// also assign to annual for Q4
|
|
165
|
-
if (reportAnnual) {
|
|
166
|
-
reportAnnual.splitRatio = split.value;
|
|
167
|
-
reportAnnual.splitDate = splitDate;
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
// sort reports ASC by year and quarter
|
|
171
|
-
var reportsSorted = [];
|
|
172
|
-
for (var year = minYear; year <= maxYear; year++) {
|
|
173
|
-
for (var i = 0; i < 5; i++) {
|
|
174
|
-
var fiscalPeriod = i === 4 ? 'FY' : "Q".concat(i + 1);
|
|
175
|
-
var key = "".concat(year, "_").concat(fiscalPeriod);
|
|
176
|
-
var report = reportsByKey.get(key);
|
|
177
|
-
if (report && report.dateReport) {
|
|
178
|
-
reportsSorted.push(report);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return reportsSorted;
|
|
183
|
-
};
|
|
184
|
-
return ReportBuilder;
|
|
185
|
-
}());
|
|
186
|
-
exports.default = ReportBuilder;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { ReportRaw } from '../../types';
|
|
2
|
-
export type TemplateCode = 'I' | 'T' | 'B' | 'M' | 'N' | 'U';
|
|
3
|
-
export default class ReportRawResolvable {
|
|
4
|
-
readonly report: ReportRaw;
|
|
5
|
-
private readonly emptyKeys;
|
|
6
|
-
private readonly addedProps;
|
|
7
|
-
private readonly calcMap;
|
|
8
|
-
private readonly templateCode;
|
|
9
|
-
private readonly keyStack;
|
|
10
|
-
constructor(report: ReportRaw, templateCode?: TemplateCode | null, calcMap?: Record<string, Record<string, string[]>>);
|
|
11
|
-
get(key: string): string | number | boolean | undefined;
|
|
12
|
-
getNumber(key: string): number;
|
|
13
|
-
isAdded(key: string): boolean;
|
|
14
|
-
private getChildKeysArr;
|
|
15
|
-
private calculateNumericKey;
|
|
16
|
-
toJSON(): ReportRaw;
|
|
17
|
-
}
|