Fund Ticker, Series and Share Class Crosswalk
A dated crosswalk between a fund's ticker, its series, its share class and the registrant that files for it, read from the header of every fund prospectus filing. The join key from a market ticker back to a fund's SEC record.
edgar_fund_series_classes - the dataset name to pass to the Obscura API.
What one row means
One **dated assertion that a fund series has a share class**, read out of the `<SERIES-AND-CLASSES-CONTRACTS-DATA>` block that EDGAR writes into the SGML header of every `497`, `497K` and `485BPOS` prospectus filing. This is the **ticker ↔ series ↔ class ↔ registrant crosswalk** that makes `edgar_nport_filings`, `edgar_nport_holdings` and `edgar_fund_risk_return` joinable to a market symbol. SEC identifies a fund by `S000nnnnnn` and a share class by `C000nnnnnn`; markets identify it by ticker; SEC publishes no mapping between them as a dataset. It does, however, state one - with a date - on every prospectus its funds file. # It is deliberately NOT a slowly-changing dimension Each filing is an OBSERVATION. There is no `valid_from`/`valid_to`, no dedupe and no "current" flag: the history IS the set of observations, and an as-of view is `DISTINCT ON (series_id, class_id) … ORDER BY available_date DESC`. Collapsing observations into intervals in the collector would bake in a merge policy that cannot be undone - the mistake recorded against `domain_subdomains`, where an event-compressed row makes a gap indistinguishable from no change. # A missing ticker is INFORMATION, not a gap `<CLASS-CONTRACT-TICKER-SYMBOL>` is optional and its absence is meaningful: insurance separate-account classes are not exchange-traded, and several ETF trusts state no symbol either. MEASURED over 324 filings on six dissemination days spanning 2023-09 to 2024-07: **4,654 of 5,210 class rows (89.3 %) carry a ticker**, and 108 of the 324 filings state classes with no ticker at all (Sprott's 11 ETF classes on `0001999371-24-005670` among them). NULL is the honest record of that; a lookup that filled it in would be fabrication. See `docs/datasets/edgar_fund_series_classes.md`.
One row per One row per (filing, series, share class) assertion, keyed by (accession, series_id, class_id). The row says 'on this dissemination day, this registrant stated that series S000061500 has class C000199169, named Class A, trading as NGJAX'. The key is the ACCESSION and not the archive path because EDGAR indexes one filing under one path PER associated CIK - measured rare but real on this family, 1 accession in ~700 fans out to 2-8 paths (master.20240228.idx: 837 single-path accessions, one two-path, one eight-path) - so keying on the path would multiply those filings' rows. A series with NO share classes still produces a row, with class_id = '' (the empty-string sentinel, because a NULL cannot sit in a composite primary key); suppressing it would lose the series' existence..
Point-in-time availability
Every Obscura dataset carries available_date: the calendar day the publisher made the row
available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the
same thing on every dataset in the catalog.
For edgar_fund_series_classes: filing_join: available_date is the EDGAR DISSEMINATION day, taken from the bronze object's own day partition, never from the header's FILED AS OF DATE (SEC back-dates it on 4.88% of filings). There is no separate event date and no occurred_on - the assertion IS the filing, so inventing a moment at which a class 'became' tickered would be fabrication. Evidence class B, CONFIRMED: all sampled accessions carry <ACCEPTANCE-DATETIME> on the same calendar day as their FILED AS OF DATE and their dissemination stamp (0001193125-24-131423 -> 20240506 in all three places), and fund supplements are filed during the business day.
Refresh cadence
Obscura refreshes edgar_fund_series_classes every 6 hours - the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.
Schema - 17 columns
The full public column list for edgar_fund_series_classes, with the meaning of every field. The same
schema is served unauthenticated at https://api.obscura.trade/v1/catalog/edgar_fund_series_classes.
| Column | Type | Description |
|---|---|---|
| accession | text · not null | PK part. SEC accession number of the filing carrying the assertion, e.g. `0001193125-24-131423`. The key is the accession, not the archive path: EDGAR lists a filing under one path per associated CIK. |
| series_id | text · not null | PK part. SEC series identifier, `S000061500` - the FUND. The same identifier `edgar_nport_filings` and `edgar_nport_holdings` carry, which is what makes them joinable to a ticker through this table. |
| class_id | text · not null | PK part. SEC class/contract identifier, `C000199169` - the SHARE CLASS. The EMPTY STRING (never NULL) when the series states no classes: a NULL cannot participate in a composite primary key, and dropping the row would erase the series' existence. Read it as "this series, no class named". |
| filename | text · not null | The registrant's canonical SEC EDGAR Archives path for this filing (`edgar/data/{cik}/{accession}.txt`), derived from the payload's own first `FILER:` block rather than from whichever index row was walked - so the scrape path and the replay path write the same value. The join key into `edgar_filings`. |
| available_date | date | Public availability date: the EDGAR DISSEMINATION day, recovered from the bronze object's own day partition. This dataset's ONLY date, and the only one a backtest may key on. |
| series_name | text | Fund name as filed, `Nuveen Global Real Estate Securities Fund` (`<SERIES-NAME>`). |
| class_name | text | Share-class label as filed, `Class A` / `Class C` / `Service Class II` / `Institutional Class` (`<CLASS-CONTRACT-NAME>`). NULL on a class-less series row. |
| ticker | text | **The exchange ticker**, `NGJAX` (`<CLASS-CONTRACT-TICKER-SYMBOL>`). NULL when the filing states none - measured on 10.7 % of class rows, concentrated in insurance separate-account classes (not exchange-traded) and some ETF trusts. That absence is a fact about the class, not a gap to fill. |
| owner_cik | bigint | Central Index Key stated on the SERIES itself (`<OWNER-CIK>`) - the registrant that owns this fund. Read per series rather than taken from the header, because a combined filing can carry series belonging to different trusts and the header names only the filer. |
| cik | bigint | Central Index Key of the FILING's primary registrant (the trust), from the header's first `FILER:` block. Equal to `owner_cik` on a single-trust filing; kept separately so a combined filing's fan-out is visible rather than assumed away. |
| company_name | text | Filing registrant's name as EDGAR conforms it, `Nuveen Investment Trust V` (`COMPANY CONFORMED NAME:`). |
| sec_file_number | text | The SECURITIES ACT registration file number - `333-138592`, `033-63759`, `002-95973`. Joins to `edgar_effectiveness_notices` (the `EFFECT` that made the registration usable). Selected BY PREFIX from every `FILER:` block, because a fund filing routinely carries two: T. Rowe Price's 485BPOS `0001741773-24-001700` states `811-07381` first and `033-63759` second, so reading "the first file number" would record the Investment Company Act number here. |
| ica_file_number | text | The INVESTMENT COMPANY ACT registration number, `811-07381` (or `814-`). The stable identifier of the registered investment company across its life, and what `N-CEN`/`N-PORT` filings key on. Selected by prefix from the same header blocks. |
| assertion_kind | text · not null | Which enclosing block stated the assertion: `existing` (the fund already exists), `new` (a fund LAUNCH), `merger_acquiring` or `merger_target` (a fund absorption, from the two halves of a `<MERGER>` element). MEASURED `existing` on 323 of 323 filings carrying a block, across six dissemination days from 2023-09 to 2024-07 - the `NEW-`/`MERGER-` wrappers belong to the registration forms (`N-1A`, `485APOS`) that are outside this collector's form list, so the other three values are parsed from the EDGAR filer-manual spelling and have NOT been observed on this family. |
| form_type | text · not null | The submission's form type - `497`, `497K` or `485BPOS`. Kept as a column because the block is form-agnostic: `497J`, `N-1A`, `N-CEN` and `485APOS` carry the identical block and can be added later with no schema change. |
| accepted_at | timestamp with time zone | When SEC ACCEPTED the submission (`<ACCEPTANCE-DATETIME>`), US-Eastern wall clock stored under a UTC type - the standing EDGAR convention in this repo. Provenance, never an availability date. NULL on a row ingested from the dissemination feed: the PDS envelope does not carry this stamp, so a NULL is a fact about the envelope and not a decoder gap. |
| filed_as_of | date | SEC's LEGAL filing date (`FILED AS OF DATE`). Kept for parity with `edgar_filings`; NEVER an availability date - SEC both back-dates it and rolls it forward past an after-hours acceptance. |
Access edgar_fund_series_classes
Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.
import obscura
client = obscura.Client("obs_live_…")
df = client.query(
dataset="edgar_fund_series_classes",
symbols=["NVDA", "AAPL"],
start="2024-01-01",
)
Create a free account Browse all 122 datasets
Frequently asked questions
What is in the edgar_fund_series_classes dataset?
A dated crosswalk between a fund's ticker, its series, its share class and the registrant that files for it, read from the header of every fund prospectus filing. The join key from a market ticker back to a fund's SEC record. One **dated assertion that a fund series has a share class**, read out of the `<SERIES-AND-CLASSES-CONTRACTS-DATA>` block that EDGAR writes into the SGML header of every `497`, `497K` and `485BPOS` prospectus filing. This is the **ticker ↔ series ↔ class ↔ registrant crosswalk** that makes `edgar_nport_filings`, `edgar_nport_holdings` and `edgar_fund_risk_return` joinable to a market symbol. SEC identifies a fund by `S000nnnnnn` and a share class by `C000nnnnnn`; markets identify it by ticker; SEC publishes no mapping between them as a dataset. It does, however, state one - with a date - on every prospectus its funds file. # It is deliberately NOT a slowly-changing dimension Each filing is an OBSERVATION. There is no `valid_from`/`valid_to`, no dedupe and no "current" flag: the history IS the set of observations, and an as-of view is `DISTINCT ON (series_id, class_id) … ORDER BY available_date DESC`. Collapsing observations into intervals in the collector would bake in a merge policy that cannot be undone - the mistake recorded against `domain_subdomains`, where an event-compressed row makes a gap indistinguishable from no change. # A missing ticker is INFORMATION, not a gap `<CLASS-CONTRACT-TICKER-SYMBOL>` is optional and its absence is meaningful: insurance separate-account classes are not exchange-traded, and several ETF trusts state no symbol either. MEASURED over 324 filings on six dissemination days spanning 2023-09 to 2024-07: **4,654 of 5,210 class rows (89.3 %) carry a ticker**, and 108 of the 324 filings state classes with no ticker at all (Sprott's 11 ETF classes on `0001999371-24-005670` among them). NULL is the honest record of that; a lookup that filled it in would be fabrication. See `docs/datasets/edgar_fund_series_classes.md`.
How do I avoid look-ahead bias with edgar_fund_series_classes?
Filter on edgar_fund_series_classes.available_date, the day the publisher made the row public. For this dataset that date is derived as follows - filing_join: available_date is the EDGAR DISSEMINATION day, taken from the bronze object's own day partition, never from the header's FILED AS OF DATE (SEC back-dates it on 4.88% of filings). There is no separate event date and no occurred_on - the assertion IS the filing, so inventing a moment at which a class 'became' tickered would be fabrication. Evidence class B, CONFIRMED: all sampled accessions carry <ACCEPTANCE-DATETIME> on the same calendar day as their FILED AS OF DATE and their dissemination stamp (0001193125-24-131423 -> 20240506 in all three places), and fund supplements are filed during the business day. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.
In what formats can I get edgar_fund_series_classes?
As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="edgar_fund_series_classes". The column schema is public at https://api.obscura.trade/v1/catalog/edgar_fund_series_classes.
Can I filter edgar_fund_series_classes by company or symbol?
Yes. edgar_fund_series_classes carries ticker, the column the API's symbols filter resolves against.
How often is edgar_fund_series_classes updated?
Obscura refreshes edgar_fund_series_classes on a every 6 hours schedule - that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.