Operators
Arithmetic operators
There are five arithmetic operators in Pine Script:
Symbol | Operation |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Modulo (remainder after division) |
The arithmetic operators above are all binary, whith +
and -
also
serving as unary operators.
When using arithmetic operators, the type of the result depends on the
type of the operands. If at least one of the operands is a series,
then the result will also have a series type. If both operands are
numeric, but at least one of these has the type float, then the result
will also have the type float. If both operands are of type integer,
then the result will also have the type integer. If at least one
operand is na
then the result is also na
.
The +
operator also serves as the concatenation operator for strings.
"EUR"+"USD"
constructs the “EURUSD” string.
Comparison operators
There are six comparison operators in Pine Script:
Symbol | Operation |
---|---|
< | Less Than |
<= | Less Than or Equal To |
!= | Not Equal |
== | Equal |
> | Greater Than |
>= | Greater Than or Equal To |
Comparison operations are binary. The result is determined by the type of the operands. If at least one of these operands has a series type, then the type of the result will also be series (a series of logical values). If both operands have a numerical type, then the result will be of the logical type bool.
Logical operators
There are three logical operators in Pine Script:
Symbol | Operation |
---|---|
not | Negation |
and | Logical Conjunction |
or | Logical Disjunction |
All logical operators can operate with bool operands, numerical operands, or series type operands. As is the case with arithmetic and comparison operators, if at least one of the operands is of series type, then the result will also be of series type. In all other cases the type of the result will be the logical type bool.
The operator not
is unary. When applied to a true
operand the result
will be false
, and vice versa.
and
operator truth table:
a | b | a and b |
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
or
operator truth table:
a | b | a or b |
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
?: conditional operator and the iff function
The ?:
conditional ternary
operator
calculates the first expression (condition) and returns the value of
either the second operand (if the condition is true
) or of the third
operand (if the condition is false
). Syntax is:
condition ? result1 : result2
If condition
is true
then the ternary operator will return
result1
, otherwise it will return result2
.
A combination of conditional operators can build constructs similar to switch statements in other languages. For example:
isintraday ? red : isdaily ? green : ismonthly ? blue : na
The example is calculated from left to right. First, the isintraday
condition is calculated; if it is true
then red
will be the result.
If it is false
then isdaily
is calculated, if this is true
, then
green
will be the result. If it is false
, then ismonthly
is
calculated. If it is true
, then blue
will be the result, otherwise
na
will be the result.
For those who find using the ?:
operator syntax inconvenient, there is
an alternative: the built-in iff
function. The function has the
following signature:
The function acts identically to the ?:
operator, i.e., if the
condition is true
then it returns result1
, otherwise result2
. This
is the equivalent of the previous example using iff
:
History reference operator []
It is possible to refer to the historical values of any variable of the
series type with the []
operator. Historical values are variable
values for the previous bars.
Most data in Pine is stored in series (somewhat like arrays, but with a
dynamic index). Let’s see how the index is dynamic, and why series are
also very different from arrays. In Pine, the close
variable, or
close[0]
which is equivalent, holds the price at the close of the
current bar. If your code is now executing on the third bar of the
dataset, close
will contain the price at the close of that bar,
close[1]
will contain the price at the close of the preceding bar (the
second), and close[2]
, the first. close[3]
will return na
because
no bar exists in that position, and thus its value is not available.
When the same code is executed on the next bar, the fourth in the
dataset, close
will now contain the closing price of that bar, and the
same close[1]
used in your code will now refer to the close of the
third bar. The close of the first bar in the dataset will now be
close[3]
and this time close[4]
will return na
.
In the Pine runtime environment, as your code is executed once for each historical bar in the dataset, starting from the left of the chart, Pine is adding a new element in the series at index 0 and pushing the pre-existing elements in the series one index further away. Arrays, in comparison, are usually static in size and their content or indexing structure is not modified by the runtime environment. Pine series are thus very different from arrays and share familiarity with them mostly through their indexing syntax.
At the realtime, close
variable represents the current price and will
only contain the actual closing price of the realtime bar the last time
the script is executed on that bar, and from then on, when it is
referred to using the history-referencing operator.
Pine has a variable that keeps track of the bar count: bar_index
. On
the first bar, bar_index
is equal to 0 and it increases by 1 at each
new bar, so at the last bar, bar_index
is equal to the number of bars
in the dataset minus one.
There is another important consideration to keep in mind when using the
[]
operator in Pine. We have seen cases when a history reference may
return the na
value. na
represents a value which is not a number and
using it in any math expression will produce a result that is also na
(similar to NaN). Such cases often
happen during the script’s calculations in the early bars of the
dataset, but can also occur in later bars under certain conditions. If
your Pine code does not explicitly provide for handling these special
cases, they can introduce invalid results in your script’s calculations
which can ripple through all the way to the realtime bar. The
na() and
nz()
functions are designed to allow for handling such cases.
Note 1. Almost all built-in functions in Pine’s standard library
return a series result. It is therefore possible to apply the []
operator directly to function calls, as is done here:
Note 2. Despite the fact that the []
operator returns a result of
series type, it is prohibited to apply this operator to the same
operand over and over again. Here is an example of incorrect use which
will generate a compilation error:
In some situations, the user may want to shift the series to the left.
Negative arguments for the operator []
are prohibited. This can be
accomplished using the offset
parameter in the plot
annotation,
which supports both positive and negative values. Note though that it is
a visual shift., i.e., it will be applied after all calculations.
Further details on plot
and its parameters can be found
here.
Operator precedence
The order of calculations is determined by the operators’ precedence. Operators with greater precedence are calculated first. Below is a list of operators sorted by decreasing precedence:
Precedence | Operator |
---|---|
9 | [] |
8 | unary + , unary - , not |
7 | * , % |
6 | + , - |
5 | > , < , >= , <= |
4 | == , != |
3 | and |
2 | or |
1 | ?: |
If in one expression there are several operators with the same precedence, then they are calculated left to right.
If the expression must be calculated in a different order than precedence would dictate, then parts of the expression can be grouped together with parentheses.