Python port of TradingView real-time stock/crypto WebSocket API and Indicators scraper.
Project description
TradingView API Python
Get realtime market prices, quote ticks, drawing elements, backtest results, and indicator values from Tradingview in Python!
This is a 100% complete Python port of the popular Node.js library TradingView-API. It covers all WebSocket messages, HTTP REST methods, session structures, and custom packet framing logic in Python.
🟢 Features & Mapped Coverage
Our Python library implements 100% of the features contained in the original Node.js version, wrapped with Pythonic improvements like callback decorators:
- Real-time Chart Data: Stream live price bar updates (OHLCV) on any timeframe.
- Technical Indicators: Stream outputs of standard and custom community Pine Script indicators (e.g. Nadaraya-Watson).
- Strategy Backtesting: Extract full backtest strategy reports (trades log, cumulative profit, performance metrics, Sharpe ratio).
- Quotes & Tickers: Subscribe to ask, bid, volume, and sector/industry metrics.
- Drawings Scraper: Retrieve drawing lines, boxes, labels, and polygons you made on your chart layout.
- Private & Invite-Only Indicators: Read/manage invite-only indicator lists and access them.
- Timeframe Replay: Control replay mode step-by-step or automatically.
- Lightweight & Thread-Safe: Handles the WebSocket loop in a background daemon thread with safe automatic heartbeat ping-pong framing.
🔑 How to Get sessionid and sessionid_sign (Signature)
To access intraday charts, private indicators, or to override general API rate limits, the library needs to authenticate using your active TradingView browser session cookies: sessionid and sessionid_sign (signature).
Why are these credentials needed?
- Intraday Timeframes: Free connections are restricted to daily/weekly/monthly charts. Paid accounts require session tokens to access 1-minute, 5-minute, or 1-hour feeds.
- Custom/Private Indicators: Bypasses limits and resolves invite-only Pine Scripts.
- Cloudflare & CAPTCHA Bypass: Prevents connection blocks by establishing a logged-in socket session.
Steps to retrieve cookies:
- Open your web browser and go to TradingView.
- Log in to your account.
- Open Developer Tools: press F12 (Windows) or Cmd + Option + I (Mac), or right-click and select Inspect.
- Navigate to the Application (or Storage) tab.
- On the left panel, expand Cookies and select
https://www.tradingview.com. - Locate the following two keys in the table and copy their values:
sessionid(This is yoursessionid/ token value)sessionid_sign(This is yoursignaturevalue)
- Pass them into the
Clientconstructor.
[!WARNING] Keep these credentials private as they allow access to your TradingView account. If you click Log Out on the TradingView website, these tokens immediately expire, and you will need to retrieve new ones. Closing the browser tab does not invalidate them.
Installation
Install the package directly from PyPI:
pip install tradingview-api-python
Or install it from the local source directory:
pip install .
Dependencies
requests>=2.32.0websocket-client>=1.8.0
🚀 Scenario Code Examples
1. Real-time Prices (Chart Session)
Create a daily chart session and update on each new candle tick:
import time
from tradingviewApiPython import Client
client = Client() # Public connection
chart = client.Session.Chart()
chart.set_market('BINANCE:BTCEUR', {
'timeframe': 'D',
'range': 100
})
@chart.on_symbol_loaded
def on_loaded():
print(f"Market \"{chart.infos['description']}\" resolved!")
@chart.on_update
def on_update(changes):
if chart.periods:
last_bar = chart.periods[0]
print(f"Last candle close: {last_bar['close']} | Open: {last_bar['open']}")
time.sleep(10)
chart.delete()
client.end()
2. Fetch Exactly 100 Bars (Historical Pull & Exit)
Connects to the feed, waits until 100 historical periods are loaded, extracts them, and exits immediately. This is useful for building data downloaders:
import time
from tradingviewApiPython import Client
client = Client()
chart = client.Session.Chart()
state = {'completed': False}
# Set range to 100 and symbol
chart.set_market('BINANCE:BTCUSDT', {
'timeframe': 'D',
'range': 100
})
@chart.on_update
def on_update(changes):
# Wait until we have at least 100 bars loaded
if len(chart.periods) >= 100 and not state['completed']:
state['completed'] = True
# Slice exactly the last 100 bars
data = chart.periods[:100]
print(f"Successfully fetched {len(data)} bars!")
for idx, bar in enumerate(data[:3]):
print(f"Bar {idx}: Timestamp {bar['time']} | Close: {bar['close']}")
chart.delete()
client.end()
# Bounded wait loop
timeout = 10
start_time = time.time()
while not state['completed'] and (time.time() - start_time) < timeout:
time.sleep(0.1)
3. Extract and Align Prices + Indicators into a Pandas DataFrame
This scenario fetches price candle data and combines it with custom indicator values (e.g., Nadaraya-Watson) to build a unified Pandas DataFrame for ML/Deep Learning training features:
import time
import pandas as pd
from tradingviewApiPython import Client, get_indicator
# Session credentials (optional but recommended for custom indicators)
client = Client(token="sessionid", signature="sessionid_sign")
chart = client.Session.Chart()
chart.set_market('BINANCE:ETHUSDT', {'timeframe': 'D', 'range': 100})
state = {'completed': False}
@chart.on_symbol_loaded
def loaded():
# Load Nadaraya-Watson indicator details by public ID
indicator = get_indicator('PUB;c2a817e7470b41c2bed3d9fe8ed1a18a', '1')
study = chart.Study(indicator)
@study.on_ready
def ready():
print("Indicator is loaded and ready!")
@study.on_update
def update(changes):
# Once both candles and indicator periods are loaded
if len(chart.periods) >= 100 and len(study.periods) >= 100 and not state['completed']:
state['completed'] = True
# Map indicator values by their timestamp
ind_map = {p['$time']: p for p in study.periods}
rows = []
for bar in chart.periods:
t = bar['time']
ind_val = ind_map.get(t, {})
rows.append({
'timestamp': pd.to_datetime(t, unit='s'),
'open': bar['open'],
'high': bar['max'],
'low': bar['min'],
'close': bar['close'],
'volume': bar['volume'],
# Map indicator plot outputs (Nadaraya-Watson upper/lower envelopes)
'nw_upper': ind_val.get('Plot_0'),
'nw_lower': ind_val.get('Plot_1')
})
df = pd.DataFrame(rows).sort_values('timestamp').reset_index(drop=True)
print("\nAligned Pandas DataFrame:")
print(df.tail(5))
chart.delete()
client.end()
timeout = 15
start_time = time.time()
while not state['completed'] and (time.time() - start_time) < timeout:
time.sleep(0.1)
4. Sequential Batch Fetcher for Multiple Timeframes
Iterate through multiple symbols and timeframes sequentially to download historical price datasets:
import time
import os
import json
from tradingviewApiPython import Client
symbols = ['BIST:XU100', 'NASDAQ:NDX', 'TVC:GOLD']
timeframes = ['D', '1H']
client = Client()
def fetch_symbol(symbol, timeframe):
chart = client.Session.Chart()
chart.set_market(symbol, {
'timeframe': timeframe,
'range': 200
})
state = {'saved': False}
@chart.on_update
def on_update(changes):
if len(chart.periods) >= 200 and not state['saved']:
state['saved'] = True
data = chart.periods
file_name = f"{symbol.replace(':', '_')}_{timeframe}.json"
with open(file_name, 'w') as f:
json.dump(data, f, indent=2)
print(f"Saved {file_name} ({len(data)} periods)")
chart.delete()
# Block until saved or timeout (10 seconds)
start_time = time.time()
while not state['saved'] and (time.time() - start_time) < 10:
time.sleep(0.1)
if not state['saved']:
print(f"Timeout/Error fetching {symbol} {timeframe}")
chart.delete()
for s in symbols:
for tf in timeframes:
fetch_symbol(s, tf)
client.end()
5. Multi-Timeframe Technical Analysis Scanner (REST)
Fetch overall TradingView Technical Analysis recommendations (Strong Buy, Buy, Sell, etc.) across multiple periods:
from tradingviewApiPython import get_ta
# Fetch recommendations for BIST100
ta_advices = get_ta('BIST:XU100')
if ta_advices:
for timeframe, recommendations in ta_advices.items():
print(f"\nTimeframe: {timeframe}")
print(f" - Summary: {recommendations.get('All')}")
print(f" - Moving Averages: {recommendations.get('MA')}")
print(f" - Oscillators: {recommendations.get('Other')}")
6. Retrieve Private Indicators Saved in Your Account
Query and load custom indicators saved under your private TradingView account:
import time
from tradingviewApiPython import Client, get_private_indicators
SESSION_ID = "your_sessionid_cookie"
SIGNATURE = "your_sessionid_sign"
client = Client(token=SESSION_ID, signature=SIGNATURE)
# Retrieve list of saved private indicators
saved_indicators = get_private_indicators(SESSION_ID, SIGNATURE)
print("Found Private Indicators:")
for ind in saved_indicators:
print(f" - Name: {ind['name']} | ID: {ind['id']}")
if saved_indicators:
chart = client.Session.Chart()
chart.set_market('BINANCE:BTCUSDT', {'timeframe': 'D'})
@chart.on_symbol_loaded
def loaded():
# Compile and load the first private indicator
target_indicator = saved_indicators[0]['get']()
study = chart.Study(target_indicator)
@study.on_update
def on_update(changes):
print("Private indicator values:", study.periods[0])
time.sleep(10)
chart.delete()
client.end()
7. Manage Access Permissions for Invite-Only Indicators
If you publish invite-only indicators, manage who can access them using your session cookies:
from datetime import datetime, timedelta
from tradingviewApiPython import PinePermManager
SESSION_ID = "your_sessionid_cookie"
SIGNATURE = "your_sessionid_sign"
PINE_SCRIPT_ID = "PUB;XXXXXXXXXXXXXXXXXXXXX"
perm_manager = PinePermManager(SESSION_ID, SIGNATURE, PINE_SCRIPT_ID)
# 1. Add username to authorized list for 30 days
expire_date = datetime.now() + timedelta(days=30)
status = perm_manager.add_user("test_trader_username", expiration=expire_date)
print("User authorized:", status)
# 2. Get list of all currently authorized users
users = perm_manager.get_users(limit=10)
for u in users:
print(f"User: {u['username']} | Expiration: {u.get('expiration')}")
# 3. Remove user access
remove_status = perm_manager.remove_user("test_trader_username")
print("User access revoked:", remove_status)
8. Interactive Replay Mode
Fetch candle history and manually step forward bar by bar:
import time
from tradingviewApiPython import Client
client = Client()
chart = client.Session.Chart()
# Enable replay starting from a timestamp (milliseconds)
chart.set_market('BINANCE:BTCUSDT', {
'timeframe': 'D',
'replay': 1672531200000 # Jan 1st 2023 00:00:00 UTC
})
@chart.on_replay_loaded
def replay_loaded(instance_id):
print("Replay session loaded!")
# Step forward 1 bar (returns when the websocket has completed calculations)
chart.replay_step(1)
print("Close after Step 1:", chart.periods[0]['close'])
chart.replay_step(1)
print("Close after Step 2:", chart.periods[0]['close'])
time.sleep(10)
chart.delete()
client.end()
💬 Issue & Bug Reports
If you run into console warnings or unexpected results, please open an issue in the GitHub repository. Contributions and suggestions are always welcome!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tradingview_api_python-1.0.0.tar.gz.
File metadata
- Download URL: tradingview_api_python-1.0.0.tar.gz
- Upload date:
- Size: 28.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50c6233f4b42e73326e8f533fa9d6112266dc8a07ae6029eb94ae9cda70ab218
|
|
| MD5 |
7e470e14bc02b5d608895a3c37c7461b
|
|
| BLAKE2b-256 |
e9153cdd2b61b439b9075e202068b9c8be66501b74ee1ae1977178c1ae942cb0
|
File details
Details for the file tradingview_api_python-1.0.0-py3-none-any.whl.
File metadata
- Download URL: tradingview_api_python-1.0.0-py3-none-any.whl
- Upload date:
- Size: 27.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79bdc77a8dded6dc27ea49e35d52906e6a4b0784a6a3277057a3963e1aec13a0
|
|
| MD5 |
a5b7ea23003bd4ee9d8795bd35607de2
|
|
| BLAKE2b-256 |
3dceae9d8784c78e4db1a9747177690a0678586983e528eed9e04f3335b62245
|