Real-time Streaming¶
The streaming system provides continuous real-time data from TradingView Desktop as JSONL (newline-delimited JSON) output. It uses a poll-and-diff pattern -- polling TradingView at a configurable interval and emitting a line only when the data changes.
Architecture¶
All streams share the same core pollLoop() function:
- Call a fetcher function that evaluates JavaScript in TradingView's page context via CDP
- JSON-stringify the result and compare to the previous hash
- If the data changed (or dedup is disabled), write a JSON line to stdout
- Sleep for the configured interval
- Repeat until SIGINT or SIGTERM
Each emitted line includes metadata fields:
| Field | Description |
|---|---|
_ts |
Unix timestamp in milliseconds when the data was emitted |
_stream |
Stream label (e.g., quote, bars, values, lines) |
Connection errors (CDP/ECONNREFUSED) are silently retried with a 2-second backoff. Other errors are logged to stderr.
Available Streams¶
Quote Stream¶
Emits the latest bar's OHLCV data for the active chart symbol.
Output fields: symbol, time, open, high, low, close, volume
Default interval: 300ms
{"symbol":"ES1!","time":1710000000,"open":5200.25,"high":5201.50,"low":5199.75,"close":5201.00,"volume":1234,"_ts":1710000300,"_stream":"quote"}
Bars Stream¶
Emits the last bar with resolution metadata. Useful for detecting new bar formation.
Output fields: symbol, resolution, bar_time, open, high, low, close, volume, bar_index
Default interval: 500ms
Values Stream¶
Emits current numeric values from all visible indicators (RSI, MACD, Bollinger Bands, EMAs, etc.).
Output fields: symbol, study_count, studies[] (each with name and values object)
Default interval: 500ms
{"symbol":"ES1!","study_count":3,"studies":[{"name":"RSI","values":{"plot_0":65.4}},{"name":"MACD","values":{"plot_0":12.5,"plot_1":10.2,"plot_2":2.3}}],"_ts":1710000500,"_stream":"values"}
Lines Stream¶
Emits horizontal price levels drawn by Pine Script indicators via line.new(). Levels are deduplicated and sorted high-to-low.
Output fields: symbol, study_count, studies[] (each with study name and levels array)
Default interval: 1000ms
Filter option: -f, --filter narrows to indicators whose name contains the given substring (case-insensitive).
Labels Stream¶
Emits text annotations drawn by Pine Script indicators via label.new(). Capped at 50 labels per study.
Output fields: symbol, study_count, studies[] (each with study name and labels array of {text, price})
Default interval: 1000ms
Tables Stream¶
Emits structured table data drawn by Pine Script indicators via table.new().
Output fields: symbol, study_count, studies[] (each with study name and tables array of {rows})
Default interval: 2000ms
All Panes Stream¶
Emits data from all panes simultaneously in a multi-chart layout. Each pane reports its symbol, resolution, and latest bar data.
Output fields: layout, pane_count, panes[] (each with index, symbol, resolution, OHLCV fields)
Default interval: 500ms
JSONL Output Format¶
Each line is a self-contained JSON object. Lines are written to stdout with \n separators. This is compatible with standard JSONL/NDJSON tooling.
# Pretty-print each line
tv stream quote | jq .
# Extract just the close price
tv stream quote | jq -r '.close'
# Filter for a specific indicator
tv stream values | jq '.studies[] | select(.name | contains("RSI"))'
# Log to file
tv stream quote >> quote_log.jsonl
Startup Banner¶
When a stream starts, a compliance notice and status line are written to stderr (not stdout), so they do not interfere with JSONL parsing:
When stopped:
Use Cases¶
Price Monitoring¶
Continuously log price data for later analysis:
Indicator-Driven Automation¶
Watch for RSI crossing a threshold:
tv stream values | jq --unbuffered 'select(.studies[] | .name == "RSI" and .values.plot_0 > 70)' | head -1
echo "RSI overbought detected"
Multi-Symbol Dashboard¶
Monitor all panes in a split layout simultaneously:
Level Change Detection¶
Track when Pine Script indicators update their drawn levels:
Data Logging for Backtesting¶
Record bars to build a local dataset:
Configuration¶
| Option | Flag | Description |
|---|---|---|
| Poll interval | -i, --interval |
Milliseconds between polls (stream-specific defaults shown above) |
| Study filter | -f, --filter |
Filter by indicator name (lines, labels, tables streams only) |
Lower intervals increase responsiveness but also increase CDP traffic. For most use cases, the defaults are well-tuned. Avoid intervals below 100ms as they may cause excessive CPU usage.