Code Monkey home page Code Monkey logo

tradingview-screener's Introduction

Overview

tradingview-screener is a Python package that allows you to create custom stock screeners using TradingView's official API. This package retrieves data directly from TradingView without the need for web scraping or HTML parsing.

Key Features

  • Access Over 3000 Fields: Retrieve data, including OHLC, indicators, and fundamental metrics.
  • Multiple Markets: Screen equities, crypto, forex, futures, and bonds.
  • Customizable Timeframes: Choose timeframes like 1 minute, 5 minutes, 1 hour, or 1 day for each field.
  • Filter and sort the results using a SQL-like syntax, with support for And/Or operators for advanced filtering.

Installation

Install the package via pip:

pip install tradingview-screener

Documentation & Source Code

Quickstart

Here’s a simple example to get you started:

from tradingview_screener import Query

(Query()
 .select('name', 'close', 'volume', 'market_cap_basic')
 .get_scanner_data())

Output:

(17580,
          ticker  name   close     volume  market_cap_basic
 0   NASDAQ:NVDA  NVDA  127.25  298220762      3.130350e+12
 1      AMEX:SPY   SPY  558.70   33701795               NaN
 2   NASDAQ:TSLA  TSLA  221.10   73869589      7.063350e+11
 3    NASDAQ:QQQ   QQQ  480.26   29102854               NaN
 4    NASDAQ:AMD   AMD  156.40   76693809      2.531306e+11
 ..          ...   ...     ...        ...               ...
 45   NASDAQ:PDD   PDD  144.22    8653323      2.007628e+11
 46     NYSE:JPM   JPM  214.52    5639973      6.103447e+11
 47     NYSE:JNJ   JNJ  160.16    7274621      3.855442e+11
 48  NASDAQ:SQQQ  SQQQ    7.99  139721164               NaN
 49  NASDAQ:ASTS  ASTS   34.32   32361315      9.245616e+09
 
 [50 rows x 5 columns])

By default, the result is limited to 50 rows. You can adjust this limit, but be mindful of server load and potential bans.

A more advanced query:

from tradingview_screener import Query, col

(Query()
 .select('name', 'close', 'volume', 'relative_volume_10d_calc')
 .where(
     col('market_cap_basic').between(1_000_000, 50_000_000),
     col('relative_volume_10d_calc') > 1.2,
     col('MACD.macd') >= col('MACD.signal')
 )
 .order_by('volume', ascending=False)
 .offset(5)
 .limit(25)
 .get_scanner_data())

Real-Time Data Access

To access real-time data, you need to pass your session cookies, as even free real-time data requires authentication.

Checking Update Modes

You can run this query to get an overview on the update_mode you get for each exchange:

from tradingview_screener import Query

_, df = Query().select('exchange', 'update_mode').limit(1_000_000).get_scanner_data()
df.groupby('exchange')['update_mode'].value_counts()
exchange  update_mode          
AMEX      delayed_streaming_900    3255
NASDAQ    delayed_streaming_900    4294
NYSE      delayed_streaming_900    2863
OTC       delayed_streaming_900    7129

Example

You can load the cookies from your local browser using rookiepy:

  1. Install rookiepy:

    pip install rookiepy
  2. Load the cookies:

    import rookiepy
    cookies = rookiepy.to_cookiejar(rookiepy.chrome(['.tradingview.com']))  # replace chrome() with your browser
  3. Pass the cookies when querying:

    Query().get_scanner_data(cookies=cookies)

Now, if you re-run the update mode check:

_, df = Query().select('exchange', 'update_mode').limit(1_000_000).get_scanner_data(cookies=cookies)
df.groupby('exchange')['update_mode'].value_counts()
exchange  update_mode          
AMEX      streaming                3256
NASDAQ    streaming                4286
NYSE      streaming                2860
OTC       delayed_streaming_900    7175

We now get live-data for all exchanges except OTC.

Alternative Methods for Loading Cookies

Extract Cookies Manually

Click to unfold example
  1. Go to TradingView

  2. Open the developer tools (Ctrl + Shift + I)

  3. Navigate to the Application tab.

  4. Go to Storage > Cookies > https://www.tradingview.com/

  5. Copy the value of sessionid

  6. Pass it in your query:

    cookies = {'sessionid': '<your-session-id>'}
    Query().get_scanner_data(cookies=cookies)

Authenticate via API

Click to unfold example

While it's possible to authenticate directly via API, TradingView has restrictions on login frequency, which may result in CAPTCHA requests and account flagging (meaning this method won't work again until the cooldown expires and the CAPTCHA is gone).
If you wish to proceed, here’s how:

from http.cookiejar import CookieJar

import requests
from tradingview_screener import Query


def authenticate(username: str, password: str) -> CookieJar:
    session = requests.Session()
    r = session.post(
       'https://www.tradingview.com/accounts/signin/', 
       headers={'User-Agent': 'Mozilla/5.0', 'Referer': 'https://www.tradingview.com'}, 
       data={'username': username, 'password': password, 'remember': 'on'}, 
       timeout=60,
    )
    r.raise_for_status()
    if r.json().get('error'):
        raise Exception(f'Failed to authenticate: \n{r.json()}')
    return session.cookies


cookies = authenticate('<your-username-or-email>', '<your-password>')
Query().get_scanner_data(cookies=cookies)

Comparison to Similar Packages

...

Robustness & Longevity

This package is designed to be future-proof. All columns and markets are documented on the website, which is updated daily via a GitHub Actions script, reducing dependency on hardcoded values.

How It Works

When using methods like select() or where(), the Query object constructs a dictionary representing the API request. Here’s an example of the dictionary generated:

{
    'markets': ['america'],
    'symbols': {'query': {'types': []}, 'tickers': []},
    'options': {'lang': 'en'},
    'columns': ['name', 'close', 'volume', 'relative_volume_10d_calc'],
    'sort': {'sortBy': 'volume', 'sortOrder': 'desc'},
    'range': [5, 25],
    'filter': [
        {'left': 'market_cap_basic', 'operation': 'in_range', 'right': [1000000, 50000000]},
        {'left': 'relative_volume_10d_calc', 'operation': 'greater', 'right': 1.2},
        {'left': 'MACD.macd', 'operation': 'egreater', 'right': 'MACD.signal'},
    ],
}

The get_scanner_data() method sends this dictionary as a JSON payload to the TradingView API, allowing you to query data using SQL-like syntax without knowing the specifics of the API.

tradingview-screener's People

Contributors

shner-elmo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tradingview-screener's Issues

is it possible to get regular trading time data only?

Thanks for the great work, I noticed that the current default setting will return price information including extend trading time, or I am wrong, which includes regular trading time data only. Any way, do we have a way to switch it on and off? thanks again.

Query to filter with "above of below %"

Hi, the new v2 screener of Trading view allows to have filters like this: "Price above New Low 52 Weeks by 100% or more"

I try to implement this filter with the Query() I add a multiplier (*2) at the end of Column('price_52_week_low'):

(Query()
.select('name', 'close', 'price_52_week_low')
.where(
Column('close') >= (Column('price_52_week_low')*2 ) ,
)
.get_scanner_data())

but get this error:

Traceback (most recent call last):
File "", line 4, in
TypeError: unsupported operand type(s) for +: 'int' and 'Column'

Is there any other way to implement this kind of filters using the "above of below %"?

Thank you

Scanner does not return data but Website does

I observed that not always data gets returned.
_, df = Query().select('name', 'close', 'earnings_release_date',, 'earnings_release_next_date').get_scanner_data()

On 07. Feb 2024 for eaxmple for CRUS:
df[df.name == 'CRUS'][['name', 'close', 'earnings_release_date', 'earnings_release_next_date']]
Empty DataFrame
Columns: [name, close, earnings_release_date, earnings_release_next_date]
Index: []

but on TradingView Earnings View/Screener page they are listed for today after Market
image

Why is this? Anything else required to retrieve the data?

Options Data

I'm trying to get options data for the exchange NSE. However if I do,

market = "options"
exchange = "NSE"
max_rows = 50000
#default_columns.remove('Market Capitalization')
(n_rows, df_) = Query().select(*default_columns).limit(max_rows).set_tickers('NSE:HDFCBANK').set_markets(market).get_scanner_data(cookies=cookies)

I get:

HTTPError: 400 Client Error: Bad Request
 Body: {"totalCount":0,"error":"required index \"underlying_symbol\" is missing from request","data":null}
 for url: https://scanner.tradingview.com/options/scan

Are options actually supported? If not, any tips on the correct HTTP request would be appreciated.

Update `constants.py`

First, great package!

I tried to use "close_1_days_back" and I get:
requests.exceptions.HTTPError: 400 Client Error: Bad Request
Body: {"totalCount":0,"error":"Unknown field "close_1_days_back"","data":null}

Seems not existing (anymore).

Is there a way to create an updated constants.py?

Thanks!!
M

Time lag in the result

thanks for the work for this great tool and it works like a charm.

Just realized that the result from the API has a few minutes lag compare to the result directly form the tradingview.

I am a premium user of tradingview. From the website you can't do much as a guest, which is the API's role fetching the data.

No sure what cause the lag. If we need to login to get realtime result, can the tool add this feature in the future? Thanks.

Classic Fundamental Formulas

Thanks for this useful tool.

I wonder, if there is a way to get Beneish-M, Altman-Z, Springate Score etc. by your library...

In TradingView PineScript, these are built in:

ALTMAN_Z_SCORE = request.financial(syminfo.tickerid, "ALTMAN_Z_SCORE", "FY")

BENEISH_M_SCORE = request.financial(syminfo.tickerid, "BENEISH_M_SCORE", "FY")

FULMER_H_FACTOR = request.financial(syminfo.tickerid, "FULMER_H_FACTOR", "FY")

GRAHAM_NUMBERS = request.financial(syminfo.tickerid, "GRAHAM_NUMBERS", "FY")

KZ_INDEX = request.financial(syminfo.tickerid, "KZ_INDEX", "FY")

PIOTROSKI_F_SCORE = request.financial(syminfo.tickerid, "PIOTROSKI_F_SCORE", "FY")

SLOAN_RATIO = request.financial(syminfo.tickerid, "SLOAN_RATIO", "FY")

SPRINGATE_SCORE = request.financial(syminfo.tickerid, "SPRINGATE_SCORE", "FY")

TOBIN_Q_RATIO = request.financial(syminfo.tickerid, "TOBIN_Q_RATIO", "FY")

ZMIJEWSKI_SCORE = request.financial(syminfo.tickerid, "ZMIJEWSKI_SCORE", "FY")

Selected column is not appearing in the DataFrame

Hello Shneor,

Thank you very much for your reply. Much appreciated.

i am running a query which allows me to extract one of the fields I am interested in, 'Revenue (Quarterly QoQ Growth'. I believe it is held in a JSON but could be wrong on this. I am trying to understand how I can place the output from this query into a dataframe? From there I can then manipulate the data, plot it and so on.

image

Thank you very much,

Stephen

Column('Change (1,5, etc)m, %') always returns an error when using .get_scanner_data()

I was testing with the scanner and can't seem to get get passed this error. It seems to be occurring for all the 'Change xm, %'s.

Error:
Exception has occurred: HTTPError 400 Client Error: Bad Request Body: {"totalCount":0,"error":"Unknown field \"change.5\"","data":null} for url: https://scanner.tradingview.com/america/scan File "N:\StockTrading\Live\StockScreener\StockScreener.py", line 20, in <module> .get_scanner_data()) requests.exceptions.HTTPError: 400 Client Error: Bad Request Body: {"totalCount":0,"error":"Unknown field \"change.5\"","data":null} for url: https://scanner.tradingview.com/america/scan

Full code:

from tradingview_screener import Scanner, Query, Column

_, scalpers = (Query()
 .select('name')
 .where(
     Column('Relative Volume') > 1.5,
     Column('relative_volume_10d_calc') > 1.5,
     Column('Change %') >= 8,
 )
 .get_scanner_data())

breakouts = (Query()
 .select('name')
 .where(
     Column('Relative Volume') > 3,
     Column('relative_volume_10d_calc') > 3,
     Column('Relative Volume at Time') > 3,
     Column('Change 5m, %') >= 5
 )
 .get_scanner_data())
#
#_, breakouts = breakouts  # Unpack the tuple to ignore the count and get the DataFrame
## Extract the 'name' column
#tickers = tickers.extend(breakouts['name'].tolist())

print(scalpers['name'].tolist())

Getting data directly from the Tradingview website/URL

Coming from the Time lag issue here, is it possible (to get around a paid account "requirement") for non-delayed data to get it from the Tradingview website directly (screener or markets URL)? I know there are some scrappers exist, but for non-delayed data on the website we have to be signed in with a free account (and I haven't seen this function in them). So my questions are:

  1. How can we get the website data through requests (without having a browser window always open like with scrappers)?
  2. How can we sign in with a free account through requests to make sure the data would be non-delayed?
  3. (optional) Is it possible that free account cookies sent through API don't let us be/stay signed in to get non-delayed data from API? How to check this?

Thank you

API Endpoint Specifications

Hi there,

first of all, thank you for this great library which has helped me out quite a lot.
I was searching for the specific endpoint from tradingview it is using, which I then found to be e.g. 'https://scanner.tradingview.com/america/scan'. Unfortunately I was not able to find the official documentation of this endpoint from tradingview's side.
Could you please provide a link to these informations if they are available so I can check the general conditions of use / specifications.

Thanks in advance and best regards,
Florian

Relative volume query change

Hello It seems like the 'Relative Volume': 'relative_volume_10d_calc' no longer works. It seems like the general 10 day relative volume has been changed to custom values.

image

cannot import name 'Screener' from 'tradingview_screener'

I'm trying to run my python script, even on Replit i get everytime
"Traceback (most recent call last):
File "C:\xxx\tradinview\index.py", line 1, in
from tradingview_screener import Screener
ImportError: cannot import name 'Screener' from 'tradingview_screener'"

Retrieve the next earnings date for a ticker but did receive a float not a date

My idea was to retrieve the next earnings date for a ticker so I checked your code and I think I found the corresponding column to use.
So I tried the customer screener with this query:

Python code used:
tmp = (Query()
.select('name', 'earnings_release_date','Recent Earnings Date','earnings_release_next_date')
.get_scanner_data())
df = tmp[1]
df[df.name == 'PFE']['earnings_release_next_date']

but getting floats instead of dates:

  ticker name  earnings_release_date  earnings_release_date earnings_release_next_date

48 NYSE:PFE PFE 1.706615e+09 1.706615e+09 1.714478e+09

Can you please help/fix?

Real time data

First of all I want to thank you for this great library.

I saw you added a section for getting real time data, but seems like it was not completed. Can you please tell how we can use our auth token to get updated data?

Thanks

Comparing current close price with previous days

It would be helpful to allow the query to compare current price to previous price. For example, if we want to create a scanner that can identify stocks that had 3 down days, and today's low is lower than yesterday's low and current price is higher than yesterday's low.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.