Technical writing
SEC Form 13F: The Institutional Holdings Disclosure Behind Every Hedge Fund Tracker
Every website that lets you “track hedge fund holdings” or “see what Warren Buffett is buying” is built on a single regulatory filing: SEC Form 13F. Filed quarterly by roughly 5,000 institutional investment managers, 13F is the mandatory public disclosure of every long equity position held by the largest money managers in the United States. Understanding what 13F covers — and what it systematically excludes — is essential for interpreting any analysis built on it.
The Section 13(f) Requirement
Section 13(f) of the Securities Exchange Act of 1934, added by the Securities Acts Amendments of 1975 and implemented by SEC Rule 13f-1, requires any institutional investment manager that exercises investment discretion over $100 million or more in Section 13(f) securities to file a quarterly report disclosing every position. The $100 million threshold is measured at the end of any month during the calendar year: a manager that crosses $100M in October must begin filing the following February, even if assets later fall below the threshold. The SEC maintains a list of Section 13(f) securities — all exchange-listed equity securities at each quarter end — and filers must report their positions in those securities. The list is updated quarterly and available from the SEC.
An institutional investment manager under the statute is broadly defined: it includes any person who uses the mails or any means or instrumentality of interstate commerce in the course of their business to manage securities accounts. This sweeps in hedge funds, mutual fund advisers, bank trust departments, insurance company investment departments, pension fund managers, registered investment advisers, and sovereign wealth fund managers with US equity exposure above the threshold. Approximately 5,000 entities file 13F each quarter.
The original rationale for Section 13(f) was transparency about institutional ownership concentration. The SEC was directed to gather data that would illuminate the influence of large institutional investors on securities markets — data that had been largely invisible before the requirement. Nearly five decades later, that data feeds an entire industry of tracking services, academic research, and investment strategies.
Filing Mechanics: Form Types and Deadlines
The primary filing form is the 13F-HR (Holdings Report), due within 45 days of the end of each calendar quarter:
- Q1 (positions as of March 31) — due by May 15
- Q2 (positions as of June 30) — due by August 15
- Q3 (positions as of September 30) — due by November 15
- Q4 (positions as of December 31) — due by February 15
Two variant form types exist. The 13F-HR/A is an amendment to a previously filed 13F-HR — used to correct errors, add positions that were inadvertently omitted, or update holdings after a confidential treatment period expires. The 13F-CT (Confidential Treatment) is a notice indicating that the filer has requested confidential treatment for some or all of its positions; the actual holdings are filed directly with the SEC but withheld from public EDGAR disclosure pending the SEC's decision on the confidential treatment request.
The 45-day lag is the central limitation of 13F as a real-time information source. A Q4 filing covers positions as of December 31 but may be filed as late as February 15 — 46 days later. A manager who held a position on December 31 has had 46 days to exit it entirely before the public ever sees the disclosure. Combined with the one-quarter observation window, the data can describe a portfolio state that is 45 to 135 days stale by the time any analyst acts on it.
What 13F Covers and What It Excludes
The scope of 13F is specific and consequential. Understanding what is inside and outside the required disclosure is the single most important analytical issue with the dataset.
13F covers: long equity positions in exchange-listed securities; American Depositary Receipts (ADRs) representing foreign shares listed on US exchanges; put and call options on equity securities (disclosed separately in the information table with a PUT/CALL field); warrants on exchange-listed securities; and convertible bonds when they are treated as equity equivalents for 13(f) security list purposes.
13F does not cover: short positions — the critical omission. A manager with a $5 billion long book and a $4 billion short book appears in 13F as a $5 billion long-only manager. The short positions are entirely invisible. Cash and cash equivalents are excluded. Treasury bonds, municipal bonds, and corporate bonds are excluded. Foreign shares listed only on foreign exchanges (not on a US exchange or as ADRs) are excluded. Private equity stakes, venture capital investments, and private credit positions are excluded. Derivatives on indices (S&P 500 futures, for instance) are excluded, as are swaps and other over-the-counter derivatives.
The practical consequence is that 13F presents a systematically bullish, long-only picture of every manager's portfolio. A global macro fund that is net short US equities will show its small long positions in 13F while the offsetting short book remains invisible. An equity long-short fund will show its longs in 13F but not the shorts that hedge them. Every “hedge fund tracker” built on 13F is really a hedge fund long-side tracker — an important caveat that most consumer-facing presentations omit.
EDGAR Filing Structure
13F filings on EDGAR consist of several components. The cover page (filed as XML) identifies the filer, the report period, the total value of all holdings, and whether the filing is an initial report or amendment. The information table (also XML) contains one row per holding position. An optional confidential treatment request may accompany the filing if the manager is seeking to withhold certain positions from public disclosure.
Programmatic access to 13F filings is available through multiple paths. The EDGAR full-text search at https://efts.sec.gov/LATEST/search-index?q=%2213F-HR%22&dateRange=custom&startdt=2024-01-01 supports form-type filtering and date ranges. Bulk quarterly index files at https://www.sec.gov/Archives/edgar/full-index/ list every filing by quarter in a fixed-width text format; filtering for form type 13F-HR yields all holdings reports for that quarter with paths to the underlying XML documents.
The SEC also publishes structured quarterly bulk datasets at the EDGAR data research page, containing three tab-separated files per quarter: SUBMISSION (filer metadata), COVERPAGE (report-level metadata), and INFOTABLE (position-level holdings data). The INFOTABLE file for a single quarter can exceed 500 MB uncompressed and contains every position disclosed by every filer in that quarter — the most efficient starting point for cross-filer analysis.
Holdings Table Schema
The information table XML follows a defined schema. Each position entry contains the following fields:
- NAME OF ISSUER — free-text issuer name as reported by the filer. Not standardized; the same company may appear with different name strings across filers (full legal name, common name, abbreviated name). Not a reliable join key.
- TITLE OF CLASS — a description of the security class: “COM” for common stock, “SHS” for shares, “ADR” for American Depositary Receipts, or option-type identifiers. Also not standardized.
- CUSIP — the nine-character Committee on Uniform Securities Identification Procedures identifier. This is the primary join key for linking 13F holdings to price data, company identifiers, and other securities databases. The CUSIP is far more reliable than the issuer name string for cross-filer and cross-quarter comparison.
- FIPS country code — the Federal Information Processing Standard country code for the issuer's country of incorporation, relevant for identifying foreign issuer ADRs.
- VALUE — the fair market value of the position in thousands of dollars, as of the last trading day of the quarter. This is what all the tracker sites display as the “position size.”
- SHARES/PRN AMT — the number of shares held (for equity positions) or the principal amount (for debt-like instruments). Combined with VALUE, this implies a per-share price that should approximate the quarter-end closing price.
- SH/PRN flag — indicates whether the SHARES/PRN AMT field represents shares (“SH”) or principal amount (“PRN”).
- PUT/CALL — for option positions, identifies whether the reported position is a put or a call. Blank for equity positions.
- INVESTMENT DISCRETION — one of SOLE, SHARED, or OTHER, indicating whether the manager exercises sole investment discretion over the position, shares discretion with another party, or has some other arrangement. Positions with shared or other discretion may not reflect the manager's own investment view.
- VOTING AUTHORITY — separate fields for Sole, Shared, and None voting authority over the shares. For passive index funds that have delegated voting, these fields surface how the proxy voting structure works.
CUSIP is the key to joining 13F data to price and company data. The CUSIP Global Services database is the authoritative source but is licensed and expensive. The OpenFIGI API (figi.openfigi.com) provides a free public interface mapping CUSIP to FIGI, ticker, and exchange — the standard free-tier approach for batch enrichment of 13F positions.
Major Filers and Their Disclosures
The 13F filer universe spans every category of institutional capital:
Berkshire Hathaway (CIK 0001067983) files one of the most closely scrutinized 13Fs each quarter. With a disclosed equity portfolio exceeding $300 billion, Warren Buffett's holdings in Apple, Bank of America, Coca-Cola, and American Express are fully visible. New positions and exits move the stocks disclosed when the filing appears on EDGAR; media coverage of the Berkshire 13F routinely accompanies each quarter. Berkshire is one of the few managers whose 13F represents a genuine long-only concentrated portfolio with minimal hedging — making its disclosures more informative than those of a diversified long-short fund.
BlackRock, Vanguard, and State Street each file massive 13Fs reflecting their passive index fund businesses. Their disclosures show enormous concentrated positions in every large-cap US company — not because they are making active investment decisions, but because they are the largest passive holders of the index weights. A 13F showing BlackRock as the largest shareholder of Apple reveals the structure of passive ownership, not active conviction. These three collectively appear as the top institutional holders of the majority of S&P 500 constituents.
Renaissance Technologies operates the Medallion Fund, the best-performing hedge fund in history, as a private fund for employees only. Medallion positions are not required to be reported in 13F because the fund has no outside investors. Renaissance does file 13F for its external funds — Renaissance Institutional Equities Fund (RIEF) and related vehicles — but these are separate strategies from Medallion and not representative of Medallion's approach. Renaissance has historically obtained confidential treatment for significant portions of its external fund positions.
Concentrated activist funds — Tiger Global, Coatue Management, Viking Global, and Bill Ackman's Pershing Square Capital Management — file 13Fs that reveal concentrated long books. Because these funds run fewer positions with larger individual weights, their 13F disclosures provide more signal per position than a diversified manager's 13F.
Sovereign wealth funds including Norway's Government Pension Fund Global (managed by Norges Bank Investment Management) file 13F for their US equity holdings. Norway's fund holds small ownership stakes across thousands of US-listed companies as part of a global diversification strategy; its 13F reflects index-like coverage rather than concentrated active positions.
Confidential Treatment Requests
Managers may request confidential treatment for specific positions in their 13F filing. The mechanism allows a filer to withhold the disclosure of positions that are actively being accumulated or unwound, where premature disclosure would harm the fund by enabling front-running. A fund building a large stake in a target company, for instance, can request that the SEC treat those positions as confidential while the accumulation is ongoing, preventing competitors from bidding up the price.
Confidential treatment is not automatic. The filer must submit a written request to the SEC demonstrating that disclosure would reveal the manager's portfolio strategy in a way that would cause harm. The SEC grants confidentiality for up to one year, after which the positions must be disclosed in a 13F-HR/A amendment. During the confidential treatment period, those positions are entirely absent from the public filing — the public 13F shows only a note that confidential treatment has been requested, not how many positions or how much value is withheld.
Carl Icahn and other activist investors have historically used confidential treatment requests when accumulating stakes that would later support a public campaign. The SEC denied a significant number of confidential treatment requests during a 2022 reform effort that sought to narrow the grounds for granting confidentiality, though the most stringent proposed changes were not adopted in final form. The structural effect is that confidential treatment creates a category of undisclosed institutional positions that are visible to the SEC but not to the public, introducing selection bias into any analysis that treats 13F as a complete inventory of a manager's holdings.
The 45-Day Lag Problem
The 45-day filing window is the defining limitation of 13F as an investment data source. A Q4 filing reports positions as of December 31 and may be filed as late as February 15 — by which point the disclosed positions may have changed entirely. A fund that held a position on December 31 purely to capture a year-end window-dressing effect may have exited by January 10. The 13F discloses the December 31 snapshot; the investor who acts on it in February is following a 45-day-old map of a portfolio that has moved on.
Academic literature has measured the return to “13F clone” strategies that mirror publicly disclosed positions. Studies find small positive abnormal returns in a short window immediately following disclosure for large-cap stocks, where the disclosed positions are plausibly still held. For small-cap stocks, where the lag between filing and market action is compressed by the faster information adjustment in less-covered names, the evidence of abnormal returns is negligible. The consensus finding is that 13F is more useful for studying institutional preference and crowding than as a trading signal.
Services that aggregate 13F filings — Whale Wisdom, WhaleRock Index, 13F.info, and Quiver Quantitative — present the data in ways that can obscure the lag. A dashboard showing “current holdings” is actually showing the most recent quarterly snapshot, which may be 45 to 135 days old depending on when the filing was made and when the next quarter closes.
Academic Research Using 13F
Institutional 13F data has generated a substantial body of academic research:
Hedge fund performance. Griffin and Xu (2009) used 13F disclosures to study hedge fund stock-picking ability, finding that hedge funds show no significant stock-picking ability on the long positions disclosed in 13F — a finding consistent with the view that whatever edge sophisticated managers have lies in their short books or in positions excluded from the required disclosure.
The tech bubble. Brunnermeier and Nagel (2004) used 13F data to document that hedge funds rode the technology bubble knowingly, holding overvalued tech stocks despite models suggesting overvaluation, and exiting positions shortly before the peak. The 13F quarterly sequence allowed reconstruction of the institutional holding patterns through the bubble and collapse.
Blockholder monitoring. Edmans (2009) used 13F to study the relationship between institutional blockholder ownership and firm performance, finding that large institutional holders improve firm value through the exit threat — the threat that a large holder will sell and drive down the stock price acts as a disciplining mechanism on management even without active engagement. The 13F position-level data made it possible to identify blockholder relationships across the full public company universe.
13F crowding and systemic risk. When many institutional managers hold the same positions — a phenomenon called crowding — a forced deleveraging event causes correlated drawdowns across all funds holding the crowded names. The March 2020 COVID-19 selloff produced a spike in return correlations among crowded hedge fund positions documented in multiple post-hoc studies. Researchers use 13F position overlap to measure crowding ex ante: positions held by a large fraction of institutional filers are more exposed to correlated liquidation.
Information diffusion. 13F data has been used to study how information propagates through institutional networks. Funds that share analysts, prime brokers, or social connections tend to hold similar positions even after controlling for observable factors — a pattern visible in 13F holdings overlap studies.
13F vs. 13D/13G and Form 4: Three Disclosure Regimes
The SEC's ownership disclosure framework encompasses three separate regimes with different triggers and different timing, which are frequently confused:
Form 13F covers all long positions of institutional managers above the $100M threshold, regardless of the percentage of any individual company they own. It is filed quarterly and captures the full institutional long book in Section 13(f) securities.
Schedule 13D and Schedule 13G are triggered when any person or entity acquires beneficial ownership of more than 5 percent of a registered class of equity securities. 13D is the activist form — required when the acquirer has the purpose of influencing the management or control of the issuer. It must be filed within 10 calendar days of crossing the 5 percent threshold, with prompt amendment obligations when material changes occur. 13G is the passive form — available to institutional investors who hold the position without activist intent. The 5 percent threshold triggers disclosure regardless of the manager's total AUM; a small fund that concentrates entirely in one company may file a 13D or 13G without ever being a 13F filer.
Form 4 is filed by corporate insiders — officers, directors, and 10 percent shareholders of the issuer — within two business days of any change in their beneficial ownership. Form 4 is a transaction-level disclosure; 13F is a position snapshot. A corporate insider who is also an institutional investment manager may trigger both Form 4 and 13F obligations simultaneously — Form 4 when they trade in the issuer's own securities, and 13F quarterly for their overall institutional holdings.
The three regimes provide overlapping but non-redundant coverage. A complete picture of institutional ownership around a significant event requires combining 13F position history with 13D/13G threshold crossing disclosures and the Form 4 insider transaction record.
Python: Parsing Berkshire Hathaway's Quarterly Holdings from EDGAR
The script below downloads EDGAR quarterly index files for two consecutive quarters, locates Berkshire Hathaway's 13F-HR filings by CIK, fetches the information table XML from the EDGAR archive, parses holdings sorted by fair market value, computes portfolio concentration in the top 10 positions, and identifies new and eliminated positions quarter-over-quarter. The same approach generalizes to any filer by substituting a different CIK.
import requests
import xml.etree.ElementTree as ET
import zipfile
import io
BASE_INDEX = "https://www.sec.gov/Archives/edgar/full-index"
BASE_EDGAR = "https://www.sec.gov/Archives"
HEADERS = {"User-Agent": "research@example.com"}
# Berkshire Hathaway CIK (zero-padded to 10 digits for some API paths)
BERKSHIRE_CIK = "0001067983"
def get_13f_index(year, quarter):
"""Return all 13F-HR entries from the quarterly EDGAR full-text index."""
url = BASE_INDEX + "/" + str(year) + "/QTR" + str(quarter) + "/form.idx"
r = requests.get(url, headers=HEADERS, timeout=60)
r.raise_for_status()
rows = []
for line in r.text.splitlines():
form_type = line[0:12].strip()
if form_type != "13F-HR":
continue
company = line[12:74].strip()
cik = line[74:86].strip()
filed = line[86:98].strip()
filename = line[98:].strip()
rows.append({"form_type": form_type, "company": company,
"cik": cik, "filed": filed, "filename": filename})
return rows
def find_filer_filing(index_rows, cik):
"""Find a specific filer in the quarterly index by CIK."""
# CIK in the index is stored without leading zeros
target = str(int(cik))
for row in index_rows:
if row["cik"].strip() == target:
return row
return None
def parse_infotable(xml_text):
"""Parse the information table XML from a 13F-HR filing."""
# 13F XML uses namespace; strip it for simpler element lookup
xml_text = xml_text.replace(
' xmlns="http://www.sec.gov/13F/2006"', ""
).replace(
' xmlns="http://www.sec.gov/13F/2011"', ""
)
holdings = []
try:
root = ET.fromstring(xml_text)
except ET.ParseError:
return holdings
for entry in root.findall(".//infoTable"):
name = (entry.findtext("nameOfIssuer") or "").strip()
cls_ = (entry.findtext("titleOfClass") or "").strip()
cusip = (entry.findtext("cusip") or "").strip()
val_str = (entry.findtext("value") or "0").strip()
shs_str = (entry.findtext("sshPrnamt") or "0").strip()
pc = (entry.findtext("putCall") or "").strip()
discr = (entry.findtext("investmentDiscretion") or "").strip()
holdings.append({
"issuer": name,
"class": cls_,
"cusip": cusip,
"value_k": int(val_str) if val_str.isdigit() else 0,
"shares": int(shs_str) if shs_str.isdigit() else 0,
"put_call": pc,
"discretion": discr,
})
return holdings
def fetch_filing_text(filename):
"""Fetch an EDGAR filing document (the .txt wrapper or the XML index)."""
url = BASE_EDGAR + "/" + filename
r = requests.get(url, headers=HEADERS, timeout=60)
r.raise_for_status()
return r.text
def extract_infotable_xml(filing_text):
"""Extract the information table XML block from an EDGAR SGML wrapper."""
marker_open = "<informationTable"
marker_close = "</informationTable>"
start = filing_text.find(marker_open)
end = filing_text.find(marker_close)
if start == -1 or end == -1:
return None
return filing_text[start : end + len(marker_close)]
# --- Main: pull Berkshire Hathaway 13F for Q4 2024, compare to Q3 2024 ---
year_curr, qtr_curr = 2024, 4
year_prev, qtr_prev = 2024, 3
print("Fetching quarterly index for " + str(year_curr) + " Q" + str(qtr_curr) + "...")
index_curr = get_13f_index(year_curr, qtr_curr)
print("Fetching quarterly index for " + str(year_prev) + " Q" + str(qtr_prev) + "...")
index_prev = get_13f_index(year_prev, qtr_prev)
filing_curr = find_filer_filing(index_curr, BERKSHIRE_CIK)
filing_prev = find_filer_filing(index_prev, BERKSHIRE_CIK)
if not filing_curr:
print("Berkshire Hathaway not found in Q4 2024 index")
else:
print("Found: " + filing_curr["company"] + " filed " + filing_curr["filed"])
text_curr = fetch_filing_text(filing_curr["filename"])
xml_curr = extract_infotable_xml(text_curr)
holdings_curr = parse_infotable(xml_curr) if xml_curr else []
text_prev = fetch_filing_text(filing_prev["filename"])
xml_prev = extract_infotable_xml(text_prev)
holdings_prev = parse_infotable(xml_prev) if xml_prev else []
# Sort by fair market value descending
holdings_curr.sort(key=lambda x: x["value_k"], reverse=True)
total_k = sum(h["value_k"] for h in holdings_curr)
top10_k = sum(h["value_k"] for h in holdings_curr[:10])
pct_top10 = round(top10_k / total_k * 100, 1) if total_k > 0 else 0
print("")
print("Berkshire Hathaway Q4 2024 Top 10 Holdings (value in $000s):")
print(" " + "Issuer".ljust(30) + " " + "CUSIP".ljust(10) + " " + "Value ($000s)".rjust(15))
print(" " + "-" * 60)
for h in holdings_curr[:10]:
issuer = h["issuer"][:28].ljust(30)
cusip = h["cusip"].ljust(10)
val = str(h["value_k"]).rjust(15)
print(" " + issuer + " " + cusip + " " + val)
print("")
print("Total portfolio value: $" + str(total_k) + "k")
print("Top 10 concentration: " + str(pct_top10) + "% of total")
# Quarter-over-quarter comparison: new and eliminated positions
cusips_curr = {h["cusip"] for h in holdings_curr}
cusips_prev = {h["cusip"] for h in holdings_prev}
new_positions = [h for h in holdings_curr if h["cusip"] not in cusips_prev]
eliminated = [h for h in holdings_prev if h["cusip"] not in cusips_curr]
print("")
print("New positions (not in Q3 2024):")
for h in sorted(new_positions, key=lambda x: x["value_k"], reverse=True):
print(" + " + h["issuer"][:40] + " " + h["cusip"])
print("")
print("Eliminated positions (not in Q4 2024):")
for h in sorted(eliminated, key=lambda x: x["value_k"], reverse=True):
print(" - " + h["issuer"][:40] + " " + h["cusip"])
A few implementation notes. The quarterly index form.idx file stores CIKs without leading zeros, so numeric comparison is required for reliable lookup. The 13F XML information table uses a namespace declaration that varies across filing years; stripping the namespace before parsing is the simplest approach for standard-library XML handling. The value field is reported in thousands of dollars — multiply by 1,000 for actual dollar amounts. Quarter-over-quarter CUSIP comparison is more reliable than issuer name comparison because name strings change across filers and over time.
Related writing
SEC Form 4: The Insider Trading Disclosure Behind Every Officer and Director Stock Transaction — the companion EDGAR filing regime covering corporate insider transactions: how Section 16(a) works, the transaction code taxonomy, the 10b5-1 plan problem, and Python for screening open-market officer purchases.
SEC EDGAR XBRL Financials: Machine-Readable Fundamentals for Every Public Company — the financial statement data filed by the same companies whose institutional ownership appears in 13F: how XBRL tagging works, the US-GAAP taxonomy, the Company Facts and frames APIs, and Python for cross-sectional fundamental screening.
CFTC Commitments of Traders: The Weekly Federal Report Behind Futures Market Positioning — the futures-market analog to 13F: how the CFTC's weekly COT report discloses institutional positioning across commodity and financial futures, what the commercial vs. non-commercial split reveals, and how to access the bulk data.