如何在PineScript中获得具有时间序列切片的数组?



我在Pinescript中有以下代码,我基本上试图将时间序列切片成NextFunction内使用的数组。

当使用array.from直接实例化的数组时,NextFunction工作正常。但是当被LoadArray实例化时,它不起作用。为什么会这样呢?如何将LoadArray转换为与NextFunction兼容的功能?

Ps:NextFunction使用矩阵来执行计算。

LoadArray(series, length) =>
res = array.new_float(length)
for i = length - 1 to 0
array.set(res, i, series[i])
res := res
NextFunction(y) =>
...
...
y = LoadArray(close, 5)
y2 = array.from(1212.3, 1211.6, 1212.7, 1214.8, 1216.1)
res1 = NextFunction(y2) // works alright
res2 = NextFunction(y) // does not work

我期望得到的数组yy2将是相等的,并且在NextFunction中以相同的方式表现。但是,出于某种原因,他们没有。

我尝试使用历史引用,但没有成功。


UPDATE 27 - 12 - 2022

我愿意执行的功能仍然不起作用。因此,为了更好地理解为什么LoadArrayALoadArrayC不能生成有效的coef数组,我决定公开整个脚本。

var global_print_counter = array.new_int()
array.push(global_print_counter, 0)
print(txt = "") => 
if txt != "" and barstate.islast
int print_counter = array.get(global_print_counter, 0)
printLabel = label.new(x=bar_index, y=high - print_counter*7500, textcolor=color.white, color=color.black, text=txt)
array.set(global_print_counter, 0, print_counter + 1)
//@version=5
indicator(title="LoadArray Test", shorttitle="LT", format=format.volume)
PowerSummation(vector0, power0, vector1, power1) =>
var accumulator = 0.0
for i = 0 to array.size(vector0) - 1
accumulator += math.pow(array.get(vector0, i), power0)*math.pow(array.get(vector1, i), power1)
accumulator := accumulator
GetCoefficients(x, y) =>
int n = array.size(x)
var coefficients = array.from(1.0, 1.0, 1.0)
var A = matrix.new<float>(3, 3, 0)
var idv = array.new_float(array.size(x), 1)
float ex1 = PowerSummation(x, 1, idv, 0)
float ex2 = PowerSummation(x, 2, idv, 0)
float ex3 = PowerSummation(x, 3, idv, 0)
float ex4 = PowerSummation(x, 4, idv, 0)
var ex = array.from(ex1, ex2, ex3, ex4)
matrix.set(A, 0, 0, n)
matrix.set(A, 0, 1, ex1)
matrix.set(A, 0, 2, ex2)
matrix.set(A, 1, 0, ex1)
matrix.set(A, 1, 1, ex2)
matrix.set(A, 1, 2, ex3)
matrix.set(A, 2, 0, ex2)
matrix.set(A, 2, 1, ex3)
matrix.set(A, 2, 2, ex4)
var B = matrix.new<float>(3, 1, 0)
float b3 = PowerSummation(x, 2, y, 1)
float b2 = PowerSummation(x, 1, y, 1)
float b1 = PowerSummation(idv, 0, y, 1)    
matrix.set(B, 0, 0, b1)
matrix.set(B, 1, 0, b2)
matrix.set(B, 2, 0, b3)

var invA = matrix.inv(A)
var X = matrix.mult(invA, B)
coefficients := array.from(matrix.get(X, 0, 0), matrix.get(X, 1, 0), matrix.get(X, 2, 0))
LoadArrayA(series, length) =>
res = array.new_float(length)
for i = length - 1 to 0
array.set(res, i, series[i])
res := res
LoadArrayB(series, length) =>
res = array.from(1219.23, 1219.54, 1220.57, 1221.2, 1221.01)
res := res
LoadArrayC(series, length) => 
res = array.new_float() 
for i = length - 1 to 0 
array.unshift(res, series[i]) 
res := res
Linspace(length) =>
res = array.new_float(length)
for i = 0 to array.size(res) - 1
array.set(res, i, i)
res := res

x = Linspace(5)
y = LoadArrayB(close, 5) // works
// y = LoadArrayA(close, 5) // does not produce valid coef
// y = LoadArrayC(close, 5) // does not produce valid coef
coef = GetCoefficients(x, y)
print(str.tostring(coef))

UPDATE 29 - 12 - 2022

nz添加到LoadArrayALoadArrayC实现中可以防止nan读取,但计算出的coef数组仍然是不正确的。

LoadArrayA(series, length) =>
res = array.new_float(length)
for i = length - 1 to 0
array.set(res, i, nz(series[i]))
res := res

您需要防止na值,这些值在序列有足够的历史参考之前悄悄进入早期柱的计算中。您可以等待,直到图表上处理的条形图的数量大于您的长度,或者您可以使用nz()来替换na的值。可以尝试一个包含nz()的修改数组函数,如下所示,以便在早期历史记录中使用na以外的值填充数组:

LoadArrayC(series, length) =>
res = array.new_float(length)
for i = length - 1 to 0
array.set(res, i, nz(series[i]))
res 

PowerSummation()函数中,accumulatorvar声明。这导致值在整个历史中不断累积,并在每个条上添加相同的值。通过删除它,我们将只对每个栏上的数组元素单独求和

PowerSummation(vector0, power0, vector1, power1) =>
float accumulator = 0.0
for i = 0 to array.size(vector0) - 1
accumulator += math.pow(array.get(vector0, i), power0)*math.pow(array.get(vector1, i), power1)
accumulator 

最后,在GetCoefficients()函数中,用var声明invAX。去除这个尤为重要。用var声明这一点会导致它们计算历史上的第一个bar,并在整个运行时保持该值,而其他变量保持动态。

祝你编码顺利。

两个数组不包含相同类型的变量。
y2 (array.from)包含float类型
y (LoadArray)包含一个系列float类型,作为[x]返回一系列值(参见https://www.tradingview.com/pine-script-reference/v5/#op_[])
似乎你的NextFunction只与float一起工作。

切换到下面的LoadArray实现应该可以修复它。

LoadArray(series, length) =>
res = array.new<float>(length, series)
res := res

你能改变一下吗

LoadArray(series, length) =>
res = array.new_float(length)
for i = length - 1 to 0
array.set(res, i, series[i])

:

LoadArray(series, length) => 
res = array.new_float() 
for i = length - 1 to 0 
array.unshift(res, series[i]) 

?

使用第一种技术,您将用相同的内容填充数组拷贝,设置它们会设置所有,你得到的唯一结果是最后一次迭代。

如果不行,我们真的需要更多的信息☺️

@fikira12在https://t.me/PineCodersQA上的回答

最新更新