Cheat sheet
The syntax of the language on one page. Header, names, inputs, operators, choices and loops, functions, formats, drawing, time and orders.
The whole language at a glance. Every form here compiles on the chart; follow the links for the rules.
A whole indicator#
// One program that uses most of the syntax on one page.
indicator "Cheat sheet"
edition = 1
display = price
enum Kind
sma = "SMA"
ema = "EMA"
type Band
upper: float
lower: float
group "Average"
/// How many bars the average reads
input length: int = 20, name = "Length", min = 2, max = 500
input kind: Kind = Kind.ema, name = "Kind"
input src: source = close, name = "Source"
input width: float = 2.0, name = "Width", min = 0.1, step = 0.1
input band_color: color = #2962ff, name = "Band colour"
session london = 08:00 .. 16:30 @ "Europe/London"
fn band_of(middle: float, size: float): Band = Band(upper = middle + size, lower = middle - size)
let sma = tech.sma(src, length)
let ema = tech.ema(src, length)
let middle = match kind
Kind.sma => sma
Kind.ema => ema
let b = band_of(middle, width * tech.atr(length))
state above_count = 0
mut last_three = 0.0
for i in 0 until 3
last_three += close[i]
if close > b.upper
above_count += 1
let crossed = tech.crosses_above(close, middle)
let top = plot(b.upper, name = "Upper", color = band_color)
let bottom = plot(b.lower, name = "Lower", color = band_color)
shade(top, bottom, color = color.fade(band_color, 90), name = "Band")
plot(middle, name = "Middle", color = color.gray, width = 2)
plot(last_three / 3, name = "Mean of 3 closes", display = none)
mark.shape(crossed, name = "Cross up", shape = triangle_up, place = below, color = color.green)
chart.background(if london.active then color.fade(color.blue, 94) else na, name = "London")
let yesterday_high = prior(day).high
plot(yesterday_high, name = "Yesterday's high", style = step_break, color = color.orange)
if bar.is_last
label.new(
bar.index,
b.upper,
f"{above_count} closes above, last {close:price}",
style = label_down,
)The shape of a script#
| Write | Means |
|---|---|
indicator "Name" | the header of an indicator; its settings are indented under it |
strategy "Name" | the header of a strategy (simulated orders) |
module Name | the header of a module that other scripts import |
edition = 1 | the edition of the language the script is written for |
display = price | draw on the price chart; without it the script gets its own pane |
// text | a comment, to the end of the line |
/// text | above an input: its tooltip |
| four spaces | one level of a block (if, for, fn, group …); a tab is an error |
One statement a line. A long statement goes on when a line ends with an operator or a comma, or inside brackets. See Syntax and layout.
Names and values#
| Write | Means |
|---|---|
let x = close - open | a name set once on each bar, never changed |
mut n = 0 | a value that starts again on each bar and may change: n += 1, -=, *=, /= |
state count = 0 | a value kept from bar to bar; state day starts again each trading day |
close[1] | the value one bar back (history) |
na, is_na(x), x ?? 0 | no value; the test for it; a fallback |
20, 2.5, "text", true | a whole number, a number, a text, a truth value |
#2962ff, color.red, color.fade(c, 80) | colours: a code, a name, more transparent |
08:30, @2026-01-01T00:00Z, 15m, 0.5% | a time of day, a moment, a duration, a percentage |
[1, 2, 3], [0.0; 4] | an array; four copies of 0.0 |
map<int, float>() | an empty map from whole numbers to numbers |
See let, mut and state, Values and types, Units and literals.
Inputs#
| Write | Shows |
|---|---|
input length: int = 20, name = "Length", min = 1, max = 500 | a whole number with limits |
input mult: float = 2.0, name = "Width", step = 0.1 | a number; step moves the field |
input on: bool = true, name = "Show" | a switch |
input src: source = close, name = "Source" | the price the script reads |
input c: color = color.blue, name = "Colour" | a colour picker |
input tf: tf = "60", name = "Timeframe" | a timeframe |
input kind: text = "EMA", name = "Kind", options = ["EMA", "SMA"] | a dropdown |
input mode: Mode = Mode.fast, name = "Mode" | a dropdown of an enum |
group "Name" | the inputs indented under it share a heading |
See Inputs.
Operators, loose to tight#
| Operators | Note |
|---|---|
if c then a else b | a value chosen by a condition; the else is required |
or | the right side runs only when the left is false |
and | the right side runs only when the left is true |
not | looser than a comparison: not a == b is not (a == b) |
== != < <= > >= | not chained: a < b < c is an error |
?? | the right side when the left is na |
+ - | add, subtract (+ also joins texts) |
* / % | multiply, divide, remainder |
-x | minus |
x[1], f(x), a.b | history, a call, a member |
There is no power operator: write math.pow(x, 2). A call that remembers earlier bars (tech.*, data.series) may not stand on the right of and, or, ?? or in a branch of if ... then ... else (E3302): give it a line of its own. See Lazy operators.
Choices and loops#
| Write | Does |
|---|---|
if cond with an indented block, else | runs the block when the condition is true |
let v = if cond then a else b | chooses a value |
match x then "a" => 1 lines and _ => 0 | chooses by value; match with no subject chooses by condition |
for i in 0 to 3 | 0, 1, 2, 3 (until 3 leaves 3 out; by 2 sets the step) |
for x in items, for (i, x) in items | each item of an array, with its position |
while cond | repeats while the condition holds |
break, continue | leave the loop; go to its next pass |
A loop may not hold a call that remembers earlier bars (E3301). See Choices and loops.
Functions, types and enums#
| Write | Means |
|---|---|
fn mid(a: float, b: float): float = (a + b) / 2 | a one-line function |
fn f(x: float) with an indented block and return | a function with a block |
fn scaled(x: float, k: float = 2.0): float | a parameter with a default; call with scaled(close, k = 0.5) |
let (a, b) = pair() | take a tuple apart (_ skips a value) |
type Band with indented fields upper: float | a record; build it with Band(upper = 1.0, lower = 0.0) |
fn Band.width(self): float = self.upper - self.lower | a method, called as b.width() |
enum Mode with indented fast = "Fast" | a closed list of names |
import Me/Name@1 as alias | one of your own modules |
A function may not call itself (E3310). See Functions, types and enums, Modules and libraries.
Text and formats#
| Write | Gives |
|---|---|
f"Close {close:price}" | the close with the symbol's own decimals |
{x:.2f}, {x:,.2f}, {x:+.1f} | two decimals; with thousands; with a sign |
{x:.1%}, {x:03} | a percentage; padded with zeros |
{x:.1f?'n/a'} | n/a while x is na |
text.fmt(x, ".2f"), text.length(s), text.split(s, ",") | text functions |
See Text and number formatting.
Drawing on the chart#
| Write | Draws |
|---|---|
plot(x, name = "A", color = color.blue, width = 2, style = histogram) | a series on every bar |
level(70, name = "Top", style = dashed) | a horizontal line |
shade(top, bottom, color = color.fade(color.purple, 90)) | the space between two plots or levels kept in names |
mark.shape(cond, shape = triangle_up, place = below) | a shape where a condition is true |
mark.char(cond, char = "x", place = above), mark.arrow(x) | a character; an arrow up or down by the sign |
chart.background(if cond then color.fade(color.green, 90) else na) | the background of a bar |
chart.candles(color) | recolours the chart's candles |
label.new(bar.index, high, "text"), line.new(x1, y1, x2, y2), box.new(left, top, right, bottom) | drawings placed by bar and price |
table.new(top_right, 2, 2), table.cell(t, 0, 0, "A") | a table in a corner |
log.info("close {0}", close) | a line in the script's log |
Plot styles: line, line_break, step, step_break, step_diamond, histogram, columns, area, area_break, circles, cross. See Plots and drawings, Tables.
Time and other timeframes#
| Write | Gives |
|---|---|
bar.index, bar.time, bar.is_last | the bar's number, its time, true on the newest bar |
data.series("240", tech.ema(close, 20), symbol = symbol.id) | an expression on another timeframe, last closed bar |
prior(day).high, current(week).open | yesterday's high; this week's open (intraday charts) |
session london = 08:00 .. 16:30 @ "Europe/London" | a named session: london.active, .start, .end, .high, .low |
clock.hour_of(bar.time, zone = "UTC") | the hour of a time in a zone |
See Other timeframes and symbols, Trading day and sessions.
Common built-ins#
| Group | Some of its names |
|---|---|
| prices | open high low close volume hl2 hlc3 ohlc4 |
tech | tech.sma tech.ema tech.rma tech.rsi tech.atr tech.stdev tech.highest tech.lowest tech.crosses_above tech.crosses_below tech.pivot_high tech.macd |
math | math.abs math.max math.min math.round math.floor math.sqrt math.pow math.sign |
symbol | symbol.id symbol.tick symbol.pip |
color | color.rgb color.fade color.gradient and the named colours |
The Function index lists every name with its parameters, and the Function reference explains each one.
Strategies#
| Write | Does |
|---|---|
orders.enter("Long", side.long) | opens a simulated long trade with the key "Long" (side.short for a short) |
orders.close("Long") | closes it |
orders.exit("Exit", "Long", stop = s, limit = t) | a stop and a target for the trade "Long" |
orders.cancel("Key"), orders.close_all() | cancels an order; closes everything |
position.size, position.avg_price | the open size (positive for a long); its price |
setup: with capital, size = sizing.lots(0.1), fees = fee.per_lot(3.5) | money, size and commission |
execution: with spread = 20 ticks, slippage = 2 ticks | the costs of a fill |
// A strategy: orders with a key, a stop and a target, size and costs in the header.
strategy "Cheat sheet strategy"
edition = 1
display = price
setup:
capital = 10000
size = sizing.lots(0.1)
fees = fee.per_lot(3.5)
execution:
spread = 20 ticks
slippage = 2 ticks
let fast = tech.ema(close, 10)
let slow = tech.ema(close, 30)
if tech.crosses_above(fast, slow)
orders.enter("Long", side.long)
if position.size > 0
orders.exit("Exit", "Long", stop = position.avg_price * 0.99, limit = position.avg_price * 1.02)
if tech.crosses_below(fast, slow)
orders.close("Long")
plot(fast, name = "Fast", color = color.green)
plot(slow, name = "Slow", color = color.red)