# Dark Pool Pulse — Off-Exchange Volume Scanner (`0xgollum/dark-pool-pulse`) Actor

Scan any stock tickers for dark pool (ATS) trading activity from official FINRA weekly data. Surfaces which venues are moving size off-exchange and flags tickers whose off-exchange volume just spiked versus their recent trailing average.

- **URL**: https://apify.com/0xgollum/dark-pool-pulse.md
- **Developed by:** [0xGollum](https://apify.com/0xgollum) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Dark Pool Pulse — Off-Exchange Volume Scanner 📊

### Changelog

- **2026-07-29** — Reliability fix: runs launched via API/integrations with unset optional fields sent as `null` could fail outright instead of using the documented defaults. Fixed, covered by tests.

**Scan any US stock tickers and find out when their off-exchange ("dark pool") trading volume just spiked — and which venues are behind it.**

### Why dark pool volume matters

Most retail trading happens on public exchanges (Nasdaq, NYSE), where every order is visible in real time. Big institutional trades often happen instead on **dark pools** — private venues (ATS, "Alternative Trading Systems") where large orders can be filled without moving the visible price first.

Individual dark pool orders stay private, but by law every ATS must report its aggregate weekly volume per symbol to FINRA. That data is public and free — but it's raw, delayed, and split across dozens of venues, so nobody looks at it directly. This actor turns it into a signal: **give it a ticker, and it tells you whether this week's off-exchange volume is unusually high compared to that ticker's own recent normal** — a sign that a large player may be moving size quietly before it shows up in the price.

### What you get

Two kinds of rows in one dataset:

**`ticker` rows** — one per flagged symbol:

| Field | Description |
|-------|-------------|
| **week\_start\_date** | The most recent week FINRA has published data for |
| **total\_shares** | Total off-exchange shares traded across all dark pool venues that week |
| **total\_notional** | Same, in dollars |
| **avg\_trailing\_shares** | The ticker's own average weekly off-exchange volume over prior weeks |
| **spike\_ratio** | This week's volume divided by the trailing average — the headline number |
| **num\_venues** | How many distinct dark pools reported volume for this ticker that week |

**`venue` rows** — the top individual dark pools behind that week's volume for the same ticker, with shares, notional value, and their share of that ticker's total off-exchange volume.

Only tickers that clear both a minimum volume and a minimum spike ratio are returned. **Zero flagged tickers = never billed.**

### How it works — read this

Data comes straight from FINRA's official OTC Transparency API (`api.finra.org`), the same body that regulates US equity markets. No scraping fragility, no login, no key — it's a public, government-mandated disclosure. Reporting is delayed (2 weeks for S\&P 500 / Russell 1000 names, 4 weeks for everything else), so "latest week" means the most recent week FINRA has actually published, not the calendar-current one.

The spike ratio is computed per ticker against **its own trailing history** (configurable lookback window), not against other tickers — so a normally-quiet small-cap and a normally-busy mega-cap are each judged against their own baseline.

### Use cases

- **Smart money tracking** — spot tickers where off-exchange volume just broke out of its normal range.
- **Pre-news positioning** — unusual dark pool activity sometimes precedes a public catalyst.
- **Venue research** — see which specific ATS venues are moving size on a given name.
- **Model inputs** — feed the spike ratio into your own screening or backtests.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| **tickers** | array | 20 liquid, volatile large caps (AAPL, TSLA, NVDA, AMD, META...) | US stock/ETF symbols to scan |
| **weeks\_lookback** | integer | 8 | How many prior weeks to average as the baseline |
| **min\_spike\_ratio** | number | 1.5 | Minimum multiple of the trailing average to flag a ticker |
| **min\_weekly\_shares** | integer | 100000 | Minimum latest-week off-exchange share volume to consider (filters illiquid noise) |
| **top\_venues\_per\_ticker** | integer | 5 | How many top dark pool venues to list per flagged ticker |
| **max\_results** | integer | 100 | Cap on ticker rows returned |
| **request\_timeout\_secs** | integer | 30 | HTTP request timeout |

### Output example

```json
{
  "row_type": "ticker",
  "ticker": "NVDA",
  "week_start_date": "2026-07-06",
  "total_shares": 87804579,
  "total_notional": 17642247746.85,
  "avg_trailing_shares": 81326827.14,
  "spike_ratio": 1.08,
  "num_venues": 30
}
```

### Notes

- This is not investment advice — it surfaces a public data signal, not a trade recommendation.
- A ticker not appearing in the results just means its off-exchange volume didn't clear your thresholds that run, not that nothing happened on it.

# Actor input Schema

## `tickers` (type: `array`):

US stock/ETF symbols to scan for dark pool (ATS) activity. Default is a diverse basket of liquid, volatile large caps so a first run is likely to surface at least one real spike (e.g. AAPL, TSLA, NVDA).

## `weeks_lookback` (type: `integer`):

How many prior weeks of FINRA data to average as the 'normal' baseline for each ticker, before comparing against the latest reported week.

## `min_spike_ratio` (type: `number`):

Flag a ticker when its latest week's off-exchange share volume is at least this multiple of its trailing weekly average.

## `min_weekly_shares` (type: `integer`):

Ignore tickers whose latest week's total off-exchange share volume is below this. Filters out illiquid noise.

## `top_venues_per_ticker` (type: `integer`):

How many individual dark pool venues (ATS) to list per flagged ticker for the latest week, ranked by share volume. Set to 0 to skip venue rows.

## `max_results` (type: `integer`):

Cap on the number of ticker summary rows returned per run.

## `request_timeout_secs` (type: `integer`):

HTTP request timeout.

## Actor input object example

```json
{
  "tickers": [
    "AAPL",
    "TSLA",
    "NVDA",
    "AMD",
    "META",
    "NFLX",
    "PLTR",
    "COIN",
    "SOFI",
    "RIVN",
    "MSTR",
    "GME",
    "SMCI",
    "ARM",
    "AVGO",
    "BAC",
    "F",
    "NIO",
    "AAL",
    "QQQ"
  ],
  "weeks_lookback": 8,
  "min_spike_ratio": 1.5,
  "min_weekly_shares": 100000,
  "top_venues_per_ticker": 5,
  "max_results": 100,
  "request_timeout_secs": 30
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "tickers": [
        "AAPL",
        "TSLA",
        "NVDA",
        "AMD",
        "META",
        "NFLX",
        "PLTR",
        "COIN",
        "SOFI",
        "RIVN",
        "MSTR",
        "GME",
        "SMCI",
        "ARM",
        "AVGO",
        "BAC",
        "F",
        "NIO",
        "AAL",
        "QQQ"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("0xgollum/dark-pool-pulse").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "tickers": [
        "AAPL",
        "TSLA",
        "NVDA",
        "AMD",
        "META",
        "NFLX",
        "PLTR",
        "COIN",
        "SOFI",
        "RIVN",
        "MSTR",
        "GME",
        "SMCI",
        "ARM",
        "AVGO",
        "BAC",
        "F",
        "NIO",
        "AAL",
        "QQQ",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("0xgollum/dark-pool-pulse").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "tickers": [
    "AAPL",
    "TSLA",
    "NVDA",
    "AMD",
    "META",
    "NFLX",
    "PLTR",
    "COIN",
    "SOFI",
    "RIVN",
    "MSTR",
    "GME",
    "SMCI",
    "ARM",
    "AVGO",
    "BAC",
    "F",
    "NIO",
    "AAL",
    "QQQ"
  ]
}' |
apify call 0xgollum/dark-pool-pulse --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=0xgollum/dark-pool-pulse",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/RUK3mmeLfdxNwS8Ln/builds/JfX9PpjCF5cmYRjvu/openapi.json
