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 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/
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.1",
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",