龙听期货论坛's Archiver

龙听 发表于 2024-3-29 14:25

【PART 2】历史操作符:使用历史引用操作符获取历史数据

使用历史引用操作符获取历史数据

在编写 TradingView Pine 脚本时,我们经常希望将当前条形图的数据与之前的条形图进行比较。但我们如何从以前的条形图中获取数据呢?

使用历史引用操作符检索以前的数据

如果没有操作符,我们的脚本只能执行非常基本的任务。操作符是对一个或多个值执行操作的代码元素(Stephens,2014 年)。操作符 "作用于 "的值就是我们所说的操作数(Sharp,2013 年)。您可能已经使用过的 TradingView 运算符包括算术运算符(+、-、/ 和 *)和赋值运算符(=)。

其中一个有价值的运算符是历史引用运算符。该运算符由两个方括号([])组成,放在变量或函数的后面。在这些方括号中,我们输入一个大于 0 的正整数。然后,历史引用运算符将返回该变量或函数在该条数之前的值(Pine Script Language Tutorial,未注明日期;TradingView,未注明日期)。

例如,close[1] 返回上一栏的收盘价,open[3] 返回 3 栏前的开盘价。同样,ta.ema(close, 10)[1] 返回基于收盘价的 10 条指数移动平均线 (EMA) 的前一栏值。我们可以使用历史引用操作符(如收盘价[0]和成交量[0])或不使用历史引用操作符(收盘价、成交量)访问当前条的值。

TradingView 历史引用操作符的上下文依赖性

TradingView脚本在每个条形图上执行计算,从最早的条形图到最近的条形图(Pine Script Language Tutorial,n.d.)。这使得[]返回的前值取决于脚本当前计算的条形图。

下面的图片对此进行了直观解释。假设脚本是在箭头所指的条形图上计算的。使用历史参考运算符访问前收盘价的过程如下:

[img]http://p.algo2.net/2024/0329/5e170da31f5d3.png[/img]
[img]http://p.algo2.net/2024/0329/07310cfc758ad.png[/img]
[img]http://p.algo2.net/2024/0329/dca1f520c7724.png[/img]

这也表明,历史引用运算符返回的值完全取决于前一个条形图。因此,像 month[1] 这样的表达式不会返回上个月,而是返回上一栏的月份。

TradingView 历史引用操作符的重要特征

[]操作符有几个值得注意的特点。首先,我们不能将该操作符重复应用于同一操作数(Pine Script Language Tutorial,n.d.)。因此,虽然 open[1] 是有效的,但不能用 open[1][2] 来检索 2 个交易日前的开盘价。相反,我们需要将这些值组合在一起(所以是 open[3])。

其次,历史引用运算符只能使用正值(表示回溯的条数)。不允许使用方括号之间的负值(如 high[-1])(Pine Script Language Tutorial,n.d.)。

第三,[]运算符只有在变量或函数的值是一系列数据时才起作用(Pine Script Language Tutorial, n.d.)。换句话说,如果一个值没有历史值,那么历史引用操作符就不起作用。也就是说,[]对所有与价格条数据相关的值(如 high[9]、time[12]和 ta.highest(high,10)[1])都有效。但对硬编码值(如 "我的文本信息"[1])或 syminfo.ticker 等变量无效,后者返回的是工具的符号(TradingView,注),没有历史值,因为符号在每个条形图上都是相同的。

第四,也是最后一点,当我们试图访问一个超出图表条数的值时,历史引用运算符会返回 NaN 值(Pine 脚本语言教程,未注明出处)。例如,当脚本当前计算的是第三条柱状图时,low[10] 返回 NaN("非数字"),因为 10 条柱状图之前还没有柱状图。

历史引用操作符返回的值

从技术上讲,历史引用操作符并不返回单个值,而是返回一系列具有一定偏移量的值(Pine Script Language Tutorial,n.d.),尽管我们通常认为历史引用操作符访问的是第 n 个元素(Admin,2014 年)。

这意味着,举例来说,close[5] 返回的不是一个收盘价,而是一系列与 5 条前收盘价相等的收盘价。我们可以通过一个简单的编程示例来直观地理解这种行为:[code]
//@version=5
indicator(title="History referencing operator", overlay=true)

plot(close[5], linewidth=2)
[/code]该代码绘制了 5 个条形图之前的收盘价,添加到图表后看起来像这样:

[img]http://p.algo2.net/2024/0329/f9f4574dbdb68.png[/img]

在 TradingView 中绘制历史值的示例

在这里,我们可以看到 close[5] 的值与收盘价相同,但只是 5 个条形图之后的价格。

由于历史引用运算符会返回一系列值,因此我们可以在函数参数中使用[]运算符。例如,用 ta.ema(close[5],20)计算 5 个交易日前收盘价的 20 期 EMA。如果 close[5] 只返回一个收盘价(而不是一系列价格),那么我们就无法用它计算指数平均值。

现在,我们来看两个将历史引用操作符应用于变量和函数的示例。

在 TradingView 中获取变量在之前条形图中的值

历史引用操作符([])可以这样访问变量的前值:[code]//@version=5
indicator(title="History referencing operator - 1", overlay=false)

priceDiff = hl2 - hl2[10]

colour = priceDiff > priceDiff[1] ? color.orange : color.blue

plot(priceDiff, color=colour, style=plot.style_histogram,
     linewidth=3)[/code]我们首先使用 indicator() 函数设置脚本属性。接下来创建的 priceDiff 变量保存了 hl2 当前值与 10 个条形图前值之间的价格差。我们在历史引用运算符(hl2[10])的方括号内加上 10,就能得到该历史值。hl2 内置变量返回的是条形图的中点([高点 + 低点] / 2;TradingView, n.d.),10 个条形图的差值显示了动量,正值表示中点值上升,负值表示中点动量下降。

然后,我们使用条件三元运算符(?:)创建颜色变量并存储两种颜色(color.橙色或 color.蓝色)中的一种。该运算符评估一个真/假条件(其第一个操作数)。如果条件为真,则返回第二个操作数(此处为 color.orange);否则,返回第三个操作数(color.blue)。这里我们要检查的条件是 priceDiff 的当前值是否大于 (>) 其先前值。我们通过在变量(priceDiff[1])后面放置 [] 运算符来获取前一个值。

示例最后使用 plot() 函数在图表上绘制一系列数据(TradingView,注)。我们将其第一个参数设置为 priceDiff 变量的值。它的颜色参数设置为 color 变量,这样,根据条形图的中点动量差值,绘图会呈现橙色或蓝色。如果将样式设置为 plot.style_histogram,我们就会得到柱状图(而不是普通的折线图),如果将线宽设置为 3,我们就会得到粗柱状图条。

该示例指标添加到图表后的效果如下:

[img]http://p.algo2.net/2024/0329/48e3d2d64063c.png[/img]

在 TradingView 中使用函数历史引用操作符

[ ] 操作符也可用于函数参数(如 ta.ema(close[2],20))和函数(ta.ema(close,20)[2])之后(参见 Pine Script Language Tutorial, n.d.)。例如[code]//@version=5
indicator(title="History referencing operator - 2", overlay=true)

highestHigh = ta.highest(high, 20)[1]
lowestLow = ta.lowest(low[1], 20)

plot(highestHigh, color=color.green)
plot(lowestLow, color=color.red)[/code]我们首先在这里使用所需的 indicator() 函数。

然后创建两个变量。第一个变量是 highestHigh,它被设置为 ta.highest() 函数返回的值,该函数返回一定数量条形图的最高值(TradingView,n.d.)。通过将参数设置为 high 和 20,它将返回 20 条记录的最高值。

但由于这 20 条记录的最高值也包括当前记录,因此某条记录的最高值永远不会超过 ta.highest(high,20)。这就是为什么我们要在函数后面添加值为 1 的历史引用操作符。现在,它会返回前 20 个条形图的最高点,但不包括当前条形图的最高点。

同样,the lowestLow 变量也被设置为 ta.lowest() 函数计算出的值,该函数返回给定条数的最低值(TradingView,n.d.)。这会产生同样的问题:如果 ta.lowest() 包括当前条形图,那么条形图的低点就永远不会低于 20 条形图的低点。但是,由于我们是在 low[1] 上计算最低点的,因此历史引用运算符会带来 1 个条形图的滞后。因此,ta.last(low[1], 20) 并不包括当前条形图的低点。

计算出变量后,我们使用 plot() 函数将其显示在图表上。最高 High 值绘制为绿色直线,最低 Low 值显示为红色实线。

当我们将此示例指标添加到图表中时,我们可以看到历史引用运算符是如何使最高高点和最低低点的值滞后于 1 个条形图的:

[img]http://p.algo2.net/2024/0329/1a63ea827c201.png[/img]

总结

历史引用运算符([])在方括号之间加上一个正整数,可返回前一个条形图的值。该操作符可用于任何内置变量、用户自定义变量、标准函数或返回一系列值的自定义函数。当我们试图访问的数据多于图表上的条形图时,历史引用操作符会返回 NaN。

页: [1]