Indicators on Charts
Once you apply a Pine script to a replay chart, it becomes part of the chart: it draws in the right pane, gets a legend row with controls, remembers its settings per symbol, and updates live as the replay streams. This page covers everything about that lifecycle.
Overlay vs sub-pane
Where an indicator draws depends on its declaration:
- Overlay scripts (
indicator("...", overlay=true)) draw directly on the price pane — moving averages, VWAP, bands, and anything else priced in the instrument’s units. - Non-overlay scripts (
overlay=false, the default) get their own sub-pane below the price chart, the way RSI or MACD render on TradingView. Each non-overlay indicator gets its own pane.
What renders
| Pine call | Rendered as |
|---|---|
plot() | A line in the script’s pane |
plotshape(), plotchar() | Chart markers at the bar location |
hline() | A horizontal level line |
box.new, line.new, label.new | Boxes, trend/level lines, and label bubbles drawn on the pane |
table.new / table.cell | A screen-anchored panel (for example a state readout in a corner) |
barcolor/bgcolor/fill and linefill are not rendered yet — scripts that use them still run, but those visuals are skipped. See Supported Features for the full matrix.
Legend controls
Every applied indicator gets a legend row on the chart with four controls:
| Control | What it does |
|---|---|
| Status dot | Shows the script’s state — running normally or halted on an error |
| Eye | Hides or shows the indicator’s plots without removing it |
| Gear | Opens the inputs dialog |
| × | Removes the indicator from the chart |
The inputs dialog
The inputs dialog is generated automatically from the script’s input.* declarations — you never build a settings UI by hand. Supported input types:
| Declaration | Dialog field |
|---|---|
input.int() | Number field (integer) |
input.float() | Number field (decimal) |
input.bool() | Checkbox |
input.string() | Text field, or a dropdown when options is provided |
input.color() | Color picker |
input.source() | Source dropdown (close, open, hl2, …) |
input.timeframe() | Timeframe field |
Constraints declared on the input — minval, maxval, step, and options — are honored by the dialog fields.
While the dialog is open, changes apply as a live preview: the indicator re-runs and the chart updates as you edit. Click OK to commit the new values or Cancel to revert to what you had.
Per-symbol persistence
Applied indicators are saved per symbol. If you apply your SMA cross to NQ with a fast length of 8, it will be there — with the same inputs — the next time you load an NQ chart, even after a full page reload. Switching to ES gives you that symbol’s own set of applied indicators.
You can have up to 10 indicators applied per symbol. Removing one with the × control also removes it from the persisted set (the saved script itself is untouched).
Live replay updates
Indicators are not static overlays — they recalculate in real time as replay candles stream in:
- Closed bars — Each new completed candle extends every plot by one value.
- The forming candle — The still-open candle updates with exact Pine open-bar semantics: as the current candle’s price moves, the indicator’s value for that bar recalculates on each update, and the value commits when the bar closes — the same behavior your script has on a TradingView realtime chart.
Strategies follow the same rule: strategy state updates live as candles stream. See Strategies for how orders interact with the forming bar.
The error console
The error console at the bottom of the editor drawer surfaces two kinds of problems:
- Compile errors — Syntax and type errors found when you apply the script. Each entry shows the location; click it to jump to that line in the editor.
- Runtime errors — Errors that occur while the script is running, reported with the bar index where they happened — for example, calling an unsupported
ta.*function.
Runtime error behavior:
- The first runtime error halts that script instance. Its status dot on the legend row shows the halted state. Other applied indicators keep running — one broken script never takes the rest down.
- A halted script stays halted until you re-apply it.
- Runs over chart history are capped at 30 seconds; a script that exceeds the cap halts with a timeout error.