sec-edgar-api 0.0.1 → 0.0.3
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 +153 -0
- package/build/.DS_Store +0 -0
- package/build/services/ReportParser/ReportParser.d.ts +4 -0
- package/build/services/ReportParser/ReportParser.js +19 -0
- package/build/services/SecEdgarApi/FactsDownloader.js +0 -1
- package/build/services/SecEdgarApi/SecEdgarApi.d.ts +8 -3
- package/build/services/SecEdgarApi/SecEdgarApi.js +8 -3
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -3,8 +3,134 @@
|
|
|
3
3
|
Fetch and parse earnings reports and other documents filed with the SEC using the EDGAR API.
|
|
4
4
|
This package is focused on the earnings reports for stock analysis.
|
|
5
5
|
|
|
6
|
+
## Report Interface
|
|
7
|
+
|
|
8
|
+
Reports are all returned as a uniform interface:
|
|
9
|
+
|
|
10
|
+
```TS
|
|
11
|
+
interface ReportTranslated {
|
|
12
|
+
dateReport: string
|
|
13
|
+
dateFiled: string
|
|
14
|
+
fiscalPeriod: FiscalPeriod
|
|
15
|
+
fiscalYear: number
|
|
16
|
+
form: string
|
|
17
|
+
isTTM: boolean
|
|
18
|
+
|
|
19
|
+
assetTotal: number | null
|
|
20
|
+
assetCurrent: number | null
|
|
21
|
+
assetCurrentCashEquivalents: number | null
|
|
22
|
+
assetCurrentInvestments: number | null
|
|
23
|
+
assetCurrentAccountsReceivable: number | null
|
|
24
|
+
assetCurrentInventory: number | null
|
|
25
|
+
|
|
26
|
+
assetNonCurrent: number | null
|
|
27
|
+
assetNonCurrentPPENet: number | null
|
|
28
|
+
assetNonCurrentPPEGross: number | null
|
|
29
|
+
assetNonCurrentInvestments: number | null
|
|
30
|
+
assetNonCurrentGoodwill: number | null
|
|
31
|
+
assetNonCurrentIntangibleLessGoodwill: number | null
|
|
32
|
+
|
|
33
|
+
liabilityTotal: number | null
|
|
34
|
+
liabilityCurrent: number | null
|
|
35
|
+
liabilityCurrentAccountsPayable: number | null
|
|
36
|
+
liabilityCurrentDebt: number | null
|
|
37
|
+
liabilityNonCurrent: number | null
|
|
38
|
+
liabilityNonCurrentDebt: number | null
|
|
39
|
+
|
|
40
|
+
equityTotal: number | null
|
|
41
|
+
equityRetainedEarnings: number | null
|
|
42
|
+
equityStockPreferred: number | null
|
|
43
|
+
|
|
44
|
+
sharesOutstanding: number | null
|
|
45
|
+
sharesOutstandingDiluted: number | null
|
|
46
|
+
|
|
47
|
+
eps: number | null
|
|
48
|
+
epsDiluted: number | null
|
|
49
|
+
|
|
50
|
+
ebit: number | null
|
|
51
|
+
ebitda: number | null
|
|
52
|
+
|
|
53
|
+
profitGross: number | null
|
|
54
|
+
|
|
55
|
+
revenueTotal: number | null
|
|
56
|
+
revenueCost: number | null
|
|
57
|
+
revenueOperating: number | null
|
|
58
|
+
|
|
59
|
+
expenseTotal: number | null
|
|
60
|
+
expenseOperating: number | null
|
|
61
|
+
expenseResearchDevelopment: number | null
|
|
62
|
+
expenseInterest: number | null
|
|
63
|
+
expenseDepreciation: number | null
|
|
64
|
+
expenseTax: number | null
|
|
65
|
+
|
|
66
|
+
expenseDepreciationAccumulated: number | null
|
|
67
|
+
expenseStockCompensation: number | null
|
|
68
|
+
expenseNonCashOther: number | null
|
|
69
|
+
|
|
70
|
+
incomeOperating: number | null
|
|
71
|
+
incomeNet: number | null
|
|
72
|
+
|
|
73
|
+
cashFlowFree: number | null
|
|
74
|
+
cashFlowDividendsPaid: number | null
|
|
75
|
+
cashFlowDividendsPaidPreferred: number | null
|
|
76
|
+
|
|
77
|
+
cashFlowCapex: number | null
|
|
78
|
+
cashFlowOperating: number | null
|
|
79
|
+
cashFlowDeferredTax: number | null
|
|
80
|
+
|
|
81
|
+
cashFlowWorkingCapitalNonCash: number | null
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Usage
|
|
86
|
+
|
|
87
|
+
import package contents
|
|
88
|
+
|
|
89
|
+
```TS
|
|
90
|
+
import { factFileReader, reportParser, secEdgarApi } from 'sec-edgar-api'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
You can fetch reports individually directly from the SEC website, (throttled to 10 requests per second)
|
|
94
|
+
|
|
95
|
+
```TS
|
|
96
|
+
// returns array of ReportWrapper (which implements ReportTranslated)
|
|
97
|
+
const reports = await secEdgarApi.getReports({ symbol: 'AAPL' })
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
or download all data from the SEC website and read directly from the files so you don't have to worry about rate limiting.
|
|
101
|
+
|
|
102
|
+
```TS
|
|
103
|
+
const downloadDirectory = './downloads/companyfacts'
|
|
104
|
+
|
|
105
|
+
// Download companyfacts directory from sec.gov (over 15GB)
|
|
106
|
+
await secEdgarApi.downloadCompanyFactsDirectory({
|
|
107
|
+
outputDirname: downloadDirectory,
|
|
108
|
+
onDownloadComplete: () => process.stdout.write('\n'),
|
|
109
|
+
onChunk: ({ percentComplete, stage }) => {
|
|
110
|
+
// Write progress bar to console
|
|
111
|
+
const countBarsComplete = Math.ceil(percentComplete * 30)
|
|
112
|
+
const barStr = `${'='.repeat(countBarsComplete)}${' '.repeat(30 - countBarsComplete)}`
|
|
113
|
+
const percentStr = `${(Math.round(percentComplete * 10000) / 100).toFixed(2)}%`
|
|
114
|
+
const statusStr = stage === 'download' ? 'Downloading...' : 'Unzipping...'
|
|
115
|
+
|
|
116
|
+
process.stdout.write(`\r<${barStr}> ${percentStr} ${statusStr}`)
|
|
117
|
+
},
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
// read companyfacts directory
|
|
121
|
+
const companyFacts = factFileReader.readFactFile({
|
|
122
|
+
companyFactsDirname: downloadDirectory,
|
|
123
|
+
symbol: 'AAPL',
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
// parse reports (same return value as secEdgarApi.getReports())
|
|
127
|
+
const reports = reportParser.parseReports(companyFacts)
|
|
128
|
+
```
|
|
129
|
+
|
|
6
130
|
## Resolvers
|
|
7
131
|
|
|
132
|
+
**WARNING** Still in testing. Values may not be accurate for all companies since the properties provided in the reports differ.
|
|
133
|
+
|
|
8
134
|
The main problem with the edgar API is that the property names and data provided are not uniform. You have to deal with companies omitting important data
|
|
9
135
|
in some filings, or using different property keys for the same data point.
|
|
10
136
|
|
|
@@ -25,3 +151,30 @@ Resolvers attempt to get information from each report and output a uniform inter
|
|
|
25
151
|
| resolveFiscalYearCumulativeProperties | Q1 + Q2 + Q3 + Q4 = FY (for quarterly properties that add to annual) |
|
|
26
152
|
| resolveQ4FiscalYearMatchingProperties | Q4 = FY (for non-cumulative properties such as sharesOutstanding) |
|
|
27
153
|
| resolveRevenueTotal | revenueCost + profitGross = revenueTotal |
|
|
154
|
+
|
|
155
|
+
## Contributing
|
|
156
|
+
|
|
157
|
+
Getting all the properties in a uniform interface accurately is proving to be very difficult due to the differences in all the reports.
|
|
158
|
+
Please contribute if you know how to improve this.
|
|
159
|
+
|
|
160
|
+
Files for mapping & resolving properties:
|
|
161
|
+
|
|
162
|
+
- Mapping properties: `src/util/key-translations.ts`
|
|
163
|
+
- Resolving properties: `src/services/ReportParser.ts` (add resolvers to the `resolvers/` directory, import to `/resolver/index.ts`, and add to ReportParser.resolveAll)
|
|
164
|
+
|
|
165
|
+
These are the scripts I used to get keys commonly used across reports, which you can use to add to `key-translations.ts`
|
|
166
|
+
|
|
167
|
+
```TS
|
|
168
|
+
import { readAllCompanyFactFiles, getPropertyUsageCounts } from './scripts/script-helpers'
|
|
169
|
+
|
|
170
|
+
const companyFactsList = readAllCompanyFactFiles(path.resolve('./downloads/companyfacts'), 10)
|
|
171
|
+
const propertyUsageCounts = getPropertyUsageCounts(companyFactsList)
|
|
172
|
+
|
|
173
|
+
fs.writeFileSync('./downloads/property-usage-counts.json', JSON.stringify(propertyUsageCounts, null, 2))
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Resources
|
|
177
|
+
|
|
178
|
+
- Validate resolved values: https://finance.yahoo.com/
|
|
179
|
+
- Financial calculations: https://www.gurufocus.com/
|
|
180
|
+
- Calculate change in working capital: https://www.oldschoolvalue.com/stock-valuation/change-in-working-capital/
|
package/build/.DS_Store
ADDED
|
Binary file
|
|
@@ -35,6 +35,10 @@ export default class ReportParser {
|
|
|
35
35
|
* @see https://www.sec.gov/edgar/sec-api-documentation
|
|
36
36
|
*/
|
|
37
37
|
parseReportsRaw(companyFactListData: Pick<CompanyFactListData, 'facts'>, options?: ParseReportsOptions): ReportRaw[];
|
|
38
|
+
/**
|
|
39
|
+
* parseReportsRaw but removes meta data from the report
|
|
40
|
+
*/
|
|
41
|
+
parseReportsRawNoMeta(companyFactListData: Pick<CompanyFactListData, 'facts'>, options?: ParseReportsOptions): Record<string, number>[];
|
|
38
42
|
/**
|
|
39
43
|
* Avoids deep nesting logic while iteratating through company facts
|
|
40
44
|
*
|
|
@@ -53,6 +53,25 @@ var ReportParser = /** @class */ (function () {
|
|
|
53
53
|
ReportParser.prototype.parseReportsRaw = function (companyFactListData, options) {
|
|
54
54
|
return this.reportRawParser.parseReports(companyFactListData, options);
|
|
55
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* parseReportsRaw but removes meta data from the report
|
|
58
|
+
*/
|
|
59
|
+
ReportParser.prototype.parseReportsRawNoMeta = function (companyFactListData, options) {
|
|
60
|
+
var reportsRaw = this.parseReportsRaw(companyFactListData, options);
|
|
61
|
+
reportsRaw.forEach(function (reportRaw) {
|
|
62
|
+
var report = reportRaw;
|
|
63
|
+
delete report.dateFiled;
|
|
64
|
+
delete report.dateReport;
|
|
65
|
+
delete report.fiscalPeriod;
|
|
66
|
+
delete report.fiscalYear;
|
|
67
|
+
delete report.form;
|
|
68
|
+
delete report.frame;
|
|
69
|
+
delete report.isTTM;
|
|
70
|
+
delete report.reportType;
|
|
71
|
+
delete report.taxonomy;
|
|
72
|
+
});
|
|
73
|
+
return reportsRaw;
|
|
74
|
+
};
|
|
56
75
|
/**
|
|
57
76
|
* Avoids deep nesting logic while iteratating through company facts
|
|
58
77
|
*
|
|
@@ -65,7 +65,6 @@ var FactsDownloader = /** @class */ (function () {
|
|
|
65
65
|
var _this = this;
|
|
66
66
|
return __generator(this, function (_b) {
|
|
67
67
|
outputDirname = params.outputDirname, onChunk = params.onChunk, onDownloadComplete = params.onDownloadComplete, onError = params.onError, onComplete = params.onComplete, _a = params.unzip, unzip = _a === void 0 ? true : _a;
|
|
68
|
-
// writes download and unzip progress with percentage in terminal if useWriteProgressBar is true
|
|
69
68
|
return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
|
|
70
69
|
var filename, e_1;
|
|
71
70
|
return __generator(this, function (_a) {
|
|
@@ -70,11 +70,14 @@ export default class SecEdgarApi {
|
|
|
70
70
|
*/
|
|
71
71
|
getFactFrame(params: GetFactFrameParams): Promise<MultiCompanyFactFrame>;
|
|
72
72
|
/**
|
|
73
|
+
* Note: Properties that are not provied from report are calculated an may not be accurate,
|
|
74
|
+
* verify results finance.yahoo.com (ex: https://finance.yahoo.com/quote/AAPL/financials)
|
|
75
|
+
*
|
|
76
|
+
* Please contribute to improve resolving report properties: https://github.com/andyevers/sec-edgar-api
|
|
77
|
+
*
|
|
73
78
|
* Parses reports from company facts. Calculates missing properties and uses a single interface
|
|
74
79
|
* for all reports. This includes only 10-K and 10-Q annual and quarterly reports. To include
|
|
75
|
-
* all reports, use getReportsRaw
|
|
76
|
-
*
|
|
77
|
-
* Note that calculated properties are estimated if they are not available in the company facts.
|
|
80
|
+
* all reports, use getReportsRaw.
|
|
78
81
|
*/
|
|
79
82
|
getReports(params: GetSymbolParams): Promise<ReportWrapper[]>;
|
|
80
83
|
/**
|
|
@@ -86,6 +89,8 @@ export default class SecEdgarApi {
|
|
|
86
89
|
* Downloads the companyfacts.zip file and extracts the directory containing all company
|
|
87
90
|
* reports available from sec.gov. After downloading, you can use factFileReader and reportParser
|
|
88
91
|
* to get and read reports.
|
|
92
|
+
*
|
|
93
|
+
* Note: Over 15GB of data is downloaded and extracted.
|
|
89
94
|
*/
|
|
90
95
|
downloadCompanyFactsDirectory(params: DownloadCompanyFactsDirectoryParams): Promise<boolean>;
|
|
91
96
|
}
|
|
@@ -131,11 +131,14 @@ var SecEdgarApi = /** @class */ (function () {
|
|
|
131
131
|
});
|
|
132
132
|
};
|
|
133
133
|
/**
|
|
134
|
+
* Note: Properties that are not provied from report are calculated an may not be accurate,
|
|
135
|
+
* verify results finance.yahoo.com (ex: https://finance.yahoo.com/quote/AAPL/financials)
|
|
136
|
+
*
|
|
137
|
+
* Please contribute to improve resolving report properties: https://github.com/andyevers/sec-edgar-api
|
|
138
|
+
*
|
|
134
139
|
* Parses reports from company facts. Calculates missing properties and uses a single interface
|
|
135
140
|
* for all reports. This includes only 10-K and 10-Q annual and quarterly reports. To include
|
|
136
|
-
* all reports, use getReportsRaw
|
|
137
|
-
*
|
|
138
|
-
* Note that calculated properties are estimated if they are not available in the company facts.
|
|
141
|
+
* all reports, use getReportsRaw.
|
|
139
142
|
*/
|
|
140
143
|
SecEdgarApi.prototype.getReports = function (params) {
|
|
141
144
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -171,6 +174,8 @@ var SecEdgarApi = /** @class */ (function () {
|
|
|
171
174
|
* Downloads the companyfacts.zip file and extracts the directory containing all company
|
|
172
175
|
* reports available from sec.gov. After downloading, you can use factFileReader and reportParser
|
|
173
176
|
* to get and read reports.
|
|
177
|
+
*
|
|
178
|
+
* Note: Over 15GB of data is downloaded and extracted.
|
|
174
179
|
*/
|
|
175
180
|
SecEdgarApi.prototype.downloadCompanyFactsDirectory = function (params) {
|
|
176
181
|
return __awaiter(this, void 0, void 0, function () {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sec-edgar-api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Fetch and parse SEC earnings reports and other filings. Useful for financial analysis.",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "build/index.js",
|
|
6
6
|
"author": "Andrew Evers (https://github.com/andyevers)",
|
|
7
7
|
"homepage": "https://github.com/andyevers/sec-edgar-api#readme",
|
|
8
8
|
"license": "ISC",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
17
|
"test": "jest test",
|
|
18
|
-
"build": "tsc"
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"publish": "npm run build && npm publish"
|
|
19
20
|
},
|
|
20
21
|
"keywords": [
|
|
21
22
|
"sec",
|