quantlab.dataset.sharadar.holdings#

Sharadar 13F institutional ownership (SF3A) as a daily panel, keyed by permaticker.

Institutions file their 13F holdings up to 45 days after each calendar quarter’s end. SF3 holds every holding (security, investor, security type, quarter); SF3A is the vendor’s sum of SF3 by security and quarter, and is what this panel reads: shrholders (institutions holding the common stock), shrunits (their shares, in thousands) and shrvalue (the shares’ value, in USD millions). On the 2026-10-05 pull, SF3A’s holders and shares equal SF3 summed by hand up to rounding.

SF3 has no filing date, and a quarter’s rows fill in as the filings arrive: 40 days after a quarter end, SF3A’s newest quarter can hold a few dozen holders of a stock that has six thousand. SharadarHoldingsDataset therefore shows a quarter from its available date, the first SEP trading day on or after quarter end + 45 days (AVAILABILITY_LAG), until the next quarter’s available date. So a partial quarter is never shown, and a security with no row in the shown quarter shows nothing (NaN) rather than an older quarter’s count. Quarters due before SEP’s first trading day are all available on it, and the latest of them is the one shown. Variables:

  • holders: institutions holding the stock;

  • shares_held: the shares they hold (shrunits times 1,000);

  • value_held: the value of those shares in USD (shrvalue times 1,000,000), as the filers report it at the quarter end;

  • quarter_end: the quarter shown.

The symbol axis is the int64 permaticker. SF3 keys holdings by the security’s ticker, which TICKERS lists only under the price tables (its SF3B rows are investors), so tickers are mapped through SEP’s rows; a ticker SEP does not know (a fund, or a CUSIP Sharadar has no prices for) is left out and counted in the log. SF3A is small and has no lastupdated: update.py pulls it whole every run, and update() appends the new trading days.

A rebuilt store shows each quarter as the vendor holds it now, filings made after the 45 days included; an updated store shows it as it stood on the update. Both show a quarter only from its available date.

Examples#

Build the store and read the holders of a stock:

config = SharadarHoldingsConfig(
    zarr_file_path="/data/quantlab/market/sharadar/sharadar_holdings_1d/sharadar_holdings_1d.zarr",
    raw_data_dir_path="/data/quantlab/downloads/sharadar",
)
SharadarHoldingsDataset(config).update()
panel = SharadarHoldingsDataset(config).panel("2024-01-02", "2024-12-31")
panel["holders"].sel(symbol=199059)  # AAPL

Classes

SharadarHoldingsDataset

Daily panel of 13F holders and shares held, each quarter from quarter end + 45 days.