Skip to main content

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:

  1. Open your web browser and go to TradingView.
  2. Log in to your account.
  3. Open Developer Tools: press F12 (Windows) or Cmd + Option + I (Mac), or right-click and select Inspect.
  4. Navigate to the Application (or Storage) tab.
  5. On the left panel, expand Cookies and select https://www.tradingview.com.
  6. Locate the following two keys in the table and copy their values:
    • sessionid (This is your sessionid / token value)
    • sessionid_sign (This is your signature value)
  7. Pass them into the Client constructor.

[!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.0
  • websocket-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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tradingview_api_python-1.0.0.tar.gz (28.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tradingview_api_python-1.0.0-py3-none-any.whl (27.1 kB view details)

Uploaded Python 3

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

Hashes for tradingview_api_python-1.0.0.tar.gz
Algorithm Hash digest
SHA256 50c6233f4b42e73326e8f533fa9d6112266dc8a07ae6029eb94ae9cda70ab218
MD5 7e470e14bc02b5d608895a3c37c7461b
BLAKE2b-256 e9153cdd2b61b439b9075e202068b9c8be66501b74ee1ae1977178c1ae942cb0

See more details on using hashes here.

File details

Details for the file tradingview_api_python-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for tradingview_api_python-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 79bdc77a8dded6dc27ea49e35d52906e6a4b0784a6a3277057a3963e1aec13a0
MD5 a5b7ea23003bd4ee9d8795bd35607de2
BLAKE2b-256 3dceae9d8784c78e4db1a9747177690a0678586983e528eed9e04f3335b62245

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page