运算符
介绍
一些运算符用于构建返回结果的表达式:
其他运算符用于为变量赋值:
=
用于为变量赋值,但仅限于声明变量时(第一次使用时):=
用于为先前声明的变量赋值。以下运算符也可以这样使用:+=
,,,,,-=
*=
/=
%=
如类型系统页面中所述,限定符和类型在确定表达式产生的结果类型方面起着至关重要的作用。这反过来又会影响到你被允许使用这些结果的方式和函数。表达式总是返回一个在表达式中使用的最强限定符的值,例如,如果你将“输入 int”与“系列 int”相乘,表达式将产生“系列 int”结果,你将无法将其用作 ta.ema ()length
中的
参数。
该脚本将产生编译错误:
//@version=5
indicator("")
lenInput = input.int(14, "Length")
factor = year > 2020 ? 3 : 1
adjustedLength = lenInput * factor
ma = ta.ema(close, adjustedLength) // Compilation error!
plot(ma)
编译器会报错:无法使用参数“length”=“adjustedLength”调用“ta.ema”。使用了“series int”类型的参数,但预期为“simple int”;。发生这种情况的原因
lenInput
是“输入 int”factor
是“series int”(只能通过查看
每个条形图上的年份值来确定)。因此,为变量分配了一个“series int”值。我们的问题是, ta.ema()adjustedLength
的参考手册条目
告诉我们其参数需要“simple”值,这是一个比“series”更弱的限定符,因此不允许使用“series int”值。length
解决我们的难题需要:
- 使用其他支持“系列 int”长度的移动平均函数,例如 ta.sma(),或者
- 不使用计算来生成我们的长度的“系列整数”值。
算术运算符
Pine Script™ 中有五种算术运算符:
操作员 | 意义 |
---|---|
+ | 加法和字符串连接 |
- | 减法 |
* | 乘法 |
/ | 分配 |
% | 模数(除法后的余数) |
上面的算术运算符都是二元的(意味着它们需要两个
操作数(或值)才能进行运算,例如1 + 2
)。+
and
-
也可用作一元运算符(意味着它们只对一个操作数进行运算,例如
-1
或+1
)。
如果两个操作数都是数字,但其中至少有一个是 float 类型,则结果也将是 float。 如果两个操作数都是 int 类型,则结果也将是 int。 如果至少一个操作数是 na,则结果也是 na。
该+
运算符还可用作字符串的连接运算符。
"EUR"+"USD"
生成"EURUSD"
字符串。
该%
运算符通过将商向下舍入为尽可能低的值来计算模数。下面是一个简单的示例,有助于说明如何在后台计算模数:
//@version=5
indicator("Modulo function")
modulo(series int a, series int b) =>
a - b * math.floor(nz(a/b))
plot(modulo(-1, 100))
比较运算符
Pine Script™ 中有六种比较运算符:
操作员 | 意义 |
---|---|
< | 少于 |
<= | 小于或等于 |
!= | 不等于 |
== | 平等的 |
> | 比...更棒 |
>= | 大于或等于 |
比较运算是二进制的。如果两个操作数都是数值,则结果将为booltrue
类型,即false
或
na。
例子:
1 > 2 // false
1 != 1 // false
close >= open // Depends on values of `close` and `open`
逻辑运算符
Pine Script™ 中有三个逻辑运算符:
操作员 | 意义 |
---|---|
not | 否定 |
and | 逻辑连接 |
or | 逻辑析取 |
该运算符not
是一元运算符。当应用于true
, 操作数时,结果将为false
,反之亦然。
and
运算符真值表:
A | b | a 和 b |
---|---|---|
真的 | 真的 | 真的 |
真的 | 错误的 | 错误的 |
错误的 | 真的 | 错误的 |
错误的 | 错误的 | 错误的 |
or
运算符真值表:
A | b | a 或 b |
---|---|---|
真的 | 真的 | 真的 |
真的 | 错误的 | 真的 |
错误的 | 真的 | 真的 |
错误的 | 错误的 | 错误的 |
`?:` 三元运算符
? : 三元运算符用于创建以下形式的表达式:
condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
三元运算符返回的结果取决于 的值
condition
。如果 为true
,则valueWhenConditionIsTrue
返回 。如果condition
为false
或
na,则
valueWhenConditionIsFalse
返回 。
可以使用三元表达式的组合来达到与 switch 结构相同的效果,例如:
timeframe.isintraday ? color.red : timeframe.isdaily ? color.green : timeframe.ismonthly ? color.blue : na
示例从左到右进行计算:
- 如果
timeframe.isintraday
为
true
,则color.red
返回 。如果为false
,则 评估timeframe.isdaily 。 - 如果
timeframe.isdaily
为
true
,则color.green
返回 。如果为false
,则 评估timeframe.ismonthly 。 - 如果
timeframe.ismonthly
为
true
,则color.blue
返回 ,否则 返回na 。
请注意,每一侧的返回值:
都是表达式 --- 而不是本地块,因此它们不会影响每个范围 500 个本地块的限制。
`[ ]` 历史引用运算符
可以 使用 [] 历史引用运算符 引用时间序列的过去值。过去值是变量在脚本当前执行的柱(即当前柱)之前的柱上的值。有关脚本在柱上执行方式的更多信息,请参阅 执行模型 页面。
[]运算
符用于变量、表达式或函数调用之后。运算符方括号内的值是我们要引用的过去偏移量。要引用
距离当前柱两柱的内置变量
的卷volume[2]
值,可以使用。
由于系列会动态增长,因此随着脚本在连续的条形图上移动,与运算符一起使用的偏移量将引用不同的条形图。让我们看看相同偏移量返回的值是如何动态的,以及为什么系列与数组有很大不同。在 Pine Script™ 中,
close
变量或close[0]
等效变量保存当前条形图的“收盘价”。如果您的代码现在正在数据集
的第三条条形图(图表上所有条形图的集合)上执行,将包含该条形图收盘时的价格,将包含前一条条形图(数据集的第二条条形图)收盘时的价格,并且
,第一条条形图。将返回
na
因为该位置不存在条形图,因此其值不可用。close
close[1]
close[2]
close[3]
当在下一个柱上执行相同的代码时,数据集中的第四个柱close
现在将包含该柱的收盘价,而close[1]
代码中使用的相同代码现在将引用数据集中第三个柱的“收盘价”。数据集中第一个柱的收盘价现在将为close[3]
,这次close[4]
将返回
na。
在 Pine Script™ 运行时环境中,由于您的代码针对数据集中的每个历史条执行一次,从图表左侧开始,Pine Script™ 会在索引 0 处向系列中添加一个新元素,并将系列中预先存在的元素推向一个索引之外。相比之下,数组可以具有恒定或可变的大小,并且其内容或索引结构不受运行时环境的修改。因此,Pine Script™ 系列与数组非常不同,并且仅在索引语法方面与数组相似。
当图表符号的市场开放且脚本正在图表的最后一根柱状图(实时柱状图)上执行时, close 返回当前价格的值。它仅包含脚本最后一次在该柱状图上执行时(当该柱状图关闭时)实时柱状图的实际收盘价。
Pine Script™ 有一个变量,其中包含脚本正在执行的条形图的编号: bar_index。在第一个条形图上, bar_index 等于 0,并且在脚本执行的每个连续条形图上,它都会增加 1。在最后一个条形图上, bar_index 等于数据集中的条形图数减一。
在 Pine Script™ 中使用运算符时,还有另一个重要注意事项需要牢记
[]
。我们已经看到过历史引用可能返回
na
值的情况。
na
表示一个非数字的值,在任何表达式中使用它都会产生同样是
na 的结果
(类似于NaN)。这种情况通常发生在脚本在数据集的早期条形图中的计算过程中,但在某些条件下也可能发生在后期条形图中。如果您的代码没有明确提供处理这些特殊情况的方法,它们可能会在脚本的计算中引入无效结果,并可能一直影响到实时条形图。
na和
nz
函数旨在处理这种情况。
这些都是 [] 运算符的有效用法:
high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)
请注意, [] 运算符只能对同一个值使用一次。这是不允许的:
close[1][2] // Error: incorrect use of [] operator
运算符优先级
计算的顺序由运算符的优先级决定。优先级较高的运算符先计算。以下是按优先级降序排列的运算符列表:
优先级 | 操作员 |
---|---|
9 | [] |
8 | 一元+ ,一元- ,not |
7 | * ,,/ % |
6 | + ,- |
5 | > ,,,,< >= <= |
4 | == ,!= |
3 | and |
2 | or |
1 | ?: |
如果一个表达式中有多个优先级相同的运算符,则按从左到右的顺序进行计算。
如果必须按照与优先级所规定的顺序不同的顺序来计算表达式,则可以用括号将表达式的各部分组合在一起。
`=` 赋值运算符
该=
运算符用于在变量初始化(或声明)时(即第一次使用时)分配变量。它表示这是我将使用的一个新变量,我希望它在每个柱状图上都以此值开始。
这些都是有效的变量声明:
i = 1
MS_IN_ONE_MINUTE = 1000 * 60
showPlotInput = input.bool(true, "Show plots")
pHi = pivothigh(5, 5)
plotColor = color.green
有关如何声明变量的更多信息,请参阅 变量声明页面。
`:=` 重新赋值运算符
用于:=
将值
重新分配给现有变量。它表示使用我之前在脚本中声明的这个变量,并赋予它一个新值。
先声明然后使用 重新赋值的变量:=
称为可变变量。以下所有示例都是有效的变量重新赋值。您将
在“var”声明模式
部分中
找到有关var如何工作的更多信息:
//@version=5
indicator("", "", true)
// Declare `pHi` and initilize it on the first bar only.
var float pHi = na
// Reassign a value to `pHi`
pHi := nz(ta.pivothigh(5, 5), pHi)
plot(pHi)
注意:
- 我们用以下代码声明:
pHi
。varvar float pHi = na
关键字 告诉 Pine Script™ 我们只希望 在数据集的第一个条上用na初始化该变量。关键字告诉编译器我们正在声明一个“float”类型的变量。这是必要的,因为与大多数情况相反,编译器无法自动确定符号右侧值的类型。float
=
- 由于使用了var ,变量声明将仅在第一条柱线上执行,而
该
pHi := nz(ta.pivothigh(5, 5), pHi)
行将在图表的所有柱线上执行。在每个柱线上,它评估 pivothigh () 调用是否返回 na , 因为这是函数在未找到新枢轴时所执行的操作。 nz() 函数执行“检查 na ”部分。当其第一个参数 (ta.pivothigh(5, 5)
) 为 na时,它返回第二个参数 (pHi
) 而不是第一个。当 pivothigh() 返回新找到的枢轴的价格点时,该值将分配给pHi
。当它返回 na (因为未找到新的枢轴) 时,我们将 的先前值分配pHi
给其自身,实际上保留了其先前的值。
我们的脚本的输出如下所示:
注意:
- 该线将保留其先前的值,直到找到新的枢轴。
- 枢轴点实际发生后五根柱线才会被检测到,因为我们的
ta.pivothigh(5, 5)
调用表明,我们需要在高点两侧有五个较低的高点才能将其检测为枢轴点。
有关如何为变量重新赋值的更多信息,请参阅 变量重新赋值部分。