Skip to content

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.

TagDescribes
//@functionthe function declared below it
//@param nameone of the function's parameters
//@returnswhat the function gives back
//@type and //@field namea user type and one of its fields
//@enuman enum
//@variablethe 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 ​

KindWritten asWhat it gives
int42, 0a whole number
float3.14, .5, 5., 1e3, 2.5e-2a number with a fraction: a point or an exponent makes it float
booltrue, falsea bool, which in v6 is never na
string"text", 'text'either quote mark
color#FF8800, #FF880080a colour as hex red, green and blue, then an optional opacity byte
nanano 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 ​

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