Drawing & Visualization
Rune uses a declarative visual model. You describe what should be rendered on each bar with draw(...) and optional panel blocks.
Rune does not expose imperative APIs like line.new(...), label.new(...), or table.new(...).
draw(...)
Basic form:
draw(type=..., ...)Common arguments (accepted by every draw type):
| Argument | Meaning |
|---|---|
type / kind | Draw type |
color / colour | Color value (see Colors) |
layer / z | front or back |
title / name | Display name shown in the legend and settings |
id | Stable identifier for the plot |
pane | price or rune — which pane the plot renders in |
scale | price or rune — which price scale the plot binds to |
track_price | true/false — extend a price line from the latest value |
show_last_value | true/false — show the last-value marker on the scale |
visible / show | true/false — initial visibility |
legend | true/false — show the plot in the legend |
settings | true/false — show the plot in the settings dialog |
Supported Draw Types
The full set: line, ticks, step_line (alias step), area, histogram, columns (alias column), band (alias fill), bar, shape (alias marker), label, hline, and vline.
Series Plots: Line, Ticks, Step Line, Area, Histogram, Columns
line, ticks, step_line, area, histogram, and columns all plot a single series and share the same arguments. step is an alias for step_line; column is an alias for columns.
bar:
let fast = ema(close, 20)
let day_vwap = vwap(reset="day")
let prev_day_high = prev_high(reset="day")
let macd_line, signal_line, hist = macd(close, 12, 26, 9)
draw(type=line, series=fast, color=signal_long, width=2)
draw(type=ticks, series=day_vwap, color="gray")
draw(type=step_line, series=prev_day_high, color="#FFB300")
draw(type=histogram, series=hist, baseline=0, color=signal_long)Arguments:
series/value/y(required) — must be a series name declared withlet/flag, not an inline expressionwidthstyle=solidordashedbaseline— numeric anchor forhistogram/columns-style fillsstep=left,right, orcenter— step alignment for stepped plotscolorlayer
Band / Fill
fill is an alias for band.
draw(type=band, a=upper, b=lower, color="#2979FF", alpha=0.12)
draw(type=fill, a=support, b=resistance, color=signal_long, alpha=0.08)Arguments:
a/from/start(required)b/to/end(required)widthalphagapscolorlayer
Bar
bar:
let zero = 0
draw(type=bar, a=volume, b=zero, color=up, alpha=0.4)Both a and b must be series names declared with let/flag — bind constants to a name first.
Arguments:
a/from/start(required)b/to/end(required)widthalphagapscolorlayer
Shape / Marker
marker is an alias for shape.
draw(type=shape, shape=circle, when=overbought, at=high, color=signal_short)
draw(type=marker, shape=triangleup, when=breakout, at=low, color=signal_long)Arguments:
shape(required)when/if/condition(required)at(required)sizealphacolorlayer
Supported shape names include:
circlediamondtriangleuptriangledown
Convenience aliases:
dot->circlepoint->circletriangle->triangleupup->triangleupdown->triangledownarrowup->triangleuparrowdown->triangledown
Label
draw(type=label, when=entry, text="LONG", at=low, color=signal_long, align=up, offset=12)Arguments:
when/if/condition(required)text/label(required)at(required)align=upordownoffset— vertical offset in screen pixels (positive = down)colorlayer
Placement follows the TradingView convention: align=up hangs the label below its anchor, centered on the bar (a "LONG" tag under the bar's low), and align=down places it above the anchor (a "SHORT" tag over the high). Use offset to add pixel clearance — for example align=up, offset=12 sits 12px below the low, and align=down, offset=-12 sits 12px above the high. Without align, the label renders at the top-right of its anchor.
Horizontal Line
hline draws a fixed horizontal level across the chart. level must be a numeric literal.
draw(type=hline, level=50, color="gray", style=dashed)Arguments:
level/value/price/y(required, numeric literal)widthstyle=solidordashedcolorlayer
Vertical Line
vline draws a vertical line on every bar where the condition is true.
draw(type=vline, when=session_open, color="#2979FF", style=dashed)Arguments:
when/if/condition(required)widthstyle=solidordashedcolorlayer
Colors
Rune supports:
- literal color names such as
"orange" - hex values such as
"#00E676" - semantic color keys:
signal_long,signal_short,up,down,bull,bear,text color(...)param names, for examplecolor=accentwhereaccentis aparam accent = color(...)heat(series)/heat(series, dir)dynamic heat coloring (see below)
Example:
draw(type=line, series=fast, color=signal_long)
draw(type=line, series=slow, color="#FF1744")Heat Coloring
color=heat(series) colors the plot per bar instead of with one static color. Each bar, the plotted series value is matched to the nearest of several price levels inside a trailing window, and the color comes from a cold-to-hot gradient based on how often price traded at that level — "hotter" means more touches.
draw(type=line, series=trail, color=heat(trail, trend_dir), width=2)heat(series)— heat-color using the bullish palette (or a series namedtrend_dirif one is declared)heat(series, dir)—diris a direction series (1bullish,-1bearish) that switches between the bull and bear gradient palettes
The heat window is controlled by params named heat_len (window length, default 50), heat_levels (number of price levels, default 3, max 15), and heat_thresh (touch-count threshold, default 3) — declare params with those names to make the heat map tunable.
Panels
Panels are Rune’s dashboard surface.
panel status:
title "Trend"
metric fast = ema(close, 20) format="price"
status bias = close > ema(close, 50) tone="success"
trade_log limit=5Supported panel items:
title "..."metric name = expr format="number|price|pct|currency|r"status name = expr tone="neutral|success|danger|warn|info"trade_log limit=<int>
Behavior:
- chart preview renders live metrics and statuses
- backtests hydrate
trade_logwhen requested
Example
script(name="Bands + Markers", version=1, mode=indicator, overlay=true)
stream market = ohlcv()
panel status:
title "Bands"
metric basis = sma(market.close, 20) format="price"
status trend = market.close > ema(market.close, 50) tone="success"
bar:
let basis = sma(market.close, 20)
let band_width = stdev(market.close, 20) * 2
let upper = basis + band_width
let lower = basis - band_width
signal breakout = cross_up(market.close, upper)
draw(type=line, series=basis, color="orange", width=2)
draw(type=fill, a=upper, b=lower, color="#2979FF", alpha=0.10)
draw(type=marker, shape=triangleup, when=breakout, at=market.low, color=signal_long)Not Supported in Public Rune
Do not rely on these Pine-style patterns in Rune docs or examples:
line.new(...)label.new(...)table.new(...)box.new(...)- arbitrary chart coordinates or object mutation APIs