You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何自定义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时结果不相等,请问我忽略了什么问题?


核心问题分析

你忽略了三个关键逻辑差异:

  1. 对比对象完全错误:
    原函数的两个if判断是和上一根K线的滤波结果(array.get(rfilt, 1),即前一次的rfilt[0])对比,而你的rng_filt2是和当前输入x对比。原逻辑是基于历史滤波值做判断,你的改写完全偏离了这个核心规则。
    • 原函数中array.set(rfilt, 1, array.get(rfilt, 0))是实现状态持续的关键:把当前周期的滤波值存为下一根K线的历史参考值,并非无意义代码。
  2. 持久化状态丢失:
    原函数用var声明的rfilt数组会保留每一次的计算结果,实现跨周期的状态延续。但你的rng_filt2里,rng_filt1每次直接赋值为x,完全没有利用rfilt数组保存的历史状态,相当于每次都重新计算,没有延续之前的滤波结果。
  3. 条件逻辑完全无效:
    你写的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:35:07