Filings

There are multiple ways to download filings. The most direct way is to use the secedgar.filings() function. This function will return a class which tries to best match your needs based on the arguments provided. For the more technical, the secedgar.filings() function is a factory.

If you find that this does not meet your needs for any reason or would like more direct control over what is being created, you can use the following classes:

Supported filing types can be found at Filing Types

Filings Function

secedgar.filings(cik_lookup=None, filing_type=None, user_agent=None, start_date=None, end_date=datetime.date(2024, 11, 23), count=None, client=None, entry_filter=<function <lambda>>, **kwargs)

Utility method to get best filing object.

Parameters:
  • cik_lookup (str) – Central Index Key (CIK) for company of interest.

  • start_date (datetime.date, optional) – Date of daily filing to fetch.

  • end_date (datetime.date, optional) – Date of daily filing to fetch.

  • filing_type (secedgar.core.filing_types.FilingType, optional) – Valid filing type enum. Defaults to None. If None, then all filing types for CIKs will be returned.

  • count (int, optional) – Number of filings to fetch. Will fetch up to count if that

  • available. (many filings are available. Defaults to all filings) –

  • client (secedgar.client.NetworkClient, optional) – Client to use. Defaults to secedgar.client.NetworkClient if None given.

  • entry_filter (function, optional) – A boolean function to determine if the FilingEntry should be kept. Defaults to lambda _: True. See secedgar.core.DailyFilings for more detail.

  • kwargs – Any keyword arguments to pass to NetworkClient if no client is specified.

Examples

Using the filings function from secedgar is the easiest way to retrieve filings.

Depending on the arguments given, secedgar will return an object that will get you the information you want from EDGAR.

There are 4 main classes which can be returned.

To get all filings over a time span, you could use something like below.

from datetime import date
from secedgar import filings, FilingType

# secedgar creates correct filing object for given arguments
# this will fetch the first 50 filings found over the time span
my_filings = filings(start_date=date(2020, 12, 10),
                     end_date=date(2020, 12, 15),
                     filing_type=FilingType.FILING_4,
                     user_agent="Name (email)",
                     count=50)

# easy access to methods shared across all 4 different filing classes
my_filings_urls = my_filings.get_urls()
my_filings.save("/path/to/directory")

To get a single filing type for one or more companies, you could use this:

from secedgar import filings, FilingType

# similar to above, but fetches filings for specific tickers
company_filings = filings(cik_lookup=["aapl", "fb"],
                          filing_type=sec.FilingType.FILING_10Q,
                          user_agent="Name (email)")
company_filings_urls = company_filings.get_urls()
company_filings.save("/path/to/directory")

To get filings for a single day, you could use something like this:

from datetime import date
from secedgar import filings

# all filings for
daily_filings = filings(start_date=date(2020, 1 ,3),
                        end_date=date(2020, 1, 3),
                        user_agent="Name (email)")
daily_filings.save("/path/to/directory")

# limit which quarterly filings to use - saves only form 4 filings
limit_to_form4 = lambda f: f.form_type.lower() == "4"
daily_filings_limited = filings(start_date=date(2020, 1 ,3),
                                end_date=date(2020, 1, 3),
                                user_agent="Name (email)",
                                entry_filter=limit_to_form4)
daily_filings_limited.save("/path/to/other/directory")

For getting filings from a specific quarter, the function call would look like this:

from datetime import date
from secedgar import filings

# all quarterly filings
quarterly_filings = filings(start_date=date(2020, 1 ,1),
                            end_date=date(2020, 3, 31),
                            user_agent="Name (email)")
quarterly_filings.save("/path/to/directory")

# limit which quarterly filings to use
# saves only 10-K and 10-Q filings from quarter
limit_to_10k_10q = lambda f: f.form_type.lower() in ("10-k", "10-q")
quarterly_filings_limited = filings(start_date=date(2020, 1 ,1),
                                    end_date=date(2020, 3, 31),
                                    user_agent="Name (email)",
                                    entry_filter=limit_to_10k_10q)
quarterly_filings_limited.save("/path/to/other/directory")

Filings Classes

Filing

class secedgar.CompanyFilings(cik_lookup, filing_type=None, user_agent=None, start_date=None, end_date=datetime.date(2024, 11, 23), client=None, count=None, ownership='include', match_format='ALL', **kwargs)

Base class for receiving EDGAR filings.

Parameters:
  • cik_lookup (str) – Central Index Key (CIK) for company of interest.

  • filing_type (Union[secedgar.core.filing_types.FilingType, None]) – Valid filing type enum. Defaults to None. If None, then all filing types for CIKs will be returned.

  • user_agent (Union[str, NoneType]) – Value used for HTTP header “User-Agent” for all requests. If given None, a valid client with user_agent must be given. See the SEC’s statement on fair access for more information.

  • start_date (Union[str, datetime.datetime, datetime.date], optional) – Date before which not to fetch reports. Stands for “date after.” Defaults to None (will fetch all filings before end_date).

  • end_date (Union[str, datetime.datetime, datetime.date], optional) – Date after which not to fetch reports. Stands for “date before.” Defaults to today.

  • count (int) – Number of filings to fetch. Will fetch up to count if that many filings are available. Defaults to all filings available.

  • ownership (str) – Must be in {“include”, “exclude”}. Whether or not to include ownership filings.

  • match_format (str) – Must be in {“EXACT”, “AMEND”, “ALL”}.

  • kwargs – See kwargs accepted for secedgar.client.NetworkClient.

Examples

Restrict the start and end dates by using the start_date and end_date arguments.

from secedgar import FilingType, CompanyFilings
from datetime import date

filing = CompanyFilings(cik_lookup="aapl",
                        filing_type=FilingType.FILING_10K,
                        start_date=date(2015, 1, 1),
                        end_date=date(2019, 1, 1),
                        user_agent="Name (email)")

If you would like to find all filings from some start_date until today, simply exclude end_date. The end date defaults to today’s date.

from secedgar import FilingType, CompanyFilings
from datetime import date

# end date defaults to today
filing = CompanyFilings(cik_lookup="aapl",
                        filing_type=FilingType.FILING_10K,
                        start_date=date(2015, 1, 1),
                        user_agent="Name (email)")

You can also look up a specific filing type for multiple companies.

from secedgar import FilingType, CompanyFilings
from datetime import date

filing = CompanyFilings(cik_lookup=["aapl", "msft", "fb"],
                        filing_type=FilingType.FILING_10K,
                        start_date=date(2015, 1, 1),
                        user_agent="Name (email)")

For a full list of the available filing types, please see secedgar.core.FilingType.

SEC requests that traffic identifies itself via a user agent string. You can customize this according to your preference using the user_agent argument.

from secedgar import FilingType, CompanyFilings
from datetime import date

filing = CompanyFilings(cik_lookup=["aapl", "msft", "fb"],
                        filing_type=FilingType.FILING_10K,
                        start_date=date(2015, 1, 1),
                        user_agent="Name (email)")

New in version 0.4.0.

property cik_lookup

CIKLookup object.

Type:

secedgar.cik_lookup.CIKLookup

static clean_directory_path(path)

Clean string to use as directory name.

Parameters:

path (str) – Directory name to clean.

property client

Client to use to make requests.

Type:

secedgar.client.NetworkClient

property count

Number of filings to fetch.

property end_date

Date after which no filings fetched.

Type:

Union([datetime.date, datetime.datetime, str])

extract_meta(directory, out_dir=None, create_subdir=True, rm_infile=False)

Extract meta data from filings in directory.

property filing_type

FilingType enum of filing.

Type:

secedgar.core.FilingType

static get_accession_number(url)

Get accession number from filing URL.

Note

All URLs are expected to end with /{accession number}.txt

get_urls(**kwargs)

Get urls for all CIKs given to Filing object.

Parameters:

**kwargs – Anything to be passed to requests when making get request. See keyword arguments accepted for secedgar.client.NetworkClient.get_soup.

Returns:

List of urls for txt files to download.

Return type:

urls (list)

get_urls_safely(**kwargs)

Wrapper around get_urls to check if there is a positive number of URLs.

Note

This method will not check if the URLs are valid. Simply if they exist.

Raises:

NoFilingsError – If no URLs exist, then NoFilingsError is raised.

Returns:

Result of get_urls method.

Return type:

urls (dict)

property match_format

The match format to use when searching for filings.

property ownership

Whether or not to include ownership in search.

Type:

str

property params

Parameters to include in requests.

Type:

dict

property path

Path added to client base.

Type:

str

save(directory, dir_pattern=None, file_pattern=None)

Save files in specified directory.

Each txt url looks something like: https://www.sec.gov/Archives/edgar/data/1018724/000101872419000043/0001018724-19-000043.txt

Parameters:
  • directory (str) – Path to directory where files should be saved.

  • dir_pattern (str) – Format string for subdirectories. Default is “{cik}/{type}”. Valid options are {cik} and/or {type}.

  • file_pattern (str) – Format string for files. Default is “{accession_number}”. Valid options are {accession_number}.

Returns:

None

Raises:

ValueError – If no text urls are available for given filing object.

property start_date

Date before which no filings fetched.

Type:

Union([datetime.date, datetime.datetime, str])

Daily Filings

The DailyFilings class can be used to fetch all the URLs for or download all filings from any given day.

class secedgar.DailyFilings(date, user_agent=None, client=None, entry_filter=<function DailyFilings.<lambda>>, **kwargs)

Class for retrieving all daily filings from https://www.sec.gov/Archives/edgar/daily-index.

date

Date of daily filing to fetch.

Type:

datetime.date

user_agent

Value used for HTTP header “User-Agent” for all requests. If given None, a valid client with user_agent must be given. See the SEC’s statement on fair access for more information. Defaults to None.

Type:

Union[str, NoneType], optional

client

Client to use for fetching data. If None is given, a user_agent must be given to pass to secedgar.client.NetworkClient. Defaults to secedgar.client.NetworkClient if none is given.

Type:

Union[NoneType, secedgar.client.NetworkClient], optional

entry_filter

A boolean function to determine if the FilingEntry should be kept. Defaults to lambda _: True. The FilingEntry object exposes 7 variables which can be used to filter which filings to keep. These are “cik”, “company_name”, “form_type”, “date_filed”, “file_name”, and “path”.

Type:

function, optional

kwargs

Keyword arguments to pass to secedgar.filings._index.IndexFilings.

Using entry_filter

To only download filings from a company named “Company A”, the following function would suffice for only getting those filings:

def get_company_a_filings(filing_entry):
    return filing_entry.company_name == "Company A"

To only download Company A or Company B’s 10-K fillings from a specific day, a well-defined entry_filter would be:

def get_company_ab_10k(filing_entry):
    return filing_entry.company_name in ("Company A", "Company B") and
           filing_entry.form_type.lower() == "10-k"

To use the second function as an entry_filter, the following code could be used:

from datetime import date
from secedgar.core import DailyFilings

d = DailyFilings(date=date(2020, 12, 10),
                 entry_filter=get_company_ab_10k,
                 user_agent="Name (email)")
property date

Date of daily filing.

Type:

datetime.date

property idx_filename

Main index filename to look for.

property path

Path added to client base.

Note

The trailing slash at the end of the path is important. Omitting will raise EDGARQueryError.

Type:

str

property quarter

Get quarter number from date attribute.

Type:

int

save(directory, dir_pattern=None, file_pattern='{accession_number}', date_format='%Y%m%d', download_all=False)

Save all daily filings.

Store all filings for each unique company name under a separate subdirectory within given directory argument. Creates directory with date in YYYYMMDD format within given directory.

Parameters:
  • directory (str) – Directory where filings should be stored. Will be broken down further by company name and form type.

  • dir_pattern (str) – Format string for subdirectories. Default is {date}/{cik}. Valid options that must be wrapped in curly braces are date and cik.

  • date_format (str) – Format string to use for the {date} pattern. Default is %Y%m%d.

  • file_pattern (str) – Format string for files. Default is {accession_number}. Valid options are accession_number.

  • download_all (bool) – Type of downloading system, if true downloads all data for the day, if false downloads each file in index. Default is False.

property year

Year of date for daily filing.

Type:

int

Quarterly Filings

The QuarterlyFilings class can be used to fetch all the URLs for or download all filings from any given quarter.

class secedgar.QuarterlyFilings(year, quarter, user_agent=None, client=None, entry_filter=<function QuarterlyFilings.<lambda>>, **kwargs)

Class for retrieving all filings from specific year and quarter.

Parameters:
  • year (int) – Must be in between 1993 and the current year (inclusive).

  • quarter (int) – Must be 1, 2, 3, or 4. Quarter of filings to fetch.

  • user_agent (Union[str, NoneType], optional) –

    Value used for HTTP header “User-Agent” for all requests. If given None, a valid client with user_agent must be given. See the SEC’s statement on fair access for more information. Defaults to None.

  • client (Union[NoneType, secedgar.client.NetworkClient], optional) – Client to use for fetching data. If None is given, a user_agent must be given to pass to secedgar.client.NetworkClient. Defaults to secedgar.client.NetworkClient if none is given.

  • entry_filter (function, optional) – A boolean function to determine if the FilingEntry should be kept. Defaults to lambda _: True. See secedgar.core.DailyFilings for more detail.

  • kwargs – Keyword arguments to pass to secedgar.core._index.IndexFilings.

Examples

import secedgar as sec
quarterly = sec.QuarterlyFilings(year=2021,
                                 quarter=2,
                                 user_agent="Name (email)")
quarterly.save("/path/to/dir")
property idx_filename

Main index filename to look for.

property path

Path property to pass to client.

property quarter

Quarter of filings.

save(directory, dir_pattern=None, file_pattern='{accession_number}', download_all=False)

Save all daily filings.

Creates subdirectory within given directory of the form <YEAR>/QTR<QTR NUMBER>/. Then each distinct company name receives its own directory with all of its filings. See secedgar.core._index.IndexFilings for more detail.

Parameters:
  • directory (str) – Directory where filings should be stored. Will be broken down further by company name and form type.

  • dir_pattern (str) –

    Format string for subdirectories. Default is {year}/QTR{quarter}/{cik}. Valid options to mix and match

    are {year}, {quarter}, and {cik}.

  • file_pattern (str) – Format string for files. Default is {accession_number}. Valid options are {accession_number}.

  • download_all (bool) – Type of downloading system, if true downloads all data for each day, if false downloads each file in index. Default is False.

property year

Year of filings.

Combo Filings

The ComboFilings class can download all filings from a specified time frame. Internally, this class uses a mixture of DailyFilings and QuarterlyFilings to get all of the needed filings.

class secedgar.ComboFilings(start_date: ~datetime.date, end_date: ~datetime.date, user_agent: str | None = None, client=None, entry_filter=<function ComboFilings.<lambda>>, balancing_point=30, **kwargs)

Class for retrieving all filings between specified dates.

Parameters:
  • start_date (Union[str, datetime.datetime, datetime.date], optional) – Date before which not to fetch reports. Stands for “date after.” Defaults to None (will fetch all filings before end_date).

  • end_date (Union[str, datetime.datetime, datetime.date], optional) – Date after which not to fetch reports. Stands for “date before.” Defaults to today.

  • user_agent (Union[str, NoneType]) –

    Value used for HTTP header “User-Agent” for all requests. If given None, a valid client with user_agent must be given. See the SEC’s statement on fair access for more information.

  • client (Union[NoneType, secedgar.client.NetworkClient], optional) – Client to use for fetching data. If None is given, a user_agent must be given to pass to secedgar.client.NetworkClient. Defaults to secedgar.client.NetworkClient if none is given.

  • entry_filter (function, optional) – A boolean function to determine if the FilingEntry should be kept. Defaults to lambda _: True. The FilingEntry object exposes 7 variables which can be used to filter which filings to keep. These are “cik”, “company_name”, “form_type”, “date_filed”, “file_name”, “path”, and “num_previously_valid”.

  • balancing_point (int) – Number of days from which to change lookup method from using DailyFilings to QuarterlyFilings. If QuarterlyFilings is used, an additional filter will be added to limit which days are included. Defaults to 30.

  • kwargs – Any keyword arguments to pass to NetworkClient if no client is specified.

New in version 0.4.0.

Examples

To download all filings from January 6, 2020 until November 5, 2020, you could do following:

from datetime import date
from secedgar import ComboFilings

combo_filings = ComboFilings(start_date=date(2020, 1, 6),
                             end_date=date(2020, 11, 5)
combo_filings.save('/my_directory')
property balancing_point

Point after which to use QuarterlyFilings with entry_filter to get data.

Type:

int

property client

Client to use to make requests.

Type:

secedgar.client.NetworkClient

property daily_date_list

List of dates for which to fetch daily data.

Type:

List of datetime.date

property end_date

Date after which no filings fetched.

Type:

Union([datetime.date])

property entry_filter

A boolean function to be tested on each listing entry.

This is tested regardless of download method.

get_urls()

Get all urls between start_date and end_date.

property quarterly_date_list

List of tuples with year, quarter, and entry_filter to use.

Type:

List of tuples

save(directory, dir_pattern=None, file_pattern='{accession_number}', download_all=False, daily_date_format='%Y%m%d')

Save all filings between start_date and end_date.

Only filings that satisfy args given at initialization will be saved.

Parameters:
  • directory (str) – Directory where filings should be stored.

  • dir_pattern (str, optional) – Format string for subdirectories. Defaults to None.

  • file_pattern (str, optional) – Format string for files. Defaults to “{accession_number}”.

  • download_all (bool, optional) – Type of downloading system, if true downloads all data for each day, if false downloads each file in index. Defaults to False.

  • daily_date_format (str, optional) – Format string to use for the {date} pattern. Defaults to “%Y%m%d”.

property start_date

Date before which no filings fetched.

Type:

Union([datetime.date])

Saving Filings

In version 0.3.0, the dir_pattern and file_pattern arguments were introduced to allow for more flexible structuring of filings.

Here are some examples of how you might use those arguments to create custom directory structures

from secedgar import CompanyFilings, FilingType

f = CompanyFilings(cik_lookup=["aapl", "msft"],
                   filing_type=FilingType.FILING_10Q,
                   count=5,
                   user_agent="Name (email)")
f.save("./my_directory",
       dir_pattern="cik_{cik}/{type}",
       file_pattern="{accession_number}")

The code above would create a directory structure that would look something like this:

my_directory/
├── cik_aapl
│   └── 10-q
│       ├── 0000320193-19-000066.txt
│       ├── 0000320193-19-000076.txt
│       ├── 0000320193-20-000010.txt
│       ├── 0000320193-20-000052.txt
│       └── 0000320193-20-000062.txt
└── cik_msft
   └── 10-q
      ├── 0001564590-19-012709.txt
      ├── 0001564590-19-037549.txt
      ├── 0001564590-20-002450.txt
      ├── 0001564590-20-019706.txt
      └── 0001564590-20-047996.txt

This same sort of templating can be used for secedgar.DailyFilings and secedgar.QuarterlyFilings.