Appearance
Script structure
How is a script's text laid out so it parses? A script declares itself with indicator(), strategy() or library(), then runs one statement a line, top to bottom. Indentation makes the blocks: 4 spaces or a tab under an if, a loop or a function. A long line wraps inside parentheses or after an operator, with the next line indented by a number of spaces that isn't a multiple of 4.
pine
//@version=6
// a comment runs from // to the end of its line
indicator("Range mid-point", overlay = true)
int len = input.int(20, "Length", minval = 1)
//@function The middle of the range of the last n bars.
//@param n How many bars.
mid(int n) =>
float hi = ta.highest(high, n) // the body: indented 4 spaces
float lo = ta.lowest(low, n)
(hi + lo) / 2
float m = mid(len)
// a long call wraps after a comma, the next line indented 5 spaces
plot(m, "Mid", color = close > m ? color.teal : color.orange,
linewidth = 2)The version line
Every script runs on Pine Script v6's rules, and a //@version line is a comment to every engine here: //@version=5 runs as v6 too. Keep //@version=6 at the top of a Pine script anyway, because TradingView compiles by it. An AmenoScript text states no version, and the Script Editor marks a version line in one and offers to take it out. Pine compatibility has the reasons.
The declaration
The declaration says what the script is and sets its options: indicator("Name", overlay = true), strategy(...) for a backtest or library(...) for code other scripts import. Write exactly one, as the first statement. TradingView refuses a script without one. This engine runs such a script anyway, so a missing declaration only shows when you paste the text there. Declarations lists every argument.
Statements and blocks
Each line holds one statement: a declaration, an assignment, a call such as plot(...), or the head of a block. Several short statements can share a line, separated by commas: a = 1, b = 2.
A block is the lines indented under the line that opens it. A line opens a block when it starts with if, else, for, while, switch, type or enum, or ends with a function's =>. Indent a block 4 spaces deeper than that line, or one tab, which counts as 4 spaces. The block ends at the first line indented back to the opening line's level.
pine
//@version=6
indicator("Blocks")
float score = 0
if close > open
score := 1 // inside the if: 4 spaces
if close > close[1]
score := 2 // a nested block: 8 spaces
else
score := -1
plot(score)Plot-family calls, such as plot(), hline() and bgcolor(), go at the top level, not inside a block or a function. TradingView refuses one in a block, and so does strict Pine. Work the value out in the block and plot it outside. Labels, lines and boxes are different: make them anywhere, as the if below does.
Wrapping a long line
Break a long line inside parentheses or brackets, after an operator, or after a comma. Indent the next line by a number of spaces that isn't a multiple of 4, such as 5 or 6, since multiples of 4 mark blocks. That's the form TradingView reads too.
pine
//@version=6
indicator("Wrapped lines", overlay = true)
float typical = (high + low +
close) / 3
if barstate.islast
// a string can't break: end it and join the next part with +
label.new(bar_index, high, "Typical price: " +
str.tostring(typical, format.mintick))
plot(typical, "Typical")The operator can end the line it breaks or start the next one: indented 5 spaces, a line starting + close wraps the line above, here and on TradingView. Indented a multiple of 4, the same line is AmenoScript's leading-operator continuation, which TradingView and strict Pine refuse. A string can't break across lines: end one string and join the next with +, as the example does. See syntax TradingView refuses.
Comments and annotations
// starts a comment that runs to the end of its line, on a line of its own or after code. There's no block comment: /* ... */ is a syntax error.
An annotation is a comment that starts with //@ and a tag, placed on the lines right above what it describes. The engines skip annotations. The Script Editor reads them, as TradingView's editor does, and shows them when you hover the name.
| Tag | Describes |
|---|---|
//@function | the function declared below it |
//@param name | one of the function's parameters |
//@returns | what the function gives back |
//@type and //@field name | a user type and one of its fields |
//@enum | an enum |
//@variable | the variable declared below it |
TradingView also reads //@description as a published library's summary. Here it's an ordinary comment.
Names
A name starts with a letter or an underscore and goes on with letters, digits and underscores: fastLen, _tmp, ema2. Names are case-sensitive, so len and Len are two variables. A keyword such as if, for, var, and or true can't be a name. Keywords lists them.
Literals
| Kind | Written as | What it gives |
|---|---|---|
| int | 42, 0 | a whole number |
| float | 3.14, .5, 5., 1e3, 2.5e-2 | a number with a fraction: a point or an exponent makes it float |
| bool | true, false | a bool, which in v6 is never na |
| string | "text", 'text' | either quote mark |
| color | #FF8800, #FF880080 | a colour as hex red, green and blue, then an optional opacity byte |
| na | na | no value: see na |
A string holds \n for a new line, \t for a tab, and \\, \" and \' for the characters themselves. A backslash before any other character gives that character. In a colour's opacity byte, FF is solid and 00 invisible, so #FF000080 is red at transparency 50. Colours has the rest.
Traps
- A stray indent. Indent a line only to put it in a block or to wrap the line above. TradingView refuses an indent anywhere else, even where this engine reads past it.
- A tab counts as 4 spaces. A block indented with a tab on one line and 4 spaces on the next is one block. A line indented with a tab and 2 more spaces sits 6 deep, so it wraps the line above instead.
/*isn't a comment. Comment each line with//.
See also
- Declarations, every argument of
indicator(),strategy()andlibrary() - Types, what the literals' types mean
- Variables, declaring and assigning
- Syntax TradingView refuses, what AmenoScript adds to the layout
- Pine compatibility, where this engine and TradingView part