UNPKG

sec-edgar-api

Version:

Fetch and parse SEC earnings reports and other filings. Useful for financial analysis.

356 lines (355 loc) 15.9 kB
import type { CompanyFactFrame, CompanyFactListData, CompanyTickerItem, DailyFilingFormType, FieldDataResponse, Form10KData, Form13GData, Form4Data, FormDef14aData, MultiCompanyFactFrame, ReportRaw, ReportTranslated, FilingListDetails, FilingListItemTranslated, SubmissionList, CalculationMap } from '../../types'; import { IClient } from '../Client'; import DocumentParser from '../DocumentParser'; import ReportParser from '../ReportParser'; import ReportWrapper from '../ReportParser/ReportWrapper'; import FilingMapper from './FilingMapper'; import SubmissionRequestWrapper from './RequestWrapper'; import { IThrottler } from './Throttler'; interface SecApiArgs { throttler: IThrottler; client: IClient; cikBySymbol: Record<string, number>; reportParser: ReportParser; documentParser: DocumentParser; filingMapper?: FilingMapper; } export interface CreateRequestWrapperParams { /** symbol or cik */ symbol: string | number; filings: FilingListDetails | FilingListItemTranslated[]; /** earliest allowed filing date that is allowed to be fetched */ cutoffDate?: Date; maxRequests?: number; } export interface GetSymbolParams { /** symbol or cik */ symbol: string | number; } export interface GetReportsRawParams { symbol: string | number; includeNamePrefix?: boolean; adjustForSplits?: boolean; resolvePeriodValues?: boolean; } export interface GetReportsParams extends Omit<GetReportsRawParams, 'includeNamePrefix'> { /** symbol or cik */ symbol: string | number; withWrapper?: boolean; usePropertyResolver?: boolean; adjustForSplits?: boolean; resolvePeriodValues?: boolean; } export interface GetFactParams { /** symbol or cik */ symbol: string | number; fact: string; taxonomy?: 'us-gaap' | 'dei' | 'invest' | string; } export interface GetFactFrameParams { fact: string; frame: string; unit?: 'pure' | 'USD' | 'shares' | string; taxonomy?: 'us-gaap' | 'dei' | 'invest' | string; } export interface GetInsiderTransactionsParams { page: number; symbol: string | number; itemsPerPage?: number; isOwnerCik?: boolean; } export interface SearchCompaniesParams { sic?: number; /** Abbreviation of state: IL, CA, NY, etc... */ state?: string; page: number; itemsPerPage?: number; /** Partial name of the company for search. */ company?: string; companyMatch?: 'startsWith' | 'contains'; } interface GetCurrentFilingsParams { formType?: '4' | '3' | '10-Q' | '10-K' | 'SC 13G' | '13F-HR' | '8-K'; page?: number; itemsPerPage?: number; symbol?: string | number; searchType?: 'include' | 'exclude' | 'only'; } export interface GetDocumentXbrlParams { url?: string; symbol?: string | number; accessionNumber?: string; includeReport?: boolean; includeInstance?: boolean; includeLinkbases?: boolean; includeSchema?: boolean; } /** * Gets reports from companies filed with the SEC * * @see https://www.sec.gov/edgar/sec-api-documentation */ export default class SecEdgarApi { private readonly baseUrlEdgar; private readonly baseUrlSec; private readonly throttler; private readonly client; private readonly filingMapper; readonly cikBySymbol: Record<string, number>; readonly reportParser: ReportParser; readonly documentParser: DocumentParser; constructor(args?: SecApiArgs); private request; private mapFilingListDetails; private getCreateRequestSubmissions; /** * If symbol is not in cikBySymbol, assume it is a cik. does not make a request */ getCikString(symbol: string | number): string; /** * This JSON data structure contains metadata such as current name, former name, * and stock exchanges and ticker symbols of publicly-traded companies. The object’s * property path contains at least one year’s of filing or to 1,000 (whichever is more) * of the most recent filings in a compact columnar data array. If the entity has * additional filings, files will contain an array of additional JSON files and the * date range for the filings each one contains. * * endpoint: `/submissions/CIK${cik}.json` */ getSubmissions(params: GetSymbolParams & { includeOldFilings?: boolean; }): Promise<{ submissionList: SubmissionList; filings: FilingListItemTranslated[]; }>; /** * The company-concept API returns all the XBRL disclosures from a single company (CIK) * and concept (a taxonomy and tag) into a single JSON file, with a separate array * of facts for each units on measure that the company has chosen to disclose * (e.g. net profits reported in U.S. dollars and in Canadian dollars). * * endpoint `/api/xbrl/companyconcept/CIK${cik}/${taxonomy}/${fact}.json` */ getFact(params: GetFactParams): Promise<CompanyFactFrame>; /** * Returns all the company concepts data for a company into a single API call: * * endpoint `/api/xbrl/companyconcept/CIK${cik}/${taxonomy}/${fact}.json` */ getFacts(params: GetSymbolParams): Promise<CompanyFactListData>; /** * The xbrl/frames API aggregates one fact for each reporting entity that is last filed * that most closely fits the calendrical period requested. This API supports for annual, * quarterly and instantaneous data: * * data.sec.gov/api/xbrl/frames/us-gaap/AccountsPayableCurrent/USD/CY2019Q1I.json * * Where the units of measure specified in the XBRL contains a numerator and a denominator, * these are separated by “-per-” such as “USD-per-shares”. Note that the default unit * in XBRL is “pure”. * * The period format is CY#### for annual data (duration 365 days +/- 30 days), CY####Q# * for quarterly data (duration 91 days +/- 30 days), and CY####Q#I for instantaneous data. * Because company financial calendars can start and end on any month or day and even * change in length from quarter to quarter to according to the day of the week, the frame * data is assembled by the dates that best align with a calendar quarter or year. Data * users should be mindful different reporting start and end dates for facts contained * in a frame. * * endpoint `/api/xbrl/frames/${taxonomy}/${fact}/${unit}/${frame}.json` */ getFactFrame(params: GetFactFrameParams): Promise<MultiCompanyFactFrame>; /** * Note: Properties that are not provied from report are calculated an may not be accurate, * verify results finance.yahoo.com (ex: https://finance.yahoo.com/quote/AAPL/financials) * * Please contribute to improve resolving report properties: https://github.com/andyevers/sec-edgar-api * * Parses reports from company facts. Calculates missing properties and uses a single interface * for all reports. This includes only 10-K and 10-Q annual and quarterly reports. To include * all reports, use getReportsRaw. * * @deprecated Formerly getReports. This will be removed in a future version. */ getReportsLegacy<T extends GetReportsParams>(params: T): Promise<T['withWrapper'] extends true ? ReportWrapper[] : ReportTranslated[]>; /** * Note: Properties that are not provied from report are calculated an may not be accurate, * verify results finance.yahoo.com (ex: https://finance.yahoo.com/quote/AAPL/financials) * * Please contribute to improve resolving report properties: https://github.com/andyevers/sec-edgar-api * * Parses reports from company facts. Calculates missing properties and uses a single interface * for all reports. This includes only 10-K and 10-Q annual and quarterly reports. To include * all reports, use getReportsRaw. */ getReports<R = ReportTranslated>(params: { symbol: string | number; adjustForSplits?: boolean; resolvePeriodValues?: boolean; calculationMap?: CalculationMap<R>; }): Promise<(typeof params.calculationMap extends undefined ? ReportTranslated : ReportRaw & R)[]>; /** * Parses reports from company facts. */ getReportsRaw(params: GetReportsRawParams): Promise<ReportRaw[]>; /** * Gets a list of all tickers and CIKs from `https://www.sec.gov/files/company_tickers.json` * * Note that they key cik_str is actually a number. To get cik string, you can do `${cik_str}`.padStart(10, '0') */ getCompanyTickerList(): Promise<CompanyTickerItem[]>; /** * Gets a list of all tickers and CIKs with exchange and company name from `https://www.sec.gov/files/company_tickers_exchange.json` * * response: { fields: ['cik', 'name', 'ticker', 'exchange'], data: [ [320193,'Apple Inc.','AAPL','Nasdaq'], ... ] } */ getCompanyTickerExchangeList(): Promise<FieldDataResponse<'cik' | 'name' | 'ticker' | 'exchange'>>; /** * Gets a list of all mutual funds from `https://www.sec.gov/files/company_tickers_mf.json` * * response: { fields: ['cik','seriesId','classId','symbol'], data: [ [2110,'S000009184','C000024954','LACAX'], ... ] } */ getMutualFundList(): Promise<FieldDataResponse<'cik' | 'seriesId' | 'classId' | 'symbol'>>; /** * If url is provided, all other props are ignored. Otherwise, both accessionNumber * and symbol (symbol or cik) are required. provide fileName if different from `${accessionNumber}.txt` * * Some form types can be parsed using the DocumentParser such as form 4 (insider transactions) and form 13g (institutional holders) * * endpoint: `https://www.sec.gov/Archives/edgar/data/${cik}/${accessionNumber}/${primaryDocument}` * * @see https://www.sec.gov/forms for a list of form types */ getDocument(params: { url?: string; symbol?: string | number; accessionNumber?: string; fileName?: string; }): Promise<string>; /** * Fetches SEC document and parses XBRL data. If url is provided, symbol and accessionNumber are ignored. * * Use "include" params to specify what to parse. If not provided, all data is parsed. */ getDocumentXbrl(params: GetDocumentXbrlParams): Promise<import("../DocumentParser/parsers/parse-xbrl").DocumentXbrlResult>; /** * Builds a url for a document. If fileName is not provided, it defaults to `${accessionNumber}.txt` * * format: `https://www.sec.gov/Archives/edgar/data/${cik}/${accessionNumberNoHyphen)}/${fileNameAccessionFile}` */ buildDocumentUrl(params: { symbol: string | number; accessionNumber: string; fileName?: string; }): string; /** * Used for getting insider transactions. extracts insider transaction urls from submission list response, and parses the xml doc. * * ```ts * const submissions = await secEdgarApi.getSubmissions({ symbol: 'AAPL' }) * const requestWrapper = secEdgarApi.createRequestInsiderTransactions({ symbol: 'AAPL', filings: submissions.filings.recent }) * * const transactions1 = (await requestWrapper.requestNext()).result.transactions // array of transactions from most recent doc * const transactions2 = (await requestWrapper.requestNext()).result.transactions // array of transactions from second most recent doc * ``` */ createRequestInsiderTransactions(params: CreateRequestWrapperParams): SubmissionRequestWrapper<Form4Data>; /** * Used for getting institutional holders. extracts holders urls from submission list response, and parses the xml doc. * * ```ts * const submissions = await secEdgarApi.getSubmissions({ symbol: 'AAPL' }) * const requestWrapper = secEdgarApi.createRequestInstitutionalHolders({ symbol: 'AAPL', filings: submissions.filings.recent }) * * const holders1 = (await requestWrapper.requestNext()).result.holders // array of holders from most recent doc * const holders2 = (await requestWrapper.requestNext()).result.holders // array of holders from second most recent doc * ``` */ createRequestInstitutionalHolders(params: CreateRequestWrapperParams): SubmissionRequestWrapper<Form13GData>; /** * Used for getting earnings report tables from submission files. * * ```ts * const submissions = await secEdgarApi.getSubmissions({ symbol: 'AAPL' }) * const requestWrapper = secEdgarApi.createRequesEarningsReports({ symbol: 'AAPL', filings: submissions.filings.recent }) * * const tables1 = (await requestWrapper.requestNext()).result.tables // array of tables from most recent doc * const tables2 = (await requestWrapper.requestNext()).result.tables // array of tables from second most recent doc * ``` */ createRequestEarningsReports(params: CreateRequestWrapperParams): SubmissionRequestWrapper<Form10KData>; /** * Proxy statement includes list of holders, executiveCompensation, and other tables. returns FormDef14aData * * ```ts * const submissions = await secEdgarApi.getSubmissions({ symbol: 'AAPL' }) * const requestWrapper = secEdgarApi.createRequesProxyStatement({ symbol: 'AAPL', filings: submissions.filings.recent }) * * const { holders, executiveCompensation } = (await requestWrapper.requestNext()).result * ``` */ createRequestProxyStatement(params: CreateRequestWrapperParams): SubmissionRequestWrapper<FormDef14aData>; /** * Gets list of filings for a day up to 5 days ago. * * NOTE: This has not been updated since 2014 and has had issues with not returning data. * * @see https://www.sec.gov/edgar/searchedgar/currentevents */ getCurrentFilingsDaily(params?: { formType?: DailyFilingFormType; /** max 5 */ lookbackDays?: number; startsWith?: string; }): Promise<{ date: string; matchCount: number; totalCount: number; entries: { accessionNumber: string; form: string; companyCik: number; companyName: string; filedDate: string; }[]; }>; /** * Lists all types of current filings including non XBRL. If fetching earnings reports, * use getCurrentFilingsXbrl instead. * * @see https://www.sec.gov/cgi-bin/browse-edgar?action=getcurrent */ getCurrentFilings(params?: GetCurrentFilingsParams): Promise<import("../../types").CurrentFilingsList>; /** * Fetches XBRL filings using the RSS feeds provided by the SEC. * * @see https://www.sec.gov/structureddata/rss-feeds-submitted-filings */ getCurrentFilingsXbrl(params?: { taxonomy?: 'usGaap' | 'mutualFund' | 'inlineXbrl' | 'allXbrl'; }): Promise<import("../../types").CurrentFilingsXBRL>; /** * Gets insider transactions for a provided symbol or CIK. * * To get transactions by a specific owner, set isOwnerCik to true and provide * the owner CIK for the symbol parameter. * * example at https://www.sec.gov/cgi-bin/own-disp?action=getissuer&CIK=0000320193 */ getInsiderTransactions(params: GetInsiderTransactionsParams): Promise<{ transactions: import("../../types").InsiderTransaction[]; owners: import("../../types").Owner[]; issuers: import("../../types").Issuer[]; }>; /** * Search for companies from by name, sic code, or state. * * example at https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&owner=exclude&&start=0&count=100&hidefilings=0&company=Apple&match=contains * * TODO: Switch this to use output=atom in the url */ searchCompanies(params: SearchCompaniesParams): Promise<{ items: import("../../types").CompanySearchResult[]; }>; } export {};