在编写策略时,我们经常会在一行代码里用到好几个运算符,比如 close > open and volume > 2000
。但你有没有想过一个问题:在一行复杂的计算中,电脑到底会先算哪个、后算哪个?
这个问题不是钻牛角尖,它直接关系到你策略逻辑的生死。如果搞不清楚计算的先后顺序,代码最终执行的结果,可能跟你设想的完全是两码事。一个微小的顺序错误,就可能导致你的买卖信号在错误的时间出现,甚至让止损计算完全失效。这个计算的先后顺序,在编程里就叫“运算符优先级”。
这跟你上小学时学的“先乘除,后加减”是同一个道理。Pine Script 给每个运算符都设定了固定的“辈分”,在计算时永远是“辈分”高的运算符先执行。
有了这个规则,Pine Script 才能确保每一行代码,无论多复杂,都能以一种统一、可预测的方式来执行,避免产生歧义。
举个最经典的例子:2 + 10 * 5
如果让一个不了解优先级规则的人从左到右算,结果是 12 * 5 = 60
。但实际上,因为乘法 *
的“辈分”比加法 +
高,Pine Script 会先算 10 * 5
得到 50
,再用 2
去加,最终结果是 52
。你看,只是顺序不同,结果就差了很远。如果这是一个计算风险或资金的公式,那后果就不堪设想了。
为了帮你彻底避免踩中这类“逻辑地雷”,下面这张表,就是 Pine Script 官方的“运算符辈分排行榜”。优先级越高的运算符,排位越靠前,也就会被越先计算。强烈建议你收藏起来,时常对照。
从上表可以看出,加号(+)和减号(-)既可以作为一元运算符,也可以作为二元运算符。当运算符只作用于单个操作数时,我们称之为一元运算符(例如 -close
,用于获取收盘价的负值);当它作用于两个操作数时,则被称为二元运算符(例如 high - low
)。
此外,表中还有一些运算符的优先级是相同的。当一个表达式中包含多个优先级相同的运算符时,它们将按照从左到右的顺序进行计算。例如,加法(+)和减法(-)的优先级相同,因此表达式 9 - 3 + 22 - 3
的计算结果是 25(计算过程:9 - 3
得 6,6 + 22
得 28,28 - 3
得 25)。
Ps:您无需死记硬背所有规则;在不确定时,使用括号 ()
来明确指定运算顺序,永远是最佳实践。
通过括号强制改变运算顺序
我们可以通过括号 ()
将表达式的某些部分括起来,从而改变其默认的运算顺序。由于括号的优先级是最高的,TradingView 会最先计算括号内的表达式。
例如表达式 10 + 9 * close
会先执行乘法 9 * close
,再与 10
相加,因为乘法的优先级高于加法。但如果我们写成 (10 + 9) * close
,程序则会先计算 10 + 9
,再将结果与 close
相乘。
在某些场景下,我们必须使用括号才能确保计算的正确性。例如,下面这个脚本尝试计算每根K线的中点:
//@version=5
indicator(title="Mr Chen", overlay=true)
// 尝试计算中点
plot(high + low / 2, color=color.blue, linewidth=2)
代码中,我们用 indicator()
函数设置了指标属性,并用 plot()
函数来绘图 (TradingView, n.d.)。我们期望通过 high + low / 2
来绘制出K线的中点。
但当把这个指标添加到图表后,它的实际表现如下图所示:
很明显,计算结果出错了。问题就出在 high + low / 2
这个表达式上,我们忽略了运算符的优先级规则。由于除法(/)的优先级高于加法(+),代码实际执行的是先计算 low / 2
,再将结果与 high
相加。这显然不是我们想要的K线中点。
为了修正这个错误,我们必须使用括号来强制改变运算顺序,像这样将 high + low
括起来:
//@version=5
indicator(title="Mr Chen", overlay=true)
// 正确计算中点
plot((high + low) / 2, color=color.blue, linewidth=2)
当我们把修改后的脚本应用到图表上,它就能正确地绘制出每根K线的中点了:
在 Pine 中使用嵌套括号
有时我们会遇到复杂的表达式,需要将多层括号相互嵌套。在这种情况下,TradingView的Pine会遵循从内向外的原则,即最先计算最里层的括号。
我们以下面的变量 x
的计算为例:
x = (7 % 3) * (4 + (6 / 2))
遵循从内向外的原则,Pine首先计算最里层的 (6 / 2)
,结果为3。表达式变为:
x = (7 % 3) * (4 + 3)
接下来,程序会依次计算余下的括号:
x = 1 * 7 // 因为 (7 % 3) 的余数是 1, 而 (4 + 3) 等于 7
最终,变量 x
的值为7:
x = 7
总结
一个表达式中多个运算符的计算顺序取决于两点:优先级和计算方向。优先级高的运算符先于优先级低的进行计算。当优先级相同时,则遵循从左到右的顺序。而括号 ()
拥有最高的优先级,我们可以利用它来强制改变默认的运算顺序。懂了没,是不是很简单?pine的学习难度将会比MQL4容易很多,感兴趣的加学长微信进群交流:u31u31。