How to Use the TradingView API for Custom Financial Charts
The TradingView API is a JavaScript library for embedding interactive financial charts into any web application. I've used it to build real-time dashboards tracking AAPL, TSLA, and SPY across multiple timeframes, and the flexibility is unmatched. No other charting tool gives you this level of control over both the visual rendering and the data pipeline beneath it.
You get candlestick charts, dozens of technical indicators, drawing tools, and a datafeed system that hooks into your backend. Whether you're building a trading dashboard or adding a single chart to a landing page, the API handles the heavy lifting.
Understanding the TradingView API
The Charting Library is the core of the TradingView API. It manages the full chart interface — appearance, tools, user interactions — while the Datafeed component handles all market data. You write custom code for the datafeed that fetches historical bars, real-time prices, and symbol information from your server.
The library ships with TypeScript interfaces, which catches type errors before they hit production. I prefer working with TypeScript here because the API surface is large, and a misplaced parameter can break the entire chart render.
| Component | What It Does |
|---|---|
| Charting Library | Manages the entire chart interface — the look, the tools, and how users interact with it. |
| Datafeed | Handles all the data. This is your custom code that fetches real-time prices, historical data, and symbol information from your server. |
Many developers start with the Advanced Charts widget, which offers ready-made charts with customizable themes, layouts, and controls.
Getting access takes a few days. You fill out a form on TradingView's website and wait for approval. Once granted, you receive the charting_library and datafeeds folders. These are the essential files you place in your project, whether you use React, Vue, or plain JavaScript. In my experience, the approval process took about a week, so plan for that delay.
Getting Started: Setup and First Chart
Create a project folder and drop the charting_library and datafeeds folders into your public or src directory. If you're using React, you might need a bundler like webpack, but the library itself works with any framework that supports ES6+.
Here's a minimal setup to render a daily chart for Apple:
const widget = new TradingView.widget({
symbol: 'AAPL',
interval: 'D',
container_id: 'chart',
datafeed: new Datafeeds.UDFCompatibleDatafeed('https://your-datafeed-url'),
library_path: '/charting_library/',
theme: 'light'
});
This creates a daily chart for AAPL and looks for a <div id="chart"> on your page. The datafeed URL is the part most people get wrong — you need to swap the example URL with your own backend endpoint that returns real market data. I've seen projects stall here for days because they assumed the demo feed would work in production.
When you're testing locally, use a simple HTTP server (VS Code's Live Server works well) to avoid CORS errors. Opening the HTML file directly in your browser triggers cross-origin issues that take longer to debug than setting up a server.
If you prefer building custom indicators visually rather than writing Pine Script from scratch, the Pineify visual editor lets you generate code without programming knowledge. I haven't tested every indicator generator on the market, but this one handles the complex ones I throw at it.
Two things that trip up most beginners:
- HTTPS is mandatory. TradingView requires a secure connection for all features. If your dev server uses HTTP, expect silent failures.
- Broker integration needs testing. If you're connecting to Interactive Brokers, start with their paper trading port (7497). Test dummy trades before live capital.
Building Your Custom Datafeed
The Datafeed module is the bridge between your chart and market data. You implement the IDatafeedChartApi interface to handle symbol searches, historical bars, and live data streams.
Start by creating a datafeed class extending UDFCompatibleDatafeed. This follows TradingView's Universal Data Feed protocol, so most compatibility work is done for you.
The getBars method fetches historical candlestick data:
async getBars(ohlc, resolution, periodParams, onHistoryCallback, onErrorCallback) {
const data = await fetch(`/api/bars?symbol=${ohlc.symbol}&resolution=${resolution}`);
const bars = await data.json();
onHistoryCallback(bars, { noData: bars.length === 0 });
}
This calls your backend, parses the JSON response, and hands it to the chart. The onHistoryCallback signals data arrival. What can go wrong: if your server returns bars in a different format than TradingView expects — timestamps in seconds instead of milliseconds, for example — the chart shows nothing and the error is silent. I spent two hours on that exact bug last year.
For live updates, use subscribeBars. This is where WebSocket connections come in. As new price ticks arrive, your code calculates fresh OHLC values and pushes them to the chart:
- Connect to your WebSocket provider (I've used Polygon.io and Finnhub for different projects — Polygon's crypto coverage is better in my experience)
- Stream ticks into
subscribeBars - Let the charting library handle the visual update
Pro tip on error handling: Implement onErrorCallback properly. Network connections fail, APIs rate-limit, and servers go down. A clear error message is better than a frozen chart. For more practical fixes, check out our guide on common TradingView integration issues at pineify.app.
Adding Real-Time Data
Real-time updates make a chart feel alive. The subscribeBars method opens a persistent connection to your data source, and new bars appear without any page refresh.
Here's a practical setup: your backend — say, Python connected to Interactive Brokers via EWrapper — receives live ticks, pushes them into a queue, and forwards them to the frontend through a WebSocket. The chart stays in sync because subscribeBars processes each update as it arrives.
Keyboard shortcuts speed up trading. You can bind Ctrl+B to execute a market buy order by overriding the widget's keypress events and linking them to your broker API. I don't use this for my own trading — I prefer manual confirmation — but several users on our developer forum rely on it for speed.
Save your chart drawings. Trendlines and annotations disappear on page reload unless you persist them. The library's save and load methods handle this. Store serialized data in localStorage for a single-session fix, or send it to your database for cross-device sync. I usually pick localStorage for quick tools and a database for production dashboards — there's no one-size-fits-all answer here.
Crypto data doesn't need to be hard. The Moralis OHLCV API pulls token prices in a few lines of code. The Pyth Network offers low-latency feeds for Solana assets. I've used Pyth for a DeFi dashboard tracking SOL and MATIC, and the latency was under 200ms, which is good enough for most use cases.
| Feature | Purpose | Key Tool/API |
|---|---|---|
| Live Price Updates | Display real-time data without page refreshes | subscribeBars in Datafeed API |
| Quick Trade Execution | Execute orders instantly with keyboard shortcuts | Widget Event Overrides & Broker API |
| Persistent Drawings | Save and reload chart annotations | save/load methods, localStorage or DB |
| Crypto Data Integration | Fetch and display token prices | Moralis or Pyth Network APIs |
Advanced Tips: Broker Integration and Performance
Connecting TradingView charts directly to a broker account lets you place trades from the chart.
- Questrade lets you link an account and manage orders inline. It saves switching between screens.
- Market scanners filter through hundreds of symbols for volume spikes or price patterns. I scan for unusual options volume on SPY weekly — it catches moves I'd otherwise miss.
Custom indicators give you an edge. The study API lets you write your own scripts. If Pine Script isn't your thing, our Pine Script strategy guide walks through creating a complete trading strategy from scratch.
Performance matters for active traders:
- Limit historical bars to about 5,000. More than that and the browser suffers, especially on laptops.
- Lazy-load charts that aren't in the viewport. Your initial page load feels instant.
- Minify the library files before deployment — smaller payloads mean faster renders.
| Timeframe | Best For |
|---|---|
| 1-min to 15-min | Scalping and very short-term entry points |
| 1-hour to 4-hour | Day trading and swing trading |
| Daily to Weekly | Swing trading and identifying long-term trends |
| Monthly | Big-picture macroeconomic analysis |
Symbol search with fuzzy matching helps users find AAPL even when they type "aple." I added this to our platform after watching a demo user struggle with exact-match search for five minutes.
Security and Error Handling
Protect your API keys. Implement rate limiting on your backend, not the frontend. Rotate keys periodically. I set up automatic rotation every 30 days through a CI pipeline — it's a one-time config that prevents credential leaks.
Watch the browser console. When TradingView deprecates a feature, a warning appears in the console log first. During development, keep the console open. I caught a breaking change in the createStudy API signature this way before it reached production.
Cross-check OHLC data. During testing, compare your datafeed output against an official source. I found a mismatch in our historical BTC bars once — the server was caching stale data, and the chart showed incorrect pivot levels. Validating early prevented a bad trade signal.
Next Steps
Build a dashboard that tracks three or four symbols at once. It's a practical way to test everything you've set up — datafeed, real-time updates, multiple chart layouts. Start with AAPL, SPY, and BTC-USD to cover stocks and crypto.
TradingView's developer community on GitHub is active. When I got stuck on a WebSocket reconnection issue, someone had posted a working example within hours.
If you want to go deeper, explore Pine Script for custom strategies on TradingView's platform. Our Pine Script from scratch guide covers entry and exit rules with real backtest data. Or look into broker APIs for fully automated execution.
▶Do I need approval to use the TradingView Charting Library?
Yes. You fill out TradingView's application form and wait for approval. They review each request individually, so it's not instant. Expect about a week.
▶Can the TradingView API handle real-time crypto data?
Yes, through a data feed provider like Bitquery or Moralis. They stream OHLCV data for tokens, and the chart updates in real time via subscribeBars. I've used both and Moralis has better documentation.
▶How do I add custom indicators to a TradingView chart widget?
Call createStudy on the IChartWidget interface. Pass the indicator name, parameters like period length, and plot color. The library renders it automatically on the active chart.
▶Is the TradingView Charting Library free for commercial use?
The library itself is free once approved. But connecting to a broker for live orders may have separate fees. Check TradingView's latest licensing terms before deploying commercially.
▶What should I do if my custom datafeed fails to load bars?
Add error handling inside getBars using onErrorCallback. This lets you show a friendly message and fall back to cached data so the chart stays functional. I always keep a fallback dataset for exactly this reason.
▶How do I persist chart drawings and annotations across page reloads?
Use the charting library's save and load methods. Store serialized data in localStorage for quick access, or send it to your database for cross-device sync. I use localStorage for simple tools and a DB for multi-user setups.
▶What is the recommended maximum number of historical bars to load?
5,000 bars is a safe limit. Loading more can exhaust browser memory and slow rendering, especially on lower-end devices.

