A large share of US stock trading never touches an exchange. Institutions route big orders to dark pools, private venues where nobody sees the order until it has traded, and retail orders are mostly filled off-exchange by wholesalers.
You do not need a paid data feed to see how much of a stock trades in the dark. FINRA requires every alternative trading system (ATS) and off-exchange dealer to report weekly volume per stock, and publishes it for free through OTC Transparency. The data is just awkward to use: a separate API, paging, tier-specific delays and venue-level rows you have to add up yourself.
What you will build
- Weekly dark pool volume, trades and dollar value for a watchlist
- The dark pool venues where each stock trades the most
- A flag for weeks when dark pool volume jumps well above normal
- A market-wide list of the most traded dark pool stocks
The data source
We will use the Dark Pool Volume Tracker, which reads FINRA's OTC Transparency weekly data and returns one report per stock:
| Field | Meaning |
|---|---|
weekStartDate |
the latest week FINRA has published |
atsShares, atsTrades, atsNotionalUsd
|
dark pool (ATS) volume that week |
avgAtsTradeSize |
shares per dark pool trade |
otcNonAtsShares |
other off-exchange volume, mostly wholesalers |
atsChangeWoWPct, atsVsAverage
|
change vs last week and vs recent average |
unusualAtsVolume |
true when the week is well above normal |
topVenues |
the biggest dark pools for the stock, with market share |
history |
the previous weeks, for charting |
It costs $5 per 1,000 stock reports.
Step 1: Setup
pip install apify-client pandas
export APIFY_TOKEN="your-token-here" # Apify Console → Settings → API & Integrations
Step 2: Dark pool volume for a watchlist
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("smartmoney-data/dark-pool-volume-tracker").call(
run_input={"tickers": ["AAPL", "TSLA", "NVDA", "GME"], "weeks": 8}
)
reports = list(client.dataset(run["defaultDatasetId"]).iterate_items())
for r in reports:
print(r["ticker"], r["weekStartDate"], f'{r["atsShares"]:,}', "dark pool shares,",
f'{r["atsVsAverage"]}x average')
In a test run on October 13, 2026, the latest week FINRA had published for Tier 1 stocks was September 21. AAPL traded 23.2 million shares on 32 dark pools that week, worth about $7.9 billion, 15% fewer shares than the week before (0.79x its recent average). Dark pools made up 33% of AAPL's off-exchange volume; the other 67% was other off-exchange trading, mostly wholesalers filling retail orders.
Step 3: Where does a stock trade in the dark?
aapl = next(r for r in reports if r["ticker"] == "AAPL")
for v in aapl["topVenues"]:
print(f'{v["name"]:<30} {v["shares"]:>12,} shares {v["sharePct"]}%')
For AAPL in that week, UBS ATS was the largest venue with 14.3% of dark pool volume, followed by Intelligent Cross, Level ATS, BIDS and OneChronos. BIDS is worth watching: it handled only 3,630 trades but 1.6 million shares, which works out to about 435 shares per trade. That is block trading, the kind institutions do.
Step 4: Flag unusual weeks
A stock whose dark pool volume suddenly doubles is worth a closer look: somebody large may be building or unwinding a position quietly.
run = client.actor("smartmoney-data/dark-pool-volume-tracker").call(
run_input={"tickers": ["AMC", "GME", "PLTR", "SOFI", "RIVN"],
"unusualRatio": 2, "onlyUnusual": True}
)
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
print(r["ticker"], r["atsVsAverage"], "x normal,", r["atsChangeWoWPct"], "% week over week")
Step 5: The whole market
Leave tickers empty to get the stocks with the most dark pool volume in the latest week:
run = client.actor("smartmoney-data/dark-pool-volume-tracker").call(run_input={"topCount": 50})
Step 6: Chart the history
import pandas as pd
hist = pd.DataFrame(aapl["history"]).set_index("weekStartDate").sort_index()
hist[["atsShares", "otcShares"]].plot(kind="bar", stacked=True, title="AAPL off-exchange volume")
Going further
- Pair dark pool volume with short interest, fails-to-deliver and the Reg SHO list in Short Squeeze Radar.
- See who owns the stock with Institutional Ownership by Ticker.
Use it from an AI assistant
https://mcp.apify.com/?tools=smartmoney-data/dark-pool-volume-tracker
Then ask: "Which of my stocks had unusually high dark pool volume in the latest FINRA week?"
FAQ
Is this real-time dark pool data? No. Real-time dark pool prints come from paid feeds. This is FINRA's official weekly data, published two weeks after the week ends for Tier 1 (S&P 500 and Russell 1000) stocks and four weeks for everything else.
What is the difference between ATS and OTC volume? ATS volume is trading on registered alternative trading systems, which is what people usually mean by dark pools. OTC non-ATS volume is other off-exchange trading, mostly wholesalers filling retail orders.
Is this legal to use? Yes. FINRA publishes OTC Transparency data for public use.
Data is for informational purposes only and is not investment advice.
Top comments (0)