Language basics
The syntax follows Pine v5. Indentation matters: four spaces or a tab.
x = 1 // declare
x := x + 1 // change (also += -= *= /= %=)
var total = 0.0 // keeps its value from bar to bar
float f = na // type words are accepted and ignored
[a, b, c] = ta.macd(close, 12, 26, 9) // tuples
prev = close[1] // earlier bars: close[0] is now
ta.sma(close, 5)[1] // works on any expression
if close > open
plot(close)
else if close < open
plot(open)
for i = 0 to 9 by 2 // inclusive; break / continue work
while cond
switch kind // or a bare `switch` on conditions
"A" => 1
=> 0
f(a, b = 2) => a * b // functions; a body can be indented
Series
Every variable is a series: it has a value on every bar. close is today's close, close[1] is the previous bar's, and close[20] is twenty bars back. The first bars of a long lookback have no value yet, which shows as na (a gap on the chart).
var keeps state
A plain total = 0.0 starts again on every bar. var total = 0.0 is set once and keeps whatever you assign to it, so you can count, accumulate, or remember a level.
Operators
+ - * / %, == != < > <= >=, and or not, and ? :. Strings join with +.
- Dividing by zero gives
na. - A comparison with
nais false, except!=, which is true (as with NaN). Sota.change(x) != 0is true on the first bar.
Line wrapping
A statement can continue on the next line if you indent it by something that is not a multiple of four, or end the line with an operator or comma.
Prices are decimals
Candles are stored as integer points, and a script sees close = 1.08432. Float arithmetic can make two moves that are exactly equal in points differ in the last digit.
Do not compare computed prices with ==. Compare against a tolerance instead: math.abs(a - b) < syminfo.mintick / 2. The built-in ta.dmi already does this.