为何自定义Pine Script v4函数rng_filt2与原函数输出不一致?
关于Pine Script v4中rng_filt与自定义rng_filt2函数结果不一致的问题
以下是两个Pine Script(v4)函数:
rng_filt(x, rng_, n)=> r = rng_ var rfilt = array.new_float(2, x) array.set(rfilt, 1, array.get(rfilt, 0)) if x - r > array.get(rfilt, 1) array.set(rfilt, 0, x - r) if x + r < array.get(rfilt, 1) array.set(rfilt, 0, x + r) rng_filt1 = array.get(rfilt, 0) hi_band = rng_filt1 + r lo_band = rng_filt1 - r rng_filt = rng_filt1 [hi_band, lo_band, rng_filt] rng_filt2(x, rng_, n)=> r = rng_ var rfilt = array.new_float(2, x) rng_filt1 = x if x - r > x rng_filt1 := x - r if x + r < x rng_filt1 := x + r hi_band2 = rng_filt1 + r lo_band2 = rng_filt1 - r rng_filt2 = rng_filt1 [hi_band2, lo_band2, rng_filt2]
其中rng_filt是TradingView某指标的原生实现,rng_filt2是为简化代码转成C#而编写的自定义函数。我原以为原函数中array.set(rfilt, 1, array.get(rfilt, 0))无实际作用,且两个if判断是与输入x对比,因此改写为rng_filt2的形式。
函数调用方式如下:
[h_band, l_band, filt] = rng_filt(rng_src, rng_size(rng_src, rng_qty, rng_per), rng_per) [h_band2, l_band2, filt2] = rng_filt2(rng_src, rng_size(rng_src, rng_qty, rng_per), rng_per)
但对比h_band与h_band2时结果不相等,请问我忽略了什么问题?
核心问题分析
你忽略了三个关键逻辑差异:
- 对比对象完全错误:
原函数的两个if判断是和上一根K线的滤波结果(array.get(rfilt, 1),即前一次的rfilt[0])对比,而你的rng_filt2是和当前输入x对比。原逻辑是基于历史滤波值做判断,你的改写完全偏离了这个核心规则。- 原函数中
array.set(rfilt, 1, array.get(rfilt, 0))是实现状态持续的关键:把当前周期的滤波值存为下一根K线的历史参考值,并非无意义代码。
- 原函数中
- 持久化状态丢失:
原函数用var声明的rfilt数组会保留每一次的计算结果,实现跨周期的状态延续。但你的rng_filt2里,rng_filt1每次直接赋值为x,完全没有利用rfilt数组保存的历史状态,相当于每次都重新计算,没有延续之前的滤波结果。 - 条件逻辑完全无效:
你写的if x - r > x和if x + r < x永远不会成立——因为r是范围值,必然为正数,x - r不可能大于x,x + r也不可能小于x,这导致rng_filt1永远等于x,最终hi_band2就是x + r,lo_band2就是x - r,和原函数的滤波逻辑完全无关。
正确的简化版本
要保留原函数核心逻辑,同时简化代码便于转成C#,可以去掉数组改用持久化变量实现:
rng_filt2(x, rng_, n)=> r = rng_ var float rfilt_prev = x // 保存上一次的滤波结果 var float rfilt_curr = x rfilt_prev := rfilt_curr // 对应原函数的array.set(rfilt,1,array.get(rfilt,0)) if x - r > rfilt_prev rfilt_curr := x - r if x + r < rfilt_prev rfilt_curr := x + r hi_band2 = rfilt_curr + r lo_band2 = rfilt_curr - r [hi_band2, lo_band2, rfilt_curr]
这个版本和原函数逻辑完全一致,且结构更简洁,转成C#时只需用两个变量保存历史和当前滤波值即可。
内容的提问来源于stack exchange,提问作者OJNSim
相关产品推荐
相关产品推荐

