sec-edgar-api
Version:
Fetch and parse SEC earnings reports and other filings. Useful for financial analysis.
183 lines (182 loc) • 10 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var constants_1 = require("../../util/constants");
var FactFiscalCalculator_1 = require("./FactFiscalCalculator");
var FactGrouper_1 = require("./FactGrouper");
var FactRecordBuilder_1 = require("./FactRecordBuilder");
var FactSplitAdjuster_1 = require("./FactSplitAdjuster");
/**
* Builds ReportRaw objects from company facts. Adjusts for splits and resolves period values.
*/
var ReportRawBuilder = /** @class */ (function () {
function ReportRawBuilder() {
this.factRecordBuilder = new FactRecordBuilder_1.default();
}
ReportRawBuilder.prototype.createFacts = function (companyFacts, includeNamePrefix) {
if (includeNamePrefix === void 0) { includeNamePrefix = false; }
return this.factRecordBuilder.createFacts(companyFacts, includeNamePrefix);
};
ReportRawBuilder.prototype.getFactKey = function (fact, pathSeparator) {
var _a;
var suffix = (_a = fact.segments) === null || _a === void 0 ? void 0 : _a.map(function (_a) {
var dimension = _a.dimension, value = _a.value;
return "".concat(dimension).concat(pathSeparator).concat(value);
}).join(pathSeparator);
return suffix ? "".concat(fact.name).concat(pathSeparator).concat(suffix) : fact.name;
};
ReportRawBuilder.prototype.buildReports = function (params) {
var _this = this;
var factsProp = params.facts, filings = params.filings, splitsProp = params.splits, _a = params.resolvePeriodValues, resolvePeriodValues = _a === void 0 ? true : _a, _b = params.adjustForSplits, adjustForSplits = _b === void 0 ? true : _b, _c = params.pathSeparatorForMemberFacts, pathSeparatorForMemberFacts = _c === void 0 ? '>' : _c, fiscalYearEnd = params.fiscalYearEnd;
// Rename member facts to prevent overwriting parent facts.
var facts = factsProp.map(function (fact) {
var factKey = _this.getFactKey(fact, pathSeparatorForMemberFacts);
return __assign(__assign({}, fact), { name: factKey });
});
if (facts.length === 0) {
return [];
}
var reportsCik = Number(facts[0].cik);
var fiscalCalculator = new FactFiscalCalculator_1.default({
filings: filings === null || filings === void 0 ? void 0 : filings.filter(function (f) { return constants_1.FORMS_EARNINGS.includes(f.form) && Boolean(f.reportDate); }),
facts: facts,
fiscalYearEnd: fiscalYearEnd,
});
var accessionByYearQuarter = new Map();
filings === null || filings === void 0 ? void 0 : filings.forEach(function (f) {
var _a = fiscalCalculator.getFiscalYearQuarter({ dateStr: f.reportDate }), year = _a.year, quarter = _a.quarter;
accessionByYearQuarter.set(f.accessionNumber, "".concat(year, "_").concat(quarter));
});
var factGrouper = new FactGrouper_1.default();
var factSplitAdjuster = new FactSplitAdjuster_1.default();
// if splits not included in params and need to adjust, extract from facts
var splits = adjustForSplits
? splitsProp !== null && splitsProp !== void 0 ? splitsProp : factSplitAdjuster.getSplits({ splitFacts: factSplitAdjuster.filterSplitFacts({ facts: facts }) })
: splitsProp;
var _d = factGrouper.buildFactGroupsByReportKey({
facts: facts,
cik: reportsCik,
fiscalCalculator: fiscalCalculator,
resolvePeriodValues: resolvePeriodValues,
generateMissingGroups: false,
splits: splits,
}), factGroupsByReportKey = _d.factGroupsByReportKey, maxYear = _d.maxYear, minYear = _d.minYear;
return this.buildReportsFromGroups({
factGroupsByReportKey: factGroupsByReportKey,
fiscalCalculator: fiscalCalculator,
splits: splits,
minYear: minYear,
maxYear: maxYear,
cik: reportsCik,
});
};
ReportRawBuilder.prototype.createReportKey = function (params) {
var year = params.year, quarter = params.quarter, isAnnual = params.isAnnual;
return "".concat(year, "_").concat(isAnnual ? 'FY' : "Q".concat(quarter));
};
ReportRawBuilder.prototype.createReport = function (params) {
var group = params.group, isAnnual = params.isAnnual, splitDate = params.splitDate, splitRatio = params.splitRatio, cik = params.cik, accessionNumber = params.accessionNumber;
var fiscalPeriod = isAnnual ? 'FY' : "Q".concat(group.quarter);
var accessionNoHyphen = accessionNumber === null || accessionNumber === void 0 ? void 0 : accessionNumber.replace(/-/g, '');
var url = accessionNumber
? "https://www.sec.gov/Archives/edgar/data/".concat(cik, "/").concat(accessionNoHyphen, "/").concat(accessionNumber, ".txt")
: null;
return {
cik: cik,
url: url,
dateFiled: group.reportFiled,
dateReport: group.reportEnd,
fiscalPeriod: fiscalPeriod,
fiscalYear: group.fiscalYear,
splitDate: splitDate !== null && splitDate !== void 0 ? splitDate : null,
splitRatio: splitRatio !== null && splitRatio !== void 0 ? splitRatio : null,
};
};
ReportRawBuilder.prototype.round = function (value) {
var multiplier = 1000000;
return typeof value === 'number' ? Math.round(value * multiplier) / multiplier : value;
};
ReportRawBuilder.prototype.buildReportsFromGroups = function (params) {
var _this = this;
var factGroupsByReportKey = params.factGroupsByReportKey, minYear = params.minYear, maxYear = params.maxYear, cik = params.cik, splits = params.splits, fiscalCalculator = params.fiscalCalculator, accessionByYearQuarter = params.accessionByYearQuarter;
var splitByFiscals = new Map();
var reportByKey = new Map();
splits === null || splits === void 0 ? void 0 : splits.forEach(function (split) {
var _a = fiscalCalculator.getFiscalYearQuarter({ dateStr: split.endLast }), quarter = _a.quarter, year = _a.year;
splitByFiscals.set("".concat(year, "_").concat(quarter), split);
});
factGroupsByReportKey.forEach(function (groups) {
var _a, _b, _c, _d, _e, _f, _g;
var groupWithDates = groups.find(function (g) { return g.reportEnd; });
if (!groupWithDates)
return;
var keyYearQuarter = "".concat(groupWithDates.fiscalYear, "_").concat(groupWithDates.quarter);
var split = splitByFiscals.get(keyYearQuarter);
var accessionNumber = (_a = accessionByYearQuarter === null || accessionByYearQuarter === void 0 ? void 0 : accessionByYearQuarter.get(keyYearQuarter)) !== null && _a !== void 0 ? _a : groupWithDates.accn;
var splitDate = (_b = split === null || split === void 0 ? void 0 : split.endLast) !== null && _b !== void 0 ? _b : null;
var splitRatio = (_c = split === null || split === void 0 ? void 0 : split.splitRatio) !== null && _c !== void 0 ? _c : null;
var quarter = groupWithDates.quarter;
var reportPeriod = _this.createReport({
group: groupWithDates,
accessionNumber: accessionNumber,
cik: cik,
isAnnual: false,
splitDate: splitDate,
splitRatio: splitRatio,
});
var reportKeyPeriod = _this.createReportKey({
year: reportPeriod.fiscalYear,
quarter: quarter,
isAnnual: false,
});
for (var _i = 0, groups_1 = groups; _i < groups_1.length; _i++) {
var group = groups_1[_i];
var value = (_e = (_d = group.valuePeriodResolved) !== null && _d !== void 0 ? _d : group.valuePeriodFirst) !== null && _e !== void 0 ? _e : 0;
reportPeriod[group.name] = _this.round(value);
}
reportByKey.set(reportKeyPeriod, reportPeriod);
if (quarter !== 4)
return;
var reportAnnual = _this.createReport({
group: groupWithDates,
accessionNumber: accessionNumber,
cik: cik,
isAnnual: true,
splitDate: splitDate,
splitRatio: splitRatio,
});
var reportKeyAnnual = "".concat(reportAnnual.fiscalYear, "_").concat(reportAnnual.fiscalPeriod);
for (var _h = 0, groups_2 = groups; _h < groups_2.length; _h++) {
var group = groups_2[_h];
var value = (_g = (_f = group.valueTrailingResolved) !== null && _f !== void 0 ? _f : group.valueTrailingFirst) !== null && _g !== void 0 ? _g : 0;
reportAnnual[group.name] = _this.round(value);
}
reportByKey.set(reportKeyAnnual, reportAnnual);
});
var reports = [];
// sort reports by year and quarter
for (var year = minYear; year <= maxYear; year++) {
for (var quarter = 1; quarter <= 5; quarter++) {
var isAnnual = quarter === 5;
var reportKey = this.createReportKey({ year: year, quarter: isAnnual ? 4 : quarter, isAnnual: isAnnual });
var report = reportByKey.get(reportKey);
if (report) {
reports.push(report);
}
}
}
return reports;
};
return ReportRawBuilder;
}());
exports.default = ReportRawBuilder;