π Real-time market data from TradingView via WebSocket β typed, composable, and ergonomic.
import { tv } from 'tradingview-api-adapter'
const client = tv()
const btc = client.symbol('BINANCE:BTCUSDT')
console.log(await btc.price()) // β 72183.99
btc.stream().on('price', ({ price }) => {
console.log('BTC:', price)
})
await client.disconnect()- β
Real-time quotes β typed
lp,bid,ask,ch,chp,volume, and 50+ other fields - β Historical candles β OHLCV bars at any TradingView timeframe (1m β 1M)
- β
Symbol metadata β full
SymbolInfo(description, exchange, session hours, β¦) via one.info()call - β
Multi-symbol streams β
Portfoliofor ad-hoc collections,Groupfor named, mutable ones - β Auto-reconnect β exponential backoff + jitter, automatic session replay
- β
Full TypeScript types β
QuoteSnapshot<['lp', 'bid']>gives you{ lp?: number | null; bid?: number | null } - β
Async iterator β
for await (const tick of stream) { ... } - β
Explicit resource management β
using client = tv()auto-disconnects - β
Node + Browser β dynamic
wsimport so browser bundles don't carry Node-only code - β
Proxy + auth β HTTP/SOCKS proxy agent,
sessionid/authTokenfor premium access - β Battle-tested β 227+ unit tests, integration against a mock WebSocket server, live e2e
npm install tradingview-api-adapterRequires Node.js β₯ 20. See browser guide for client-side usage.
import { tv } from 'tradingview-api-adapter'
const client = tv()
const btc = client.symbol('BINANCE:BTCUSDT')
const price = await btc.price()
console.log(`BTC: $${price}`)
await client.disconnect()const stream = btc.stream(['lp', 'bid', 'ask', 'ch', 'chp'] as const)
stream.on('price', ({ price }) => console.log(price))
stream.on('change', ({ value, percent }) => console.log(`${value} (${percent}%)`))
// Or use async iteration:
for await (const { data } of stream) {
console.log(data.lp, data.bid, data.ask)
if (someCondition) break // β automatically closes the stream
}const candles = await btc.candles({ timeframe: '1h', count: 100 })
// β Candle[] with { time, open, high, low, close, volume }const portfolio = client.symbols([
'BINANCE:BTCUSDT',
'BINANCE:ETHUSDT',
'NASDAQ:AAPL',
])
const prices = await portfolio.prices()
// β { 'BINANCE:BTCUSDT': 72183, 'BINANCE:ETHUSDT': 2200, 'NASDAQ:AAPL': 260 }
portfolio.stream().on('price', ({ symbol, price }) => {
console.log(`${symbol}: $${price}`)
})const crypto = client.createGroup('crypto', ['BINANCE:BTCUSDT', 'BINANCE:ETHUSDT'])
const stream = crypto.stream()
stream.on('price', ({ symbol, price }) => console.log(symbol, price))
// Add a pair β active streams pick it up automatically
crypto.add('BINANCE:SOLUSDT')
// Remove a pair β active streams stop emitting for it
crypto.remove('BINANCE:ETHUSDT')
// List all registered groups on the client
console.log(client.groups.list) // β ['crypto']const info = await btc.info()
console.log(info.description) // β 'Bitcoin / TetherUS'
console.log(info.exchange) // β 'Binance'
console.log(info.currencyCode) // β 'USDT'
console.log(info.isTradable) // β true- Getting Started β installation, first requests, cleanup
- API Reference β
Client,TvSymbol,Stream,Group, types - Guides β streaming best practices, candles, groups, reconnect, browser, proxy, auth
- Migration from 1.x β before/after for every 1.x method
- Contributing β development workflow, conventions,
.jsextension rationale - Changelog
The examples/ directory contains 12 runnable demos:
| # | File | What it shows |
|---|---|---|
| 01 | 01-single-price.ts |
Minimal one-shot price fetch |
| 02 | 02-streaming.ts |
Single-symbol stream with price, change events |
| 03 | 03-multi-symbol.ts |
Ad-hoc Portfolio |
| 04 | 04-groups.ts |
Named Group with live add/remove |
| 05 | 05-candles-history.ts |
Historical OHLCV bars |
| 06 | 06-candles-streaming.ts |
Live bar ticks (via internal ChartSession) |
| 07 | 07-symbol-info.ts |
Full symbol metadata |
| 08 | 08-async-iterator.ts |
for await over a stream |
| 09 | 09-reconnect-resilience.ts |
Automatic reconnect with backoff |
| 10 | 10-browser.html |
Vanilla HTML page via esm.sh CDN |
| 11 | 11-proxy-node.ts |
HTTP/SOCKS proxy through an agent |
| 12 | 12-auth-session.ts |
Authenticated access with TradingView cookies |
Run any of them with npx tsx examples/NN-*.ts. Enable verbose logging via
DEBUG=tradingview-adapter:* npx tsx examples/NN-*.ts.
This library is a full rewrite of 1.x. The redesign prioritised:
- Typed over stringly-typed.
QuoteSnapshot<['lp', 'bid']>is{ lp?: number | null; bid?: number | null }, notRecord<string, any>. - Composable over monolithic.
TransportβProtocolβSessionManagerβ public API are independently testable and swappable. - One socket, many sessions. A single WebSocket connection multiplexes every quote and chart subscription through a shared
SessionManager. - Pooled symbols.
client.symbol('BTC')always returns the same instance, so overlapping groups dedupe automatically. - No hidden state. Every resource (symbol, stream, group) has an explicit lifecycle.
- Browser-safe by construction.
wsis loaded through dynamicimport()so browser bundlers can drop it.
MIT Β© Gerasimenko Oleg