Language Reference
This page documents the public Rune language surface shipping today: script(version=1).
Comments
Rune supports full-line comments only.
# Comment
// Also a commentInline comments are not supported. Put comments on their own line.
Script Header
Every Rune script starts with script(...):
script(name="My Script", version=1, mode=indicator, overlay=true)Supported header keys:
| Key | Values | Notes |
|---|---|---|
name | string | Display name for the script |
version | 1 | Launch Rune version |
mode | indicator, strategy | Default is indicator |
overlay | true, false | true draws over price, false uses a sub-pane |
Additional numeric and boolean header keys are treated as backtest defaults when the script runs as a strategy. Common examples include:
initial_capitalcommission_pctfee_discount_pctsize_pctreversehedgingpyramidingmax_entries
Parameters
Parameters create editor controls and runtime inputs.
param fast = int("Fast EMA", 20, min=1, max=200, group="Trend")
param mode = string("Mode", "ATR", options=["ATR", "Percent"], group="Entry")
param accent = color("Accent", "#00E676", group="Style")Parameter Types
| Type | Description |
|---|---|
int / integer | Whole-number input |
float / number | Decimal input |
bool / boolean | True/false toggle |
string | Text input, optionally constrained with options=[...] |
color | Color picker / color value |
timeframe | Timeframe selector |
session | Trading session window like "0900-1700" |
source | Source selector |
symbol | Symbol selector |
Common Parameter Options
| Option | Description |
|---|---|
label | Display label |
default | Default value |
min / max | Numeric bounds |
step | Numeric step size |
hint | Tooltip/help text |
group | Group label in the UI |
options | Allowed option list for string, timeframe, and similar selector params |
Streams
Streams bind OHLCV data into the script.
stream market = ohlcv()
stream htf = ohlcv(timeframe="15m")
stream external = ohlcv(exchange="blofin", symbol="ETH-USDT", bar="1H")Supported Forms
| Form | Meaning |
|---|---|
ohlcv() | Current chart candles |
ohlcv(timeframe="15m") | Same instrument, higher/same timeframe |
ohlcv(timeframe=higher_tf) | Same instrument, expression-backed timeframe |
ohlcv(bar="1H") | Alias for timeframe=... |
ohlcv(exchange="...", symbol="...", timeframe="...") | External OHLCV feed supplied by the host runtime |
Rules:
timeframe,bar,exchange, andsymbolmay come from literals or params- external or lower-timeframe streams require host-supplied candles through
streamSources/streamCandles - same-timeframe and higher-timeframe internal streams can be auto-aligned from chart candles
- stream aliases expose
.time,.open,.high,.low,.close, and.volume
Top-Level Blocks
Rune supports these top-level declarations:
script(...)param ...stream ...keep ...- helper
calcblocks panel ...:risk:bar:
keep
keep declares persistent state that survives from bar to bar.
keep breakout_side = 0
keep trend_count = 0Update kept state with set inside bar:.
Helper calc Blocks
Top-level calc blocks declare reusable pure helper functions:
calc rising(current, prior):
return current > priorHelper functions:
- are pure
- support positional and named arguments
- may return tuples
- may only use
returninside helper blocks
panel
Panels provide lightweight dashboards in preview and backtest results.
panel status:
title "Trend"
metric fast = ema(close, 20) format="price"
status bias = close > ema(close, 50) tone="success"
trade_log limit=5risk:
Strategy scripts can declare top-level portfolio risk controls:
risk:
max_open_positions = 1
daily_loss_limit = equity_pct(2)
daily_trade_limit = 4
reset_tz = "UTC"The bar: Section
bar: contains the per-candle logic.
bar:
let fast = ema(close, 20)
guard trend_ok = close > fast
signal long = trend_ok
alert breakout = long
draw(type=line, series=fast, color=signal_long)Supported Statements in bar:
| Statement | Purpose |
|---|---|
let name = expr | Derived value |
calc name = expr | Alias assignment form for derived values |
set name = expr | Update a keep value |
guard name = expr | Named boolean condition |
rule name: + require ... | AND-composed rule block |
flag name = expr | Named boolean series |
signal name = expr | Alias for flag |
alert name = expr | Named alert series |
draw(...) | Declarative chart rendering |
trade(...) | Entries and exits in strategy mode |
protect(...) | Managed stop/take updates in strategy mode |
Named and Positional Arguments
Expression calls support both positional and named arguments:
let fast = ema(close, 20)
let day_vwap = vwap(reset="day", tz="UTC")
let stamp = timestamp(year=2026, month=4, day=5, hour=12, minute=30, tz="UTC")Rules:
- positional arguments may come first
- after the first named argument, all remaining arguments must be named
- duplicate named arguments are invalid
- unknown named arguments are rejected
Tuple Assignment
Tuple returns can be unpacked directly:
let macd_line, signal_line, hist = macd(close, 12, 26, 9)
let upper, basis, lower = bbands(close, 20, 2)Guards and Rules
guard is a named boolean series. rule groups multiple require lines into one named setup.
bar:
guard trend_ok = close > ema(close, 50)
rule long_setup:
require trend_ok
require volume > sma(volume, 20)
signal long = long_setupRules:
- guards and rules can reference earlier calculations and earlier guards/rules
- they cannot reference future declarations
- rule bodies may not contain side effects
Strategy Statements
Strategy mode adds:
trade(...)protect(...)- position-state builtins such as
position_avg_entry(...)andposition_open_r(...) - optional
risk:blocks
See Strategies & Backtesting for the full trade model.
Deliberate Non-Goals
Rune does not currently support:
- loops
- maps or dictionaries, or array literals — the only collection is the chart-only bounded list
- imports or modules
- imperative drawing APIs like
line.new(...)orlabel.new(...) - Pine namespaces like
strategy.*orrequest.security(...)
That is intentional. Rune stays declarative and product-focused.