DEV Community

SmartMoneyData
SmartMoneyData

Posted on

Track Dark Pool Volume for Any Stock with Free FINRA Data (Python)

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
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

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"]}%')
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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})
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

Going further

Use it from an AI assistant

https://mcp.apify.com/?tools=smartmoney-data/dark-pool-volume-tracker
Enter fullscreen mode Exit fullscreen mode

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)