A comprehensive TypeScript/JavaScript client for TradingView's real-time WebSocket API and screener functionality. This library provides easy access to TradingView's live market data, charting capabilities, and powerful stock screening tools.
- 🚀 Real-time WebSocket Connection - Live market data streaming
- 📈 Chart Data Access - Historical and real-time price data
- 📊 Technical Indicators - Built-in support for popular indicators
- 🔍 Financial Data & Quotes - Comprehensive financial reports and metrics
- 🔍 Advanced Screener - Comprehensive stock screening capabilities
- 🌐 Cross-Platform - Works in browsers, Node.js, Bun, and Deno
- 📝 TypeScript Support - Full type definitions included
- 🎯 Simple API - Easy-to-use interface with Promise-based operations
# Using npm npm install @ch99q/twc # Using yarn yarn add @ch99q/twc # Using pnpm pnpm add @ch99q/twc # Using bun bun add @ch99q/twc
For Node.js/Bun environments, you'll also need the ws package:
npm install ws @types/ws
import { createSession, createChart, createSeries } from "@ch99q/twc"; // Create a session const session = await createSession(); // Create a chart const chart = await createChart(session); // Resolve a symbol const symbol = await chart.resolve("AAPL", "NASDAQ"); // Create a series for daily data const series = await createSeries(session, chart, symbol, "1D", 100); // Access historical data console.log("Latest price:", series.history[series.history.length - 1]); // Stream real-time updates for await (const update of series.stream()) { console.log("Price update:", update); } // Cleanup await series.close(); await session.close();
import { createScreener } from "@ch99q/twc"; // Create a screener for US markets const screener = createScreener("america") .select("name", "close", "change", "volume", "market_cap_basic") .where("market_cap_basic").gt(1000000000) // Market cap > 1ドルB .where("volume").gt(1000000) // Volume > 1M .where("change").gt(0) // Positive change .orderBy("volume", "desc") .limit(50); // Execute the screen const results = await screener.execute(); console.log(`Found ${results.totalCount} stocks`); results.data.forEach(stock => { console.log(`${stock.name}: $${stock.close} (${stock.change}%)`); });
import { rsiStudy, macdStudy } from "@ch99q/twc/studies"; // Add RSI indicator const rsi = await rsiStudy(session, chart, series, 14); // Add MACD indicator const macd = await macdStudy(session, chart, series, 12, 26, "close", 9); // Access indicator values console.log("Current RSI:", rsi.history[rsi.history.length - 1]); console.log("Current MACD:", macd.history[macd.history.length - 1]);
import { createQuote } from "@ch99q/twc"; // Get comprehensive financial data for a stock const quote = await createQuote(session, "AAPL", "NASDAQ"); console.log(`Financial data for ${quote.symbol}:`); console.log(`Total reports: ${quote.reports.length}`); // Filter by report type const annualReports = quote.reports.filter(r => r.type === "annual"); const quarterlyReports = quote.reports.filter(r => r.type === "quarterly"); // Access latest annual report const latestAnnual = annualReports[annualReports.length - 1]; console.log("Latest annual report:", { date: latestAnnual.date, revenue: latestAnnual.total_revenue, netIncome: latestAnnual.net_income, totalAssets: latestAnnual.total_assets, totalEquity: latestAnnual.total_equity, eps: latestAnnual.basic_eps }); // Access latest quarterly report const latestQuarterly = quarterlyReports[quarterlyReports.length - 1]; console.log("Latest quarterly report:", { date: latestQuarterly.date, revenue: latestQuarterly.total_revenue, netIncome: latestQuarterly.net_income });
Creates a new WebSocket session to TradingView.
token(optional): Pro subscription token for premium dataverbose(optional): Enable verbose logging- Returns:
Promise<Session>
// Free data const session = await createSession(); // Premium data (requires TradingView Pro) const session = await createSession("your-pro-token");
Creates a new chart instance for symbol resolution and data access.
const chart = await createChart(session);
Resolves symbol information from the exchange.
const symbol = await chart.resolve("AAPL", "NASDAQ"); console.log(symbol.description); // "Apple Inc"
Creates a data series for historical and real-time price data.
timeframe: "1", "5", "15", "30", "60", "240", "1D", "1W", "1M"count: Number of bars to fetchrange(optional): Time range or custom range
// Last 100 daily bars const series = await createSeries(session, chart, symbol, "1D", 100); // Specific date range const series = await createSeries( session, chart, symbol, "1H", 0, [1640995200, 1672531200] // Unix timestamps ); // Predefined ranges const series = await createSeries(session, chart, symbol, "1D", 0, "YTD");
Study functions create and attach technical indicators to a series. All study functions follow the pattern: studyName(session, chart, series, ...parameters).
import { rsiStudy, smaStudy, emaStudy, macdStudy, bollingerBandsStudy } from "@ch99q/twc/studies"; // Moving averages const sma20 = await smaStudy(session, chart, series, 20); const ema50 = await emaStudy(session, chart, series, 50); // Oscillators const rsi = await rsiStudy(session, chart, series, 14); const macd = await macdStudy(session, chart, series, 12, 26, "close", 9); // Bands const bb = await bollingerBandsStudy(session, chart, series, 20, "close", 2.0);
Retrieves comprehensive financial data and reports for a symbol.
symbol: Stock symbol (e.g., "AAPL", "MSFT")exchange: Exchange name (e.g., "NASDAQ", "NYSE")- Returns:
Promise<Quote>
const quote = await createQuote(session, "AAPL", "NASDAQ"); // Quote structure interface Quote { id: string; // Unique quote identifier symbol: string; // Stock symbol exchange: string; // Exchange name reports: Report[]; // Array of financial reports } // Report structure interface Report { type: "annual" | "quarterly"; // Report period type date: string; // Report date symbol: string; // Stock symbol // Income Statement total_revenue: number; // Total revenue net_income: number; // Net income basic_eps: number; // Basic earnings per share diluted_eps: number; // Diluted earnings per share // Balance Sheet total_assets: number; // Total assets total_equity: number; // Total shareholders' equity total_debt: number; // Total debt cash_n_short_term_investments: number; // Cash and equivalents // Cash Flow cash_f_operating_activities: number; // Operating cash flow cash_f_investing_activities: number; // Investing cash flow cash_f_financing_activities: number; // Financing cash flow capital_expenditures: number; // Capital expenditures // Key Ratios (calculated fields) asset_turnover: number; // Asset turnover ratio book_value_per_share: number; // Book value per share debt_to_equity_ratio_fq: number; // Debt-to-equity ratio return_on_assets_fq: number; // Return on assets return_on_equity_fq: number; // Return on equity // And 200+ other financial fields... }
Available Financial Fields:
The quote reports include comprehensive financial data with 200+ fields:
Income Statement: total_revenue, gross_profit, operating_income, net_income, basic_eps, diluted_eps
Balance Sheet: total_assets, total_equity, total_debt, cash_n_short_term_investments, accounts_receivables_net
Cash Flow: cash_f_operating_activities, cash_f_investing_activities, capital_expenditures, free_cash_flow
Per Share Metrics: book_value_per_share, tangible_book_value_per_share, cash_per_share, revenue_per_share
Financial Ratios: debt_to_equity_ratio_fq, current_ratio_fq, return_on_assets_fq, return_on_equity_fq
Profitability: gross_margin, operating_margin, profit_margin, ebitda_margin
See the complete field definitions in client.quote.ts.
Creates a new screener instance for the specified markets.
Available Markets:
america, argentina, australia, austria, bahrain, bangladesh, belgium, brazil, canada, chile, china, colombia, croatia, cyprus, czech, denmark, egypt, estonia, finland, france, germany, greece, hongkong, hungary, iceland, india, indonesia, ireland, israel, italy, japan, jordan, kenya, korea, kuwait, latvia, lebanon, lithuania, luxembourg, malaysia, mexico, morocco, netherlands, newzealand, norway, pakistan, peru, philippines, poland, portugal, qatar, romania, russia, saudiarabia, serbia, singapore, slovakia, slovenia, southafrica, spain, srilanka, sweden, switzerland, taiwan, thailand, turkey, uae, uk, ukraine, vietnam
const screener = createScreener("america", "europe") // Select columns to return .select("name", "close", "change", "volume") // Add filters .where("market_cap_basic").gte(1000000000) .where("volume").between(100000, 50000000) .where("sector").in(["Technology", "Healthcare"]) // Combine filters with AND/OR .and(builder => builder.where("price_earnings_ttm").lt(20) .where("debt_to_equity_fq").lt(0.5) ) // Sort results .orderBy("market_cap_basic", "desc") // Limit results .limit(100) // Execute the screen .execute();
Filter Operations:
eq(value)- Equal tone(value)- Not equal togt(value)- Greater thangte(value)- Greater than or equallt(value)- Less thanlte(value)- Less than or equalbetween(min, max)- Between valuesin(array)- In array of valuesmatch(pattern)- Matches patterncrosses(value)- Crosses valueabove(value)- Above valuebelow(value)- Below value
Available Fields:
The screener supports 200+ fields including:
Basic Info: name, exchange, sector, industry, country, currency
Price Data: close, open, high, low, volume, change, change_abs
Market Data: market_cap_basic, shares_outstanding_calc, enterprise_value_calc
Financial Ratios: price_earnings_ttm, price_book_fq, debt_to_equity_fq, current_ratio_fq
Performance: Perf.1D, Perf.W, Perf.1M, Perf.3M, Perf.YTD, Perf.Y
Technical: RSI, MACD.macd, SMA20, EMA50, BB.upper, BB.lower
Dividends: dividend_yield_recent, dividend_payout_ratio_ttm
See the full list in the type definitions.
import { createSession, createChart, createSeries } from "@ch99q/twc"; const session = await createSession(); const chart = await createChart(session); const symbol = await chart.resolve("BTCUSD", "BINANCE"); // Create multiple timeframes const daily = await createSeries(session, chart, symbol, "1D", 100); const hourly = await createSeries(session, chart, symbol, "1H", 200); const minute = await createSeries(session, chart, symbol, "1", 500); console.log("Daily trend:", daily.history.slice(-5)); console.log("Hourly trend:", hourly.history.slice(-10)); console.log("Recent prices:", minute.history.slice(-20));
import { createSession, createQuote } from "@ch99q/twc"; async function analyzeCompany(symbol: string, exchange: string) { const session = await createSession(); try { const quote = await createQuote(session, symbol, exchange); // Get latest annual and quarterly reports const annualReports = quote.reports.filter(r => r.type === "annual"); const quarterlyReports = quote.reports.filter(r => r.type === "quarterly"); const latestAnnual = annualReports[annualReports.length - 1]; const latestQuarterly = quarterlyReports[quarterlyReports.length - 1]; // Financial health metrics const analysis = { company: symbol, // Revenue & Growth annualRevenue: latestAnnual.total_revenue, quarterlyRevenue: latestQuarterly.total_revenue, revenueGrowth: ((latestQuarterly.total_revenue / quarterlyReports[quarterlyReports.length - 5]?.total_revenue - 1) * 100).toFixed(1), // Profitability netIncome: latestAnnual.net_income, profitMargin: ((latestAnnual.net_income / latestAnnual.total_revenue) * 100).toFixed(1), eps: latestAnnual.basic_eps, // Financial Position totalAssets: latestAnnual.total_assets, totalDebt: latestAnnual.total_debt, totalEquity: latestAnnual.total_equity, debtToEquity: (latestAnnual.total_debt / latestAnnual.total_equity).toFixed(2), // Returns roe: (latestAnnual.return_on_equity_fq * 100).toFixed(1), roa: (latestAnnual.return_on_assets_fq * 100).toFixed(1), // Cash Flow operatingCashFlow: latestAnnual.cash_f_operating_activities, freeCashFlow: latestAnnual.free_cash_flow, capex: latestAnnual.capital_expenditures, }; console.log(`Financial Analysis for ${symbol}:`, analysis); // Investment signals const signals = []; if (parseFloat(analysis.revenueGrowth) > 15) signals.push("Strong revenue growth"); if (parseFloat(analysis.profitMargin) > 20) signals.push("High profit margin"); if (parseFloat(analysis.debtToEquity) < 0.3) signals.push("Low debt burden"); if (parseFloat(analysis.roe) > 15) signals.push("Strong ROE"); if (analysis.freeCashFlow > 0) signals.push("Positive free cash flow"); console.log("Investment Signals:", signals); } finally { await session.close(); } } // Analyze multiple companies await Promise.all([ analyzeCompany("AAPL", "NASDAQ"), analyzeCompany("MSFT", "NASDAQ"), analyzeCompany("GOOGL", "NASDAQ") ]);
import { createScreener } from "@ch99q/twc"; // Find growth stocks with strong fundamentals const growthScreener = createScreener("america") .select( "name", "sector", "close", "market_cap_basic", "price_earnings_ttm", "revenue_growth_ttm_yoy", "earnings_growth_ttm_yoy", "debt_to_equity_fq" ) .where("market_cap_basic").between(1e9, 100e9) // 1ドルB - 100ドルB .where("revenue_growth_ttm_yoy").gt(0.15) // 15%+ revenue growth .where("earnings_growth_ttm_yoy").gt(0.20) // 20%+ earnings growth .where("price_earnings_ttm").between(10, 30) // Reasonable P/E .where("debt_to_equity_fq").lt(0.4) // Low debt .orderBy("revenue_growth_ttm_yoy", "desc") .limit(25); const results = await growthScreener.execute(); // Find dividend aristocrats const dividendScreener = createScreener("america") .select( "name", "sector", "dividend_yield_recent", "dividend_payout_ratio_ttm", "dividend_growth_5y" ) .where("dividend_yield_recent").between(0.02, 0.08) // 2-8% yield .where("dividend_payout_ratio_ttm").lt(0.7) // Sustainable payout .where("dividend_growth_5y").gt(0.05) // Growing dividends .orderBy("dividend_yield_recent", "desc"); const dividendStocks = await dividendScreener.execute();
import { createSession, createChart, createSeries } from "@ch99q/twc"; import { rsiStudy, macdStudy } from "@ch99q/twc/studies"; async function monitorStock(symbol: string, exchange: string) { const session = await createSession(); const chart = await createChart(session); const resolvedSymbol = await chart.resolve(symbol, exchange); // Create 1-minute series const series = await createSeries(session, chart, resolvedSymbol, "1", 100); // Add indicators const rsi = await rsiStudy(session, chart, series, 14); const macd = await macdStudy(session, chart, series, 12, 26, "close", 9); console.log(`Monitoring ${symbol}...`); // Stream updates for await (const update of series.stream()) { const [timestamp, open, high, low, close, volume] = update; const currentRSI = rsi.history[rsi.history.length - 1]; const currentMACD = macd.history[macd.history.length - 1]; console.log({ time: new Date(timestamp * 1000), price: close, volume, rsi: currentRSI?.[1], macd: currentMACD?.[1] }); // Alert conditions if (currentRSI?.[1] > 70) { console.log("🔴 OVERBOUGHT: RSI > 70"); } else if (currentRSI?.[1] < 30) { console.log("🟢 OVERSOLD: RSI < 30"); } } } // Monitor Apple stock await monitorStock("AAPL", "NASDAQ");
The library includes comprehensive error handling with specific error types:
import { ProtocolError, CriticalError, SymbolError, SeriesError, StudyError } from "@ch99q/twc"; try { const session = await createSession(); // ... your code } catch (error) { if (error instanceof ProtocolError) { console.error("Protocol error:", error.message); } else if (error instanceof SymbolError) { console.error("Symbol error:", error.symbolId, error.message); } else if (error instanceof SeriesError) { console.error("Series error:", error.seriesId, error.message); } else { console.error("Unknown error:", error); } }
- Connection Limits: Limit concurrent connections (recommended: 1-3 per application)
- Symbol Limits: Avoid subscribing to too many symbols simultaneously
- Reconnection: Implement exponential backoff for reconnections
- Memory Management: Always call
.close()on series, studies, and sessions - Error Handling: Implement proper error handling for production use
// Good: Proper resource management async function handleData() { const session = await createSession(); try { // ... use session } finally { await session.close(); // Always cleanup } } // Good: Limit concurrent subscriptions const maxSymbols = 10; const symbols = ["AAPL", "GOOGL", "MSFT", /* ... */].slice(0, maxSymbols);
- Browser: Chrome, Firefox, Safari, Edge (latest versions)
- Node.js: 18.0.0+ (requires
wspackage) - Bun: Latest version (requires
wspackage) - Deno: Latest version (built-in WebSocket support)
We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.
This library is not officially affiliated with TradingView. Use at your own risk. The library is provided "as is" without warranty. Always verify data independently for trading decisions.
Made with ❤️ for the trading community