Skip to content

Commit

Permalink
Updated readme
Browse files Browse the repository at this point in the history
  • Loading branch information
shner-elmo committed Aug 21, 2024
1 parent 04cd24d commit d3da754
Showing 1 changed file with 169 additions and 72 deletions.
241 changes: 169 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,65 +19,73 @@

</div>

```
pip install tradingview-screener
```

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

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:
### Installation

- 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.
Install the package via pip:

You can find the docs [here](https://shner-elmo.github.io/TradingView-Screener/2.5.0/tradingview_screener.html),
and the source on [GitHub](https://github.com/shner-elmo/TradingView-Screener).
```bash
pip install tradingview-screener
```


### Documentation & Source Code

# Quickstart
- [Documentation](https://shner-elmo.github.io/TradingView-Screener/2.5.0/tradingview_screener.html)
- [GitHub Repository](https://github.com/shner-elmo/TradingView-Screener)

## Creating custom stock screeners

## Quickstart

Here’s a simple example to get you started:

Create a query (like you would in a SQL database):
```python
from tradingview_screener import Query

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

**Output:**

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

Our dataframe only contains 50 rows, even though there are 18060 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.
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:


A more elaborate query:
```python
from tradingview_screener import Query, col

Expand All @@ -93,51 +101,142 @@ from tradingview_screener import Query, col
.limit(25)
.get_scanner_data())
```

<br>

## 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:
```python
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()
```
```
(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])
exchange update_mode
AMEX delayed_streaming_900 3255
NASDAQ delayed_streaming_900 4294
NYSE delayed_streaming_900 2863
OTC delayed_streaming_900 7129
```

For more examples have a look [here](https://shner-elmo.github.io/TradingView-Screener/tradingview_screener/query.html).
### Example

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

1. Install `rookiepy`:

```bash
pip install rookiepy
```

2. Load the cookies:

```python
import rookiepy
cookies = rookiepy.to_cookiejar(rookiepy.chrome(['.tradingview.com'])) # replace chrome() with your browser
```

# Real-time data
3. Pass the cookies when querying:

```python
Query().get_scanner_data(cookies=cookies)
```

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

So if you paid for a live-data add-on you need to login, you can do that
```python
_, 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`.

# Comparison to similar packages

...
### Alternative Methods for Loading Cookies

#### Extract Cookies Manually

<details>
<summary>Click to unfold example</summary>

## Longevity this is made to last, even if the API changes
1. Go to [TradingView](https://www.tradingview.com)
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:

Learned from my mistakes and all columns, markets are documented in the website instead of being hardcoded in the library.
And the website is updated daily by a GH actions script.
```python
cookies = {'sessionid': '<your-session-id>'}
Query().get_scanner_data(cookies=cookies)
```

You can also easily use other operations if theyre not documented: `Query.where({'left': ..., 'right': ..., 'operation': ...})`
</details>

#### Authenticate via API

<details>
<summary>Click to unfold example</summary>

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:

```python
from http.cookiejar import CookieJar
import requests
from tradingview_screener import Query
# 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.
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
For example, the previous query creates the following dictionary:
```py
cookies = authenticate('<your-username-or-email>', '<your-password>')
Query().get_scanner_data(cookies=cookies)
```
</details>
## 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:
```python
{
'markets': ['america'],
'symbols': {'query': {'types': []}, 'tickers': []},
Expand All @@ -153,7 +252,5 @@ For example, the previous query creates the following dictionary:
}
```
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.
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.

0 comments on commit d3da754

Please sign in to comment.