Package: edgartools
The world's easiest, most powerful edgar libraryAbout the projectedgartoolsis one of the nicest looking EDGAR libraries out there. It is also powerful and easy to use.
You can query, filter and select any filing since 1994 and view the filing's html, text, xml or structured data.Getting startedInstall using pippipinstalledgartoolsImport and start usingfromedgarimport*# Tell the SEC who you areset_identity("Michael Mccallum mike.mccalum@indigo.com")filings=get_filings()ConceptsHow do I find a filing?Depends on what you knowA. I know the accession numberfiling=find("0001065280-23-000273")B. I know the company ticker or cikfilings=Company("NFLX").get_filings(form="10-Q").latest(1)C. Show me a list of filingsfilings=get_filings(form="10-Q")filing=filings[0]What can I do with a filingYou canviewit in the terminal oropenit in the browser, get the filing ashtml,xmlortext,
and downloadattachments. You can extract data from the filing into a data object.What can I do with a companyYou can get the company'sfilings,factsandfinancials.How to use edgartoolsTaskCodeSet your EDGAR identity in Linux/Macexport EDGAR_IDENTITY="First Last email@domain.com"Set your EDGAR identity in Windowsset EDGAR_IDENTITY="First Last email@domain.com"Set identity in Windows Powershell$env:EDGAR_IDENTITY="First Last email@domain.com"Set identity in Pythonset_identity("First Last email@domain.com")Importing the libraryfrom edgar import *Working with filingsTaskCodeGet filings for the year to datefilings = get_filings()Get only xbrl filingsfilings = get_filings(index="xbrl")Get filings for a specific yearfilings = get_filings(2020)Get filings for a specific quarterfilings = get_filings(2020, 1)Get filings for multiple yearsfilings = get_filings([2020, 2021])Get filigs for a range of yearsfilings = get_filings(year=range(2010, 2020)Get filings for a specific formfilings = get_filings(form="10-K")Get filings for a list of formsfilings = get_filings(form=["10-K", "10-Q"])Show the next page of filingsfilings.next()Show the previous page of filingsfilings.prev()Get the first n filingsfilings.head(20)Get the last n filingsfilings.tail(20)Get the latest n filings by datefilings.latest(20)Get a random sample of the filingsfilings.sample(20)Filter filings on a datefilings = filings.filter(date="2020-01-01")Filter filings between datesfilings.filter(date="2020-01-01:2020-03-01")Filter filings before a datefilings.filter(date=":2020-03-01")Filter filings after a datefilings.filter(date="2020-03-01:")Get filings as a pandas dataframefilings.to_pandas()Working with a filingTaskCodeGet a single filingfiling = filings[3]Get a filing by accession numberfiling = get_by_accession_number("0000320193-20-34576")Get the filing homepagefiling.homepageOpen a filing in the browserfiling.open()Open the filing homepage in the browserfiling.homepage.open()View the filing in the terminalfiling.view()Get the html of the filing documentfiling.html()Get the XBRL of the filing documentfiling.xbrl()Get the filing document as markdownfiling.markdown()Get the full submission text of a filingfiling.text()Get and parse the data object of a filingfiling.obj()Get the filing attachmentsfiling.attachmentsGet a single attachmentattachment = filing.attachments[0]Open an attachment in the browserattachment.open()Download an attachmentcontent = attachment.download()Working with a companyTaskCodeGet a company by tickercompany = Company("AAPL")Get a company by CIKcompany = Company("0000320193")Get company factscompany.get_facts()Get company facts as a pandas dataframecompany.get_facts().to_pandas()Get company filingscompany.get_filings()Get company filings by formcompany.get_filings(form="10-K")Get a company filing by accession_numbercompany.get_filing(accession_number="0000320193-21-000139")Get the company's financialscompany.financialsGet the company's balance sheetcompany.financials.balance_sheetGet the company's cash flow statementcompany.financials.cash_flow_statementInstallationpip install edgartoolsUsageSet your Edgar user identityBefore you can access the SEC Edgar API you need to set the identity that you will use to access Edgar.
This is usually your name and email, or a company name and email.SampleCompanyNameAdminContact@<samplecompanydomain>.comThe user identity is sent in the User-Agent string and the Edgar API will refuse to respond to your request without it.EdgarTools will look for an environment variable calledEDGAR_IDENTITYand use that in each request.
So, you need to set this environment variable before using it.Setting EDGAR_IDENTITY in Linux/MacexportEDGAR_IDENTITY="Michael Mccallum mcalum@gmail.com"Setting EDGAR_IDENTITY in Windows Powershell$Env:EDGAR_IDENTITY="Michael Mccallum mcalum@gmail.com"Alternatively, you can callset_identitywhich does the same thing.fromedgarimportset_identityset_identity("Michael Mccallum mcalum@gmail.com")For more detail seehttps://www.sec.gov/os/accessing-edgar-dataUsageImporting edgarfromedgarimport*Getting filings# Get filings for the current year and quarterfilings=get_filings()# Get filings for 2022filings=get_filings(2022)# OR filings = get_filings(year=2022)# Get filings for 2022 quarter 4filings=get_filings(2022,4)# OR filings = get_filings(year=2022, quarter=4)# Get filings for 2020, 2021 and 2022filings=get_filings([2020,2021,2022])# OR filings = get_filings(year=range(2020, 2023))# Get filings for 2020 quarters 1 and 2filings=get_filings(2020,quarter=[1,2])Filtering filings# Filter for form Dfilings.filter(form="D")# Filter for form 10-K and 10-Qfilings.filter(form=["10-K","10-Q"])# When you filter by form e.g. "D" it includes amendments e.g. "D\A". You can omit amendmentsfilings.filter(form="D",amendments=False)# Filter by filing_date. date and filing_date mean the same thing# Get all filings on 2023-02-23filings.filter(date="2023-02-23")# ORfilings.filter(filing_date="2023-02-23")# Filter to get all filings between 2023-01-23 and 2023-02-23filings.filter(date="2023-01-23:2023-02-23")# Filter to get all filings since 2023-01-23filings.filter(date="2023-01-23")# Filter to get all filings before 2023-02-23filings.filter(date=":2023-02-23")Combining getting and filteringget_filings(2022,form="D")Convert the filings to a pandas dataframeThe filings data is stored in theFilingsclass as apyarrow.Table. You can get the data as a pandas dataframe usingto_pandasdf=filings.to_pandas()Navigating filingsThe Filings object allows you to navigate through filings usingfilings.next()andfilings.prev().
This shows you pages of the data - the page size is about 50.# To see the next page of datafilings.next()# To see the previous pagefilings.prev()# To see the current pagefilings.current()Getting the latest filingsYou can get the latestnfilings by filing_date from a filings usingfilings.latest().If you provide the parameternit will return the latestnfilings.filing=filings.latest(n=5)filingIf you omit this parameter, or setn=1it will return a single `Filings object.filing=filings.latest()filingFiltering filingsYou can filter the filings object using tefilter()function. This allows you to filter
by filing date, or by form.Filtering filings by dateTo filter by filing date specify the filing date inYYYY-MM-DDformat e.g.2022-01-24(Note the parametersdateandfiling_dateare equivalent aliases for each other)filings.filter(date="2021-01-24")# or filings.filter(filing_date="2021-01-24")You can specify a filing date range using the colonfilings.filter(date="2021-01-12:2021-02-28")To filter by dates before a specified date use `:YYYY-MM-DD'filings.filter(date=":2021-02-28")To filter by dates after a specified date use `YYYY-MM-DD:'filings.filter(date="2021-02-28:")Filtering filings by formYou can filter filings by form using theformparameter.filings.filter(form="10-K")To filter by form e.g.10-Kand include form amendments useamendments = True.filings.filter(form="10-K",amendments=True)Working with a single filingYou can get a single filing from the filings using the bracket operator[],
specifying the index of the filing. The index is the value displayed in the leftmost
position in the filings table. For example, to get the10-QforCostcoin the table above
usefilings[3]filing=filings[3]View the filing homepageYou can view the filing homepage in the terminal usingfiling.homepageThis gives you access to theFilingHomepageclass that you can use to list all the documents
and datafiles on the filing.filing.homepageOpen a filingYou can open the filing in your browser usingfiling.open(). This will work on environments with access to the browser,
will probably not work on a remote server.filing.open()Open the Filing HomepageYou can open the filing homepage in the browser usingfiling.homepage.open().filing.homepage.open()View the filing as MarkdownYou can view the filing's HTML content as markdown in the console usingview(). It works for all filing types
but can be a little slow for filings with large HTML filesfiling.view()Get the filing's htmlYou can get the html content of the filing using.html()filing.html()Get the filing's html as MarkdownYou can get the html content as markdown using.markdown()filing.markdown()Viewing and downloading attachmentsEvery filing has a list of attachments. You can view the attachments usingfiling.attachments# View the attachmentsfiling.attachmentsYou can access each attachment using the bracket operator[]and the index of the attachment.# Get the first attachmentattachment=filing.attachments[0]You can download the attachment usingattachment.download(). This will download the attachment to string or bytes in memory.Automatic parsing of filing dataNow the reason you may want to download attachments is to get information contained in data files.
For example,13F-HRfilings have attached infotable.xml files containing data from the holding report for that filing.Fortunately, the library handles this for you. If you callfiling.obj()it will automatically download and parse the data files
into a data object, for several different form types. Currently, the following forms are supported:FormData ObjectDescription10-KTenKAnnual report10-QTenQQuarterly report8-KEightKCurrent reportMA-IMunicipalAdvisorFormMunicipal advisor initial filingForm 144Form144Notice of proposed sale of securitiesDOfferingOfferings3,4,5OwnershipOwnership reports13F-HRThirteenF13F Holdings ReportNPORT-PFundReportFund ReportEFFECTEffectNotice of EffectivenessAnd other filing with XBRLFilingXbrlFor example, to get the data object for a13F-HRfiling you can do the following:filings=get_filings(form="13F-HR")filing=filings[0]thirteenf=filing.obj()If you callobj()on a filing that does not have a data file, then it will returnNone.Working with XBRL filingsSome filings are inXBRL (eXtensible Business Markup Language)format.
These are mainly the newer filings, as the SEC has started requiring this for newer filings.If a filing is in XBRL format then it opens up a lot more ways to get structured data about that specific filing and also
about the company referred to in that filing.TheFilingclass has anxbrlfunction that will download, parse and structure the filing's XBRL document if one exists.
If it does not exist, thenfiling.xbrl()will returnNone.The functionfiling.xbrl()returns aFilingXbrlinstance, which wraps the data, and provides convenient
ways of working with the xbrl data.filing_xbrl=filing.xbrl()Using the Company APIWith the company API you find a company using thecikorticker.
From the company you can access all their historicalfilings,
and a dataset of the companyfacts.
The SEC's company API also supplies a lot more details about a company including industry, the SEC filer type,
the mailing and business address and much more.Find a company using the cikThecikis the id that uniquely identifies a company at the SEC.
It is a number, but is sometimes shown in SEC Edgar resources as a string padded with leading zero's.
For the edgar client API, just use the numbers and omit the leading zeroes.company=Company(1324424)Find a company using tickerYou can get a company using a ticker e.g.SNOW. This will do a lookup for the company cik using the ticker, then load the company using the cik.
This makes it two calls versus one for the cik company lookup, but is sometimes more convenient since tickers are easier to remember that ciks.Note that some companies have multiple tickers, so you technically cannot get SEC filings for a ticker.
You instead get the SEC filings for the company to which the ticker belongs.The ticker is case-insensitive so you can useCompany("snow")orCompany("SNOW")snow=Company("snow")Company(1832950)Get filings for a companyTo get the company's filings useget_filings(). This gets all the company's filings that are available from the Edgar submissions endpoint.company.get_filings()Filtering filingsYou can filter the company filings using a number of different parameters.classCompanyFilings:...defget_filings(self,*,form:str|List=None,accession_number:str|List=None,file_number:str|List=None,is_xbrl:bool=None,is_inline_xbrl:bool=None):"""Get the company's filings and optionally filter by multiple criteria:param form: The form as a string e.g. '10-K' or List of strings ['10-Q', '10-K']:param accession_number: The accession number that uniquely identifies an SEC filing e.g. 0001640147-22-000100:param file_number: The file number e.g. 001-39504:param is_xbrl: Whether the filing is xbrl:param is_inline_xbrl: Whether the filing is inline_xbrl:return: The CompanyFiling instance with the filings that match the filters"""The CompanyFilings classThe result ofget_filings()is aCompanyFilingsclass. This class contains a pyarrow table with the filings
and provides convenient functions for working with filings.
You can access the underlying pyarrowTableusing the.datapropertyfilings=company.get_filings()# Get the underlying Tabledata:pa.Table=filings.dataGet a filing by indexTo access a filing in the CompanyFilings use the bracket[]notation e.g.filings[2]filings[2]Get the latest filingTheCompanyFilingsclass has alatestfunction that will return the latestFiling.
So, to get the latest10-Qfiling, you do the following# Latest filing makes sense if you filter by form  type e.g. 10-Qsnow_10Qs=snow.get_filings(form='10-Q')latest_10Q=snow_10Qs.latest()# Or chain the function callssnow.get_filings(form='10-Q').latest()Get company factsFacts are an interesting and important dataset about a company accumlated from data the company provides to the SEC.
Company facts are available for a company on the Company Factsf"https://data.sec.gov/api/xbrl/companyfacts/CIK{cik:010}.json"It is a JSON endpoint andedgartoolsparses the JSON into a structured dataset - apyarrow.Table.Getting facts for a companyTo get company facts, first get the company, then callcompany.get_facts()company=Company("SNOW")company_facts=company.get_facts_for_namespace()The result is aCompanyFactsobject which wraps the underlying facts and provides convenient ways of working
with the facts data. To get access to the underyling data use thefactsproperty.You can get the facts as a pandas dataframe by callingto_pandasdf=company_facts.to_pandas()Facts differ among companies. To see what facts are available you can use thefacts_metaproperty.ContributingContributions are welcome! We would love to hear your thoughts on how this library could be better at working with SEC Edgar.Reporting IssuesWe use GitHub issues to track public bugs.
Report a bug byopening a new issue; it's that easy!Making code changesFork the repo and create your branch from master.If you've added code that should be tested, add tests.If you've changed APIs, update the documentation.Ensure the test suite passes.Make sure your code lints.Issue that pull request!Licenseedgartoolsis distributed under the terms of theMITlicense.ContactLinkedInSupportersSubscribe to Polar2  
34