# TradingView Screener Scraper (`axiomworks/tradingview-screener-scraper`) Actor

Read instrument data from TradingView’s public scanner and save one row per exchange-qualified symbol. Results can include close, change, volume, market cap, sector, RSI, exchange, and type. Configure scanner columns, filters, market, sort order, and maximum results without a login.

- **URL**: https://apify.com/axiomworks/tradingview-screener-scraper.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** Business
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.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.
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

**Returns:** one row per instrument with symbol, description, close, change, volume, market_cap_basic, exchange, and type.
**Input:** `{"market":"america","filters":[{"left":"type","operation":"equal","right":"stock"}],"maxItems":20}`
**Best for:** stock screeners, market snapshots, and structured instrument research.

```json
{"symbol": "NASDAQ:NVDA", "description": "NVIDIA Corporation", "close": 228.52, "change": 0.9720749381406932, "volume": 84030656, "market_cap_basic": 5507332178229.848, "exchange": "NASDAQ"}
```

### What does TradingView Screener Scraper do?

TradingView Screener Scraper reads public instrument rows from the TradingView scanner API and saves one dataset row for each unique exchange-qualified symbol. It supports the scanner markets exposed by the endpoint, including American stocks and crypto instruments. You choose scanner filters, requested columns, sort field, sort direction, and a maximum row count. The Actor makes requests to `scanner.tradingview.com`, checks available scanner columns with the market's metainfo endpoint, and pages through the scan response until the requested count is reached or the results end.

The output is a compact TradingView API view of the screener. It is useful when you need a repeatable table of market values rather than manually copying a changing browser table. The `id` and `symbol` fields contain the exchange-qualified scanner symbol, such as `NASDAQ:NVDA`. Each row also has a TradingView symbol page in `sourceUrl`. This Actor does not require a TradingView login. It uses the public scanner response; figures can change between runs as the underlying market changes.

### What data can you get?

The Actor publishes the following fields. A standard field can be `null` when it is not available for the selected instrument or market. Standard fields are always requested; `columns` adds extra fields. The `id`, `sourceUrl`, and `symbol` fields identify every accepted row.

| Field | Meaning |
| --- | --- |
| `id` | Stable exchange-qualified scanner symbol used for deduplication. |
| `sourceUrl` | TradingView symbol page for the scanner instrument. |
| `symbol` | Scanner symbol in `EXCHANGE:TICKER` form. |
| `name` | Scanner name or ticker. |
| `description` | Scanner instrument description. |
| `close` | Scanner close value. |
| `change` | Scanner percentage change value. |
| `volume` | Scanner volume value. |
| `market_cap_basic` | Basic market capitalization when supplied for that instrument. |
| `sector` | Sector classification where the scanner has one. |
| `RSI` | Scanner relative strength index value. |
| `exchange` | Scanner exchange identifier. |
| `type` | Scanner instrument type, such as `stock` or `spot`. |

The overview table shows the columns most useful for quick inspection. The complete dataset row retains every field above, including fields that are `null`. Scanner values are copied as returned; the Actor does not convert currencies, normalize trading volume, or infer a sector. The output reflects the scanner at the time the run makes its requests. If a field is important to your workflow, include its scanner column in `columns` and choose a market where the field exists.

#### Technical, fundamental and performance column groups, and ticker lookup

Two optional inputs make the output richer without hand-writing column names. `columnGroups` accepts `technicals`, `fundamentals` and `performance`. With `technicals` each row also carries `Recommend.All`, `Recommend.MA`, `Recommend.Other`, `MACD.macd`, `MACD.signal`, `Mom`, `Stoch.K`, `Stoch.D`, `ADX`, `CCI20`, `BB.upper`, `BB.lower`, `SMA20`, `SMA50`, `SMA200`, `EMA20`, `EMA50` and `EMA200`. With `fundamentals` you also get `price_earnings_ttm`, `earnings_per_share_basic_ttm`, `dividends_yield_current`, `price_book_fq`, `total_revenue_ttm`, `net_income_ttm`, `beta_1_year`, `industry` and `country`. The `performance` group adds the `Perf.*` columns, 52-week high and low, relative volume and daily volatility. Columns a market does not have are skipped with a warning, so the groups are safe on crypto or forex.

`symbols` is a list of tickers such as `["AAPL","NASDAQ:NVDA","MSFT"]`. Bare tickers match on any exchange; exchange-qualified tickers match exactly. Filters also apply to these tickers. `maxItems` is one shared limit across the entire symbol list; a bare ticker can return rows from several exchanges. Both inputs default to empty.

Example input: `{"market":"america","symbols":["AAPL","NASDAQ:NVDA","MSFT"],"columnGroups":["technicals","fundamentals"],"maxItems":5}`

### How to use

Open the Actor input form, choose a scanner market, and decide how many unique rows to collect. The prefilled example scans American stocks, filters for stock instruments with market capitalization above one billion, sorts by market cap in descending order, and returns up to 20 rows. Run it directly to see the current output. To create another screen, change `filters` to scanner filter objects. Each filter has `left` for a scanner column, `operation` for a scanner comparison, and `right` for the comparison value.

You can use `columns` to add scanner values relevant to your project, such as `Recommend.All` or `price_earnings_ttm`. The standard fields are always requested, and each extra column you add appears in the row under its scanner name. The scanner metainfo endpoint is checked before scanning. Column names are matched without regard to case, common names such as `price` or `marketCap` are mapped to `close` and `market_cap_basic`, and a column the market does not have is skipped with a warning in the log instead of stopping the run.

Filters are forgiving in the same way. Text values such as `technology`, `nasdaq` or `Stock` are matched to the exact values the scanner uses (`Technology Services`, `Electronic Technology`, `Health Technology`, `NASDAQ`, `stock`). Numbers written as text, such as `"1000000000"` or `"1B"`, are converted to numbers, and operators such as `>`, `<=`, `=` or `between` are converted to the scanner's operation names. Every conversion is written to the run log so you can see exactly what was sent.

The Actor requests results in pages and stops at `maxItems`. It uses the scanner's `totalCount` to stop when no more rows exist. A run with `maxItems` set to seven pushes at most seven unique records and charges only those seven successful result pushes. If no rows match, the run succeeds with an empty dataset and a status message suggesting that you loosen filters, check ticker exchange prefixes, or choose another market. A well-formed but unknown market also succeeds with zero rows and a message naming supported examples. A malformed market name fails input validation. Unavailable or blocked scans report what to change, including enabling proxy routing; the first-result request budget is 70 seconds. A scan interrupted after results preserves the rows already saved.

For live scans, consider whether the requested sort field is meaningful in your market. A stock market capitalization sort is useful for large company screens. A crypto volume sort is useful for active pairs, but it can surface instruments whose close value is extremely small. Inspect `symbol`, `exchange`, and `type` alongside the price and volume fields before comparing unlike instruments.

### Input

| Field | Type | Default and use |
| --- | --- | --- |
| `market` | string | `america`; scanner market such as `crypto`, `forex`, or `futures`. |
| `columns` | string array | Extra scanner columns to add to each row; the standard fields are always included. |
| `filters` | object array | Empty by default; scanner comparisons with `left`, `operation`, and `right`. |
| `columnGroups` | string array | `[]`; choose `technicals`, `fundamentals`, or `performance`, e.g. `["technicals"]`. |
| `symbols` | string array | `[]`; tickers such as `["AAPL","NASDAQ:NVDA"]`, combined with the selected market and filters. |
| `sortBy` | string | `market_cap_basic`; scanner column used for sorting. |
| `sortOrder` | string | `desc`; choose `asc` or `desc`. |
| `maxItems` | integer | 50; unique result limit from 1 through 10000. |
| `proxyConfiguration` | object | Apify Proxy disabled by default; enable it when your run needs proxy routing. |

A complete American stock input looks like this:

```json
{
  "market": "america",
  "columns": ["name", "description", "close", "change", "volume", "market_cap_basic", "sector", "RSI", "exchange", "type"],
  "filters": [
    {"left": "market_cap_basic", "operation": "greater", "right": 1000000000},
    {"left": "type", "operation": "equal", "right": "stock"}
  ],
  "sortBy": "market_cap_basic",
  "sortOrder": "desc",
  "maxItems": 20,
  "proxyConfiguration": {"useApifyProxy": false}
}
```

A crypto example can use `market` set to `crypto`, `sortBy` set to `volume`, and `maxItems` set to 30. A column that exists in one scanner market may be absent from another; for example forex and futures have no `market_cap_basic`, so that field is `null` there. The Actor checks requested columns against that market's metainfo response and logs the names it skips. `name` and `description` are valid scanner response columns even though they are omitted from the metainfo field list.

### Output

The following item came from a local run against the public American stock scanner. Market values are time-sensitive and will differ when you run the Actor. The full record includes all output fields so consumers can work with a consistent shape.

```json
{
  "id": "NASDAQ:NVDA",
  "sourceUrl": "https://www.tradingview.com/symbols/NASDAQ-NVDA/",
  "symbol": "NASDAQ:NVDA",
  "name": "NVDA",
  "description": "NVIDIA Corporation",
  "close": 228.52,
  "change": 0.9720749381406932,
  "volume": 84030656,
  "market_cap_basic": 5507332178229.848,
  "sector": "Electronic Technology",
  "RSI": 51.97373465188092,
  "exchange": "NASDAQ",
  "type": "stock"
}
```

The same dataset structure also works for crypto rows. In a local crypto run, `type` was `spot`, while `market_cap_basic` and `sector` were `null` for many decentralized exchange pairs because the scanner has no value for them. Dataset consumers should handle those fields as nullable. The row `id` comes from the scanner's symbol, so the Actor can avoid duplicate identifiers when it moves through result pages.

### How much does it cost?

This Actor is charged per result pushed to the dataset. The `result` event is attached to each successful row push, so a row is charged once. An empty result set does not create result events. The selected `maxItems` limits the number of pushed rows and therefore the number of result events for a run. See the Actor's Pricing tab for current terms. Market data and available rows may vary between runs, so the final count can be below your requested maximum when a filter has fewer matches.

The Actor does not add an enrichment step. It copies values from the scanner response, validates the basic output types, and writes the resulting rows. Its run time depends on the scanner response and on how many pages are needed. Requests are paced to about one per second, and temporary blocks or server errors use retries with backoff. The Actor can move to a fresh Apify Proxy session after a block when proxy routing is available to the run.

### Use with AI agents (MCP)

Apify's MCP server can expose this Actor as a tool to an AI agent. Add an MCP server with the URL `https://mcp.apify.com/?tools=axiomworks/tradingview-screener-scraper` in your agent's MCP configuration. The tool input is the same JSON described above, and the tool's output points to the Actor dataset. Keep `maxItems` explicit in agent prompts when you need a bounded response.

Example agent prompts:

> Run the TradingView screener for American stocks with `type` equal to `stock`, sort by `market_cap_basic` descending, and return 20 rows with symbol, description, close, volume, and sector.

> Scan the crypto market, sort by `volume` descending, return 30 rows, and identify which records have a non-null `close` and `type` equal to `spot`.

> Compare the `RSI` and `change` fields for the first 15 American stock results from a market cap screen, while preserving each row's `sourceUrl`.

An agent should treat the rows as market observations from the scanner, with no implied recommendation. If it needs a current answer, it should run the Actor at the time of the question. The MCP setup does not change the Actor's filters, result limit, or output schema; it supplies another way to call the same run.

### Integrations and API

You can connect the dataset to Apify integrations or call the Actor through the Apify API. The snippets below show the same bounded stock screen in three common clients. Replace the Actor identifier and token in your own environment as appropriate; do not place tokens in public code or logs.

Python:

```python
from apify_client import ApifyClient
import os

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('axiomworks/tradingview-screener-scraper').call(run_input={
    'market': 'america',
    'filters': [{'left': 'type', 'operation': 'equal', 'right': 'stock'}],
    'maxItems': 20,
})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item['symbol'], item['close'])
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('axiomworks/tradingview-screener-scraper').call({
  market: 'america',
  filters: [{ left: 'type', operation: 'equal', right: 'stock' }],
  maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) process.stdout.write(`${item.symbol} ${item.close}\n`);
```

cURL:

```bash
curl -X POST 'https://api.apify.com/v2/acts/axiomworks~tradingview-screener-scraper/run-sync-get-dataset-items' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"market":"america","filters":[{"left":"type","operation":"equal","right":"stock"}],"maxItems":20}'
```

The examples request current rows and should be adapted to your chosen scanner market. Store the dataset if you need to compare runs over time, since the scanner's values can change. A downstream spreadsheet can use `id` as its key, while a dashboard can group by `exchange`, `sector`, or `type` when those fields are populated.

### FAQ

**Why are some fields null?** A standard field may not apply to an instrument or be available in that market. Standard columns are always requested; custom `columns` adds extra fields. Sector is generally relevant to stocks rather than every crypto or forex row. Include the corresponding scanner column and check whether the selected market provides a value.

**What happens with an unsupported column?** The Actor checks scanner metainfo for the selected market before paging. A column or filter the market does not have is skipped with a warning naming it, and the rest of the scan continues. This is useful when a scanner field name changes or is not available for that market.

**How are duplicate rows handled?** The Actor uses the exchange-qualified scanner symbol as `id` and keeps a set of ids already pushed during the run. The same symbol is not pushed twice, even when pages overlap or the scanner ordering changes during a run.

**Does this need a login?** No. The Actor reads the public scanner endpoint. The scanner may still rate limit or block a request; the Actor backs off and retries. Enabling Apify Proxy can help when the site blocks a network route.

**Can I request exactly seven items?** Set `maxItems` to 7. If at least seven valid unique scanner rows match your screen, the Actor pushes seven. If fewer match, it pushes only the rows that exist. The result event is attached only to actual pushed rows.

### Is it legal to scrape TradingView?

The Actor reads public scanner responses without a login. Rules for reuse of market data vary by jurisdiction and use case, and TradingView's terms may affect how you may use its service or redisplay data. Review the terms that apply to your organization and the data rights for any instruments you use. Use modest request volumes and respect the destination's operational limits. This Actor is an independent tool and is not affiliated with TradingView.

### Feedback

If a scanner market, column, or response shape changes, report the market name, input JSON, and error message through the Actor's feedback channel. A small example helps reproduce the issue without sharing private data. Requests for clearer field documentation or an additional supported scanner market are also useful. The output is designed to keep its stable keys even when a field is unavailable, so downstream workflows can remain predictable while scanner coverage evolves.

# Actor input Schema

## `market` (type: `string`):

Scanner market to query, e.g. 'america' for US stocks, 'crypto', 'forex' or 'germany'. Default america screens all US instruments unless filters or symbols narrow it. Select the market containing your symbols; unsupported markets return zero rows with guidance.

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

Conditions combined with AND, e.g. \[{"left":"type","operation":"equal","right":"stock"}]. left is a scanner column; right is a number, text or array. Operations include greater, equal, in_range and match; >, = and between also work. Default \[] adds no conditions. Filters also apply to symbols. Unknown columns or rejected filters are skipped with a warning; inspect logs before relying on a screen.

## `columns` (type: `array`):

Extra scanner columns to return besides the standard ones, e.g. 'Recommend.All', 'price_earnings_ttm', 'dividends_yield_current'. Unknown columns are skipped with a warning. Default: name, description, close, change, volume, market_cap_basic, sector, RSI, exchange, type.

## `columnGroups` (type: `array`):

Column sets to add, e.g. \["technicals","fundamentals"]. Accepts technicals, fundamentals and performance; default \[]. Unavailable columns are skipped with a warning. Technicals adds indicators; fundamentals adds financial ratios; performance adds returns and ranges.

## `symbols` (type: `array`):

Ticker strings in the selected market, e.g. \["AAPL","NASDAQ:NVDA"]. Exchange-qualified tickers match exactly; bare tickers can match multiple exchanges. Filters still apply, so a listed ticker may return no row. Default \[] screens the whole market. maxItems is shared across all tickers, not per ticker; no matches succeed with zero rows and guidance.

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

Scanner column to sort by, e.g. 'market_cap_basic', 'volume', 'change' or 'RSI'. Default market_cap_basic; ignored with a warning if the market lacks it.

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

Order matching rows by sortBy: 'desc' (largest first, default) or 'asc' (smallest first), e.g. 'asc' with sortBy 'close'. Applies to the selected market and filters before maxItems limits the returned rows.

## `maxItems` (type: `integer`):

Total unique instrument limit across the selected market and all symbols, e.g. 20. Integer 1-10000, default 50; not a per-symbol limit. Returns fewer if fewer rows match or the run's spending limit stops collection.

## `proxyConfiguration` (type: `object`):

Apify Proxy options, e.g. {"useApifyProxy":false} (default) or {"useApifyProxy":true}. Blocked requests retry with backoff and use a fresh Apify Proxy session when available. Local runs may have no proxy access.

## Actor input object example

```json
{
  "market": "america",
  "filters": [
    {
      "left": "market_cap_basic",
      "operation": "greater",
      "right": 1000000000
    },
    {
      "left": "type",
      "operation": "equal",
      "right": "stock"
    }
  ],
  "columns": [
    "name",
    "description",
    "close",
    "change",
    "volume",
    "market_cap_basic",
    "sector",
    "RSI",
    "exchange",
    "type"
  ],
  "columnGroups": [],
  "symbols": [],
  "sortBy": "market_cap_basic",
  "sortOrder": "desc",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Scanner result rows

# 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 = {
    "market": "america",
    "filters": [
        {
            "left": "market_cap_basic",
            "operation": "greater",
            "right": 1000000000
        },
        {
            "left": "type",
            "operation": "equal",
            "right": "stock"
        }
    ],
    "columns": [
        "name",
        "description",
        "close",
        "change",
        "volume",
        "market_cap_basic",
        "sector",
        "RSI",
        "exchange",
        "type"
    ],
    "sortBy": "market_cap_basic",
    "sortOrder": "desc",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/tradingview-screener-scraper").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 = {
    "market": "america",
    "filters": [
        {
            "left": "market_cap_basic",
            "operation": "greater",
            "right": 1000000000,
        },
        {
            "left": "type",
            "operation": "equal",
            "right": "stock",
        },
    ],
    "columns": [
        "name",
        "description",
        "close",
        "change",
        "volume",
        "market_cap_basic",
        "sector",
        "RSI",
        "exchange",
        "type",
    ],
    "sortBy": "market_cap_basic",
    "sortOrder": "desc",
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/tradingview-screener-scraper").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 '{
  "market": "america",
  "filters": [
    {
      "left": "market_cap_basic",
      "operation": "greater",
      "right": 1000000000
    },
    {
      "left": "type",
      "operation": "equal",
      "right": "stock"
    }
  ],
  "columns": [
    "name",
    "description",
    "close",
    "change",
    "volume",
    "market_cap_basic",
    "sector",
    "RSI",
    "exchange",
    "type"
  ],
  "sortBy": "market_cap_basic",
  "sortOrder": "desc",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axiomworks/tradingview-screener-scraper --silent --output-dataset

```

## MCP server setup

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

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/iVWuCRLXN6kEF8jHp/builds/BKiE9jNGIb62B0xY7/openapi.json
