Giter Club home page Giter Club logo

tradingview-screener's Introduction

PyPi Downloads Downloads

pip install tradingview-screener

About

This package allows you to create stock screeners with TradingView, and retrieve the data directly from the official API (without doing any kind of web-scraping/HTML-parsing).

Some of its main features are:

  • Get data from over 3000 fields, including OHLC, indicators, and fundamental data.
  • Variety of markets, including equities, crypto, forex, futures, and bonds.
  • Choose the timeframe for each field, such as 1 minute, 5 minutes, 1 hour, or 1 day.
  • Filter and sort the results using SQL, a common database language.
  • Create and save screeners to easily monitor the markets and identify trading opportunities.

You can find the docs here, and the source on GitHub.

Quickstart

Builtin stock scanners

from tradingview_screener import Scanner

Some of the pre-built scanners:

>>> Scanner.names()
['premarket_gainers',
 'premarket_losers',
 'premarket_most_active',
 'premarket_gappers',
 'postmarket_gainers',
 'postmarket_losers',
 'postmarket_most_active']

Say we want to get the Pre-Market Gainers:

n_rows, df = Scanner.premarket_gainers.get_scanner_data()

And we get a DataFrame with the data:

>>> df
         ticker  name  ...  premarket_change_abs  premarket_volume
0   NASDAQ:APLM  APLM  ...               0.72200          30551043
1      OTC:RNVA  RNVA  ...               0.00005            200000
2      OTC:OCLN  OCLN  ...               0.00690            220000
3   NASDAQ:BKYI  BKYI  ...               0.09740           8826676
4    NASDAQ:ICU   ICU  ...               0.28790           7527703
..          ...   ...  ...                   ...               ...
45     OTC:BSEM  BSEM  ...               0.25000               200
46     NYSE:SWI   SWI  ...               0.76000              5425
47     NYSE:BPT   BPT  ...               0.45000               380
48    NYSE:HOUS  HOUS  ...               0.39000               200
49   NASDAQ:HCM   HCM  ...               1.40000              1950

[50 rows x 8 columns]

With the following columns:

>>> df.columns
Index(['ticker', 'name', 'close', 'volume', 'market_cap_basic',
       'premarket_change', 'premarket_change_abs', 'premarket_volume'],
      dtype='object')

If you aren't yet familiar with Pandas DataFrames, you can convert the output to a list of dictionaries like so:

>>> df.to_dict('records')[:10]
[
    {'ticker': 'NASDAQ:APLM', 'name': 'APLM', 'close': 0.862, 'volume': 94235502, 'market_cap_basic': 146422699.0, 'premarket_change': 127.11267606, 'premarket_change_abs': 0.722, 'premarket_volume': 30551043}
    {'ticker': 'OTC:RNVA', 'name': 'RNVA', 'close': 0.0001, 'volume': 11050007, 'market_cap_basic': 2993432.0, 'premarket_change': 100.0, 'premarket_change_abs': 5e-05, 'premarket_volume': 200000}
    {'ticker': 'OTC:OCLN', 'name': 'OCLN', 'close': 0.0076, 'volume': 2543494, 'market_cap_basic': 9864586.0, 'premarket_change': 86.25, 'premarket_change_abs': 0.0069, 'premarket_volume': 220000}
    {'ticker': 'NASDAQ:BKYI', 'name': 'BKYI', 'close': 0.22, 'volume': 39926873, 'market_cap_basic': 2036156.0, 'premarket_change': 57.05916813, 'premarket_change_abs': 0.0974, 'premarket_volume': 8826676}
    {'ticker': 'NASDAQ:ICU', 'name': 'ICU', 'close': 1.02, 'volume': 46835892, 'market_cap_basic': 19834890.0, 'premarket_change': 36.3510101, 'premarket_change_abs': 0.2879, 'premarket_volume': 7527703}
    ...
]

Creating custom stock screeners

from tradingview_screener import Query, Column

Create a query (like you would in a SQL database):

(Query()
 .select('name', 'close', 'volume', 'relative_volume_10d_calc', 'market_cap_basic')
 .get_scanner_data())
(18060,
          ticker  name  ...  relative_volume_10d_calc  market_cap_basic
 0      AMEX:SPY   SPY  ...                  1.112917               NaN
 1    NASDAQ:QQQ   QQQ  ...                  1.050254               NaN
 2   NASDAQ:TSLA  TSLA  ...                  0.784272      6.589904e+11
 3   NASDAQ:NVDA  NVDA  ...                  0.819148      1.000350e+12
 4   NASDAQ:AMZN  AMZN  ...                  2.206912      1.310658e+12
 ..          ...   ...  ...                       ...               ...
 45     NYSE:UNH   UNH  ...                  0.898852      4.859952e+11
 46  NASDAQ:DXCM  DXCM  ...                  2.763555      3.449933e+10
 47      NYSE:MA    MA  ...                  1.254684      3.429080e+11
 48    NYSE:ABBV  ABBV  ...                  2.007460      2.452179e+11
 49     AMEX:XLK   XLK  ...                  1.041988               NaN
 [50 rows x 6 columns])

Our dataframe only contains 50 rows, even though there are 5271 rows in total. This is because the default LIMIT is 50, but you can change that if you need to. Just keep in mind that the more rows you request, the heavier the load you're putting on the server, and the longer it will take to respond. And if you request too many rows, you might even get banned, so don't get crazy.

A more elaborate query:

(Query()
 .select('name', 'close', 'volume', 'relative_volume_10d_calc')
 .where(
     Column('market_cap_basic').between(1_000_000, 50_000_000),
     Column('relative_volume_10d_calc') > 1.2,
     Column('MACD.macd') >= Column('MACD.signal')
 )
 .order_by('volume', ascending=False)
 .offset(5)
 .limit(25)
 .get_scanner_data())
(393,
          ticker  name     close    volume  relative_volume_10d_calc
 0      OTC:YCRM  YCRM  0.012000  19626514                  1.887942
 1      OTC:PLPL  PLPL  0.000200  17959914                  3.026059
 2   NASDAQ:ABVC  ABVC  1.380000  16295824                  1.967505
 3      OTC:TLSS  TLSS  0.000900  15671157                  1.877976
 4      OTC:GVSI  GVSI  0.012800  14609774                  2.640792
 ..          ...   ...       ...       ...                       ...
 15    AMEX:TPET  TPET  0.483999   2707793                  3.141248
 16     OTC:PWDY  PWDY  0.000700   2138674                  1.802687
 17  NASDAQ:FGEN  FGEN  0.476100   1846644                  1.385978
 18  NASDAQ:VVPR  VVPR  1.930000   1541197                 64.668412
 19     OTC:NAVB  NAVB  0.052000   1475558                  2.491307
 [20 rows x 5 columns])

For more examples have a look here.


How it works

When you call a method like select() or where() on the Query object, it updates a dictionary that contains all the data to send to the API.

For example, the previous query creates the following dictionary:

{
    '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'},
    ],
}

When the get_scanner_data() method is called, it will dump that dictionary as a JSON and send it to the API.

Using this package, you can access and query TradingView data with a simple SQL syntax, without needing to know the details of TradingView's 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

tradingview-screener's Issues

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?

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

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())

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

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.

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?

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

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'"

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

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.