"Who owns this stock?" sounds like a simple question. Most finance sites answer it with the top 10 holders, a quarter late, and put the rest behind a paywall.
The full answer is public. Every investment manager with $100M or more in US stocks files a Form 13F with the SEC each quarter, listing every position. The SEC even publishes all of them as one bulk data set. The problem is size: one quarter is a 100 MB zip holding a 400 MB table of about 3 million positions, keyed by CUSIP rather than ticker.
This tutorial gets you from a ticker to the full holder list, with quarter-over-quarter changes, without downloading any of that yourself.
What you will build
- The full list of institutions holding a stock, largest first
- Who added, reduced, opened (NEW) or EXITED a position versus the previous quarter
- The top buyers and sellers of a stock in one call
- A cross-check of several stocks to see which funds hold all of them
The data source
We will use the Institutional Ownership by Ticker actor. It reads the SEC's quarterly Form 13F data sets, maps your ticker to its CUSIP, and compares the latest quarter with the one before. For each ticker it returns one summary row, then one row per holder:
| Field | Meaning |
|---|---|
filer, filerCik | the fund or institution |
action | NEW, ADDED, REDUCED, UNCHANGED or EXITED vs last quarter |
shares, valueUsd | position at quarter end |
changeShares, changePct | how much they bought or sold |
pctOfInstitutionalShares | their slice of all 13F-reported shares |
putShares, callShares | options, kept apart from the share count |
filingUrl | the original filing on EDGAR |
It costs $2 per 1,000 rows.
Step 1: Setup
pip install apify-client pandas export APIFY_TOKEN="your-token-here" # Apify Console → Settings → API & Integrations Step 2: Get the holders of a stock
import os from apify_client import ApifyClient client = ApifyClient(os.environ["APIFY_TOKEN"]) run = client.actor("smartmoney-data/institutional-ownership-by-ticker").call( run_input={"tickers": ["AAPL", "PLTR"], "maxHoldersPerTicker": 200} ) rows = list(client.dataset(run["defaultDatasetId"]).iterate_items()) summaries = [r for r in rows if r["type"] == "ticker-summary"] holders = [r for r in rows if r["type"] == "holder"] for s in summaries: print(s["ticker"], s["reportPeriod"], s["holders"], "holders,", s["newPositions"], "new,", s["exited"], "exited") In a test run on October 13, 2026 (quarter ending June 30, 2026), this found 6,139 institutions holding AAPL and 2,880 holding PLTR. For AAPL, 295 opened new positions, 2,547 added, 2,892 trimmed and 185 sold out.
Step 3: See who is buying and who is selling
import pandas as pd df = pd.DataFrame(holders) aapl = df[df.ticker == "AAPL"] print(aapl[["filer", "action", "shares", "changeShares", "pctOfInstitutionalShares"]].head(10)) The largest holders come first. In the same run BlackRock held 1.16 billion AAPL shares (11.9% of all 13F-reported shares, up 1.6% on the quarter), followed by Vanguard and State Street.
The summary row already ranks the biggest movers, so you do not have to sort 6,000 rows yourself:
s = next(s for s in summaries if s["ticker"] == "AAPL") for b in s["topBuyers"][:5]: print("BUY ", b["filer"], f'{b["changeShares"]:+,}', b["action"]) for b in s["topSellers"][:5]: print("SELL", b["filer"], f'{b["changeShares"]:+,}', b["action"]) Step 4: Find new money
New positions are often the most interesting rows: a fund that did not own the stock at all last quarter now does.
new = df[df.action == "NEW"].sort_values("valueUsd", ascending=False) print(new[["ticker", "filer", "shares", "valueUsd", "filedOn"]].head(20)) Step 5: Which funds hold all of my stocks?
Run several tickers at once and intersect the holder lists:
held = df[df.action != "EXITED"] counts = held.groupby("filer").ticker.nunique() print(counts[counts == held.ticker.nunique()].index.tolist()[:20]) Going further
- One fund's whole portfolio instead of one stock's holders: Hedge Fund 13F Tracker.
- What the best-known funds agree on: Hedge Fund 13F Consensus.
- Faster signals than 13F: insiders file within two days (Insider Trades), and 5%+ activist stakes within ten (13D/13G).
Use it from an AI assistant
https://mcp.apify.com/?tools=smartmoney-data/institutional-ownership-by-ticker Add it as a remote MCP server in Claude, ChatGPT or Cursor, then ask: "Which funds opened new positions in NVDA last quarter?"
FAQ
Why is the data a quarter behind? Managers have 45 days after each quarter to file, and the SEC then publishes the bulk data set. Every 13F site has the same delay, because it is the same data.
Are short positions included? No. 13F covers long positions, plus puts and calls, which are reported separately here.
What about amended filings? They are applied: a restatement replaces the original report, and a "new holdings" amendment adds to it.
Is this legal to use? Yes. Form 13F filings are public SEC records.
Data is for informational purposes only and is not investment advice.
