# TradingView Screener Scraper & API - Stocks, Crypto, FX Monitor (`neverempty/tradingview-screener-monitor`) Actor

For stock screens, crypto scans and trading signals: the TradingView Screener as an API, one row per symbol with ticker, close, change %, volume, market cap, RSI and any indicator you pick, for stocks, crypto and forex. Monitoring returns only symbols that entered or left your screen. No API key.

- **URL**: https://apify.com/neverempty/tradingview-screener-monitor.md
- **Developed by:** [NeverEmpty](https://apify.com/neverempty) (community)
- **Categories:** Business, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 symbol returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## TradingView Screener Scraper & API - Stocks, Crypto, FX Monitor

Run a **TradingView Screener** query and get one row per symbol: ticker, name, close, change %, volume, market cap, RSI, relative volume and any extra indicators you pick. Works for US stocks, stocks of other countries, crypto and forex. Filter by market cap, volume, price, change, RSI or any listed column, and choose the sort order.

**Monitoring mode** runs the same screen on a schedule and returns only what changed: symbols that **entered** the screen, symbols that **left** it, and symbols whose **price moved** by your threshold or more. A run that finds no change returns no symbol rows.

No login, no API key, no browser. The Actor reads one endpoint only (`scanner.tradingview.com/global/scan`), the single path that site's robots.txt allows, and it re-reads robots.txt at the start of every run and stops if that path is no longer allowed.

> This is market data for research and screening. It is **not investment advice**, and most quotes are **delayed** (see "How fresh the values are"). This Actor is not affiliated with or endorsed by TradingView. TradingView's own terms restrict automated and commercial use of its data; check whether your use is permitted before relying on it.

### What you get

| Column | Meaning |
|---|---|
| `symbol` | Exchange and ticker as TradingView writes it, for example `NASDAQ:AAPL` |
| `ticker`, `name`, `exchange` | Ticker, company or pair name, exchange code |
| `close` | Last price TradingView reports, in `currency` |
| `changePct`, `changeAbs` | Change since the previous close, in percent and in price units |
| `volume` | Volume of the current daily bar |
| `marketCap` | Market capitalization (stocks: `market_cap_basic`; crypto: `market_cap_calc`); empty where TradingView has none |
| `rsi`, `relativeVolume` | 14-period daily RSI; volume divided by the 10-day average |
| `indicators` | The extra columns you asked for, by TradingView column name |
| `type`, `subtype`, `country`, `sector`, `industry`, `isPrimaryListing` | Classification as TradingView reports it |
| `dataMode`, `delaySeconds` | How the quote is delivered: `streaming` (0) or `delayed_streaming_900` (900 seconds = 15 minutes) and so on |
| `barTime` | Start of the daily bar the values belong to |
| `change`, `previousClose`, `movePct` | Monitoring mode only: `entered-screen`, `left-screen` or `price-moved`, the remembered price, and the move in percent |
| `listed` | `false` only for a `left-screen` row whose symbol TradingView no longer returns at all |
| `url`, `markets`, `scrapedAt` | Symbol page address, the markets that were screened, time of the run |

Values are passed through as TradingView returns them. A value TradingView does not have is left empty; it is never filled with 0.

### How fresh the values are

TradingView's screener serves each exchange with that exchange's delay, and says so per symbol in `dataMode`. Measured on 2026-10-05:

- US stocks (NASDAQ, NYSE): `delayed_streaming_900`, 15 minutes behind.
- Tokyo (TSE): `delayed_streaming_1200`, 20 minutes behind. India (BSE), German regional exchanges: 15 minutes.
- Futures (NYMEX): `delayed_streaming_600`, 10 minutes.
- Crypto exchanges and forex feeds: `streaming`.

On the same day the close, change and volume of AAPL, KO, TSLA, 8306 and 7203 matched Yahoo Finance's daily values exactly; BTC and EUR/USD differed by a few hundredths of a percent because the venues differ. Read `delaySeconds` on each row rather than assuming.

### Input

- **Markets** (required): `america`, `crypto` (pairs on exchanges), `coin` (coins by market cap), `forex`, `japan`, `uk`, `germany`, `india`, `canada`, `australia`, `hongkong`, `korea`, `brazil`, `france`, `futures`, `cfd` and other TradingView market names. Each name is checked first; a name TradingView does not know comes back as a free row instead of an empty result.
- **Primary listing only**: one row per company. Without it the same stock appears once per exchange and share class.
- **Simple filters**: minimum and maximum market cap, minimum volume, price range, change % range, RSI range, minimum relative volume.
- **More filters**: any listed column with `greater`, `egreater`, `less`, `eless`, `equal`, `nequal`, `in_range`, `not_in_range`. Text values must be written exactly as TradingView writes them, capitals included: `Finance` matches 46 large US companies, `finance` matches none (measured 2026-10-05).
- **Extra indicators**: more columns to return.
- **Sort by / order**, **Maximum symbol rows** (default 100).
- **Monitoring mode**, **Price move threshold (%)**, **Forget remembered symbols**.

Market cap filters cannot be used when crypto markets and other markets are mixed in one run, because TradingView keeps the two in different columns; run them separately.

#### Columns you can filter on, sort by, or add

`name` `description` `close` `change` `change_abs` `volume` `market_cap_basic` `market_cap_calc` `currency` `exchange` `type` `subtype` `update_mode` `country` `sector` `industry` `is_primary` `RSI` `relative_volume_10d_calc` `time` `open` `high` `low` `gap` `VWAP` `RSI7` `MACD.macd` `MACD.signal` `SMA20` `SMA50` `SMA200` `EMA20` `EMA50` `EMA200` `BB.upper` `BB.lower` `ATR` `ADX` `Stoch.K` `Stoch.D` `CCI20` `Mom` `Recommend.All` `Recommend.MA` `Recommend.Other` `Volatility.D` `Volatility.W` `Volatility.M` `Perf.W` `Perf.1M` `Perf.3M` `Perf.6M` `Perf.Y` `Perf.YTD` `price_earnings_ttm` `earnings_per_share_basic_ttm` `price_52_week_high` `price_52_week_low` `High.All` `Low.All` `average_volume_10d_calc` `average_volume_30d_calc` `float_shares_outstanding` `total_shares_outstanding` `premarket_change` `beta_1_year` `price_book_fq` `number_of_employees` `24h_vol|5` `24h_close_change|5` `24h_vol_cmc` `base_currency`

The list is fixed on purpose. TradingView answers a misspelled column with an empty value on every row, and a misspelled filter with "0 symbols", without any error. A column outside this list is refused before anything is read, so a typo cannot look like a real result. Every returned row is also checked against your filters again before it is delivered.

#### Example: large US stocks up 2% or more today

```json
{
  "markets": ["america"],
  "primaryListingOnly": true,
  "minMarketCap": 10000000000,
  "minChangePct": "2",
  "extraColumns": ["SMA50", "SMA200", "Perf.W"],
  "sortBy": "change",
  "sortOrder": "desc",
  "maxResults": 100
}
```

#### Example: watch oversold large caps

```json
{
  "markets": ["america"],
  "primaryListingOnly": true,
  "minMarketCap": 10000000000,
  "maxRsi": "30",
  "monitoringMode": true,
  "priceMovePct": "5"
}
```

### Monitoring mode in detail

1. **First run**: the matching symbols and their prices are remembered. No symbol row is returned and nothing is charged. One free row says how many symbols were remembered.
2. **Later runs** return, in this order: symbols that left the screen, symbols that entered it, symbols whose price moved by the threshold or more from the remembered price.
3. A symbol that is missing from the list is looked up by name and checked against your filters again before it is reported as having left. A `left-screen` row carries its current values, so you can see why it left.
4. The remembered price of a symbol changes only when a row for it was delivered. Small moves therefore add up: three moves of 2% trigger a 5% threshold on the third.
5. Rows that could not be delivered (maximum rows or your spending limit) are not remembered as delivered and come back at the next run.
6. If the list could not be read to the end, nothing is reported as having left and the run is marked `incomplete`.

Memory is kept per combination of markets, filters and threshold, so different screens do not disturb each other. Sort order, maximum rows and extra indicators do not change the memory. A monitored screen may match at most 10,000 symbols.

### Free rows that explain

Rows whose `status` is not `ok` are never charged: `invalid-input`, `unknown-market`, `no-symbols-matched`, `baseline-recorded`, `no-change-since-last-run`, `incomplete`, `too-many-to-monitor`, `budget-reached`, `blocked`, `unreadable`, `robots-disallowed`. Each has a `note` in plain words. A refusal or an unreadable answer is never reported as "no symbols".

### Pricing

Pay per event: one `symbol-returned` event per symbol row delivered. In monitoring mode a run that compared the whole screen and found nothing to return charges one small `scan-checked` event instead. First monitoring runs, rows with a `status` other than `ok`, and runs that could not read TradingView are free. No start fee.

### Limits

- Only what the TradingView screener itself reports; no intraday history, no order book, no news.
- The Actor reads politely (one request at a time, about two per second at most) and up to 20,000 symbols per run.
- Indicator values are daily-timeframe values. Other timeframes are not offered.
- Not investment advice.

### Thanks for using this Actor

We build these tools for people who run them every day, and we improve them from what users tell us.

- **Missing a field, or need another filter?** Tell us in the **Issues** tab. If the data is there, we add it.
- **Found a bug or a wrong value?** Post the run ID in the **Issues** tab. Wrong data is the thing we fix first.

If this Actor saved you time, a short review helps other people find it.

# Actor input Schema

## `markets` (type: `array`):

TradingView market names, one per line. Examples: america (US stocks), crypto (pairs on exchanges), coin (coins by market cap), forex, japan, uk, germany, india, canada, australia, hongkong, korea, brazil, france, futures, cfd. Required. A name TradingView does not know comes back as a free row that says so.

## `primaryListingOnly` (type: `boolean`):

Keep one row per company: only the primary listing, not the same stock on other exchanges or the share classes that TradingView marks as secondary.

## `minMarketCap` (type: `integer`):

Only symbols whose market capitalization is at least this number, in the unit TradingView reports (US dollars for US stocks and for crypto). Leave empty for no minimum.

## `maxMarketCap` (type: `integer`):

Only symbols whose market capitalization is at most this number. Leave empty for no maximum.

## `minVolume` (type: `integer`):

Only symbols whose volume in the current daily bar is at least this many units (shares for stocks). Leave empty for no minimum.

## `minPrice` (type: `string`):

Only symbols whose last price is at least this number, in the currency of the symbol. Leave empty for no minimum.

## `maxPrice` (type: `string`):

Only symbols whose last price is at most this number. Leave empty for no maximum.

## `minChangePct` (type: `string`):

Only symbols whose change since the previous close is at least this percent. 3 means up 3% or more. Leave empty for no minimum.

## `maxChangePct` (type: `string`):

Only symbols whose change since the previous close is at most this percent. -3 means down 3% or more. Leave empty for no maximum.

## `minRsi` (type: `string`):

Only symbols whose 14-period daily RSI is at least this number (0 to 100). Leave empty for no minimum.

## `maxRsi` (type: `string`):

Only symbols whose 14-period daily RSI is at most this number (0 to 100). 30 is the usual oversold line. Leave empty for no maximum.

## `minRelativeVolume` (type: `string`):

Only symbols whose volume is at least this many times their 10-day average (2 means twice the usual). Leave empty for no minimum.

## `filters` (type: `array`):

Extra conditions, all of which must hold. Each is an object with field (a column name from the README list, such as Perf.W, SMA200, sector, exchange, type), operation (greater, egreater, less, eless, equal, nequal, in_range, not_in_range) and value (a number, a text, true or false, or \[low, high] for the range operations). Example: \[{"field":"sector","operation":"equal","value":"Finance"},{"field":"Perf.W","operation":"greater","value":5}]. Text values are case-sensitive (Finance, not finance). A field the Actor does not know is refused before anything is read.

## `extraColumns` (type: `array`):

More TradingView columns to return for every symbol, one per line, from the README list. Examples: MACD.macd, SMA50, SMA200, EMA20, ATR, ADX, Perf.W, Perf.1M, Perf.YTD, Volatility.D, price_earnings_ttm, price_52_week_high, Recommend.All. They come back in the indicators column.

## `sortBy` (type: `string`):

Column the list is ordered by, and which symbols come first when more match than the maximum.

## `sortOrder` (type: `string`):

Highest first or lowest first.

## `maxResults` (type: `integer`):

The most symbol rows this run returns (and charges for). In monitoring mode it limits the changed symbols returned in one run; the rest come at the next run.

## `monitoringMode` (type: `boolean`):

Run the same screen on a schedule. The first run only remembers the matching symbols and their prices (no rows, no charge). Every later run returns only symbols that entered the screen, symbols that left it, and symbols whose price moved by the threshold or more since it was last returned. The screen may match at most 10,000 symbols.

## `priceMovePct` (type: `string`):

Monitoring mode: return a symbol when its price moved at least this percent, up or down, from the remembered price (5 means for example 100 to 105, or to 95). From 0.1 to 1000. Empty means 5.

## `resetMonitoringState` (type: `boolean`):

Clears the monitoring memory for these exact markets, filters and threshold before the run, so the run starts again as a first run.

## Actor input object example

```json
{
  "markets": [
    "america"
  ],
  "minMarketCap": 10000000000,
  "minChangePct": "2",
  "extraColumns": [
    "SMA50",
    "SMA200",
    "Perf.W"
  ],
  "sortBy": "volume",
  "sortOrder": "desc",
  "maxResults": 100,
  "monitoringMode": false,
  "resetMonitoringState": false
}
```

# Actor output Schema

## `results` (type: `string`):

One row per symbol from the TradingView screener: symbol, ticker, name, exchange, close, change %, volume, market cap, currency, RSI, relative volume, the extra indicators you asked for, and how delayed the quote is; in monitoring mode only symbols that entered the screen, left it, or whose price moved past the threshold (with the remembered price). Unknown markets, screens with no match, refusals and limits come back as free rows that say why.

# 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 = {
    "markets": [
        "america"
    ],
    "minMarketCap": 10000000000,
    "minChangePct": "2",
    "extraColumns": [
        "SMA50",
        "SMA200",
        "Perf.W"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/tradingview-screener-monitor").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 = {
    "markets": ["america"],
    "minMarketCap": 10000000000,
    "minChangePct": "2",
    "extraColumns": [
        "SMA50",
        "SMA200",
        "Perf.W",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("neverempty/tradingview-screener-monitor").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "markets": [
    "america"
  ],
  "minMarketCap": 10000000000,
  "minChangePct": "2",
  "extraColumns": [
    "SMA50",
    "SMA200",
    "Perf.W"
  ]
}' |
apify call neverempty/tradingview-screener-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,neverempty/tradingview-screener-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qZLVWmb8pw0dMscWX/builds/ltKO9ZwrkQIUaBtil/openapi.json
