Skip to content

Variables ​

How do you make a variable, change it later, and know where you can read it? Declare it with = and change it with :=. A name lives from its declaration to the end of the block that declares it, and writing = again inside a nested block makes a second variable instead of changing the first.

pine
//@version=6
indicator("Last breakout", overlay = true)
float top = ta.highest(high, 20)[1] // computed again on every bar
var float level = na                // declared once, then kept
if close > top
    level := close                  // := changes the level declared above
plot(level, "Breakout level")

Declaring ​

name = value declares a variable and gives it its value. The line runs on every bar, so a plain declaration holds a fresh value each bar: top above is that bar's 20-bar high. The value sets the type, so n = 0 is an int and price = close a float.

Write the type first when the value doesn't say it. na alone has no type, so a variable that starts empty is declared as float level = na. Strict Pine refuses level = na, as TradingView does.

Put var in front to declare the variable once and keep its value from bar to bar, as level does. var and varip covers what that keeps and when.

A function that returns several values gives a tuple, which [a, b] = f() takes apart into two new variables:

pine
//@version=6
indicator("Channel width")
channel(int len) => [ta.highest(high, len), ta.lowest(low, len)]
[upper, lower] = channel(20) // two variables from one call
plot(upper - lower, "Width")

Changing a value ​

:= gives a declared variable a new value. +=, -=, *=, /= and %= change it by an operation, so n += 1 is n := n + 1. The variable has to be declared first: the Script Editor stops n := 1 when no n came before it.

= always makes a variable, so it can't change one: after n = 0, a second n = n + 1 in the same block is another declaration, not a change. Declaring a name twice in one block is an error on TradingView (CE10095), and strict Pine refuses it with the same reason. AmenoScript accepts it, with a warning, and the second declaration starts a new variable for the rest of the block.

Where a name can be read ​

A block is the indented lines under an if, an else, a loop, a switch arm or a function. A name declared at the top of the script, outside every block, can be read on any line after it, inside blocks and functions too. A name declared inside a block exists only there, from its declaration to the block's end.

pine
//@version=6
indicator("Inside and outside a block")
float body = close - open     // top level: readable below, blocks included
float shown = na
if body > 0
    float half = body / 2     // exists only inside this if
    shown := half             // carry it out through an outer variable
plot(shown, "Half the body")

TradingView refuses a name read after the block that declared it. To use a block's result after the block, declare the variable before it and change it inside, as shown does here. Or write the if as an expression that gives its value: see Control flow.

A second variable by the same name ​

x = ... inside a block, where x was declared outside it, doesn't change the outer x. It declares a new x that lives in the block and hides the outer one there. When the block ends, the outer x still holds what it held before. TradingView warns about this (CW10013), and so does the Script Editor, because it's nearly always a typo for :=:

pine
//@version=6
indicator("= or := in a block", overlay = true)
float kept = na
float changed = na
if close > ta.highest(high, 20)[1]
    kept = close     // a new kept, gone at the block's end: warns
    changed := close // changes the changed declared above
plot(kept, "Always na")
plot(changed, "Breakout close")

The warning reads: "This declares a new kept for this block, and the kept outside it keeps its value. To change that one, write kept := ...".

A loop's counter is its own variable in the same way. for i = 0 to 3 beside an outer i leaves the outer i as it was, and the editor says so: "This loop's i is its own, and the i outside it keeps its value".

Functions and outer variables ​

A function can read the script's top-level variables, but it can't change one: TradingView refuses := on an outer variable inside a function.

Instead, return the new value and assign it where you call the function. Or keep the state in an array, a map or an object, which a function can change through its reference (see Collections). A function's own variables and parameters are local to it, and each place you call it keeps its own var values and history: see State in functions and branches.

Traps ​

  • = where you meant :=. Inside a block it makes a second variable, and the outer one never changes. Read the CW10013 warning.
  • A block's variable read after the block. Declare it before the block instead.
  • := on an outer variable inside a function. Return the value, or change an array or object.
  • A type that changes. Here a reassignment can change a variable's type, as in x = 1 then x := "a". TradingView refuses that. See the types reference.
  • [a, b] := [b, a]. Swapping through a tuple is AmenoScript only. In Pine, use a third variable.

See also ​

AmenoScript is compatible with Pine Script v6. Pine Script is a trademark of TradingView, Inc., which has no part in AmenoScript.