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

Pine Script获取RSI背离点bar索引时计数器始终返回固定值问题

RSI背离指标首个背离点bar索引定位异常问题分析

问题描述

基于公开脚本开发RSI背离检测指标时,需要定位构成背离形态的两个K线中第一个背离点的bar索引(即该点距当前K线已走过的K线根数):

  • 已通过Y=ta.valuewhen(plFound, rsi[lbR], 1)语句成功获取第一个点的RSI数值
  • 后续尝试使用ta.barssince函数、for循环回溯遍历K线,查找RSI值等于Y的K线位置时逻辑失效,计数器q始终返回固定值51

涉及代码如下:

//@version=5  
indicator(title="RSI Divergence Indicator w/Alerts", format=format.price,overlay=true)
len = input.int(title="RSI Period", minval=1, defval=14)
src = input.source(title="RSI Source", defval=close)
lbR = input.int(title="Pivot Lookback Right", defval=5)
lbL = input.int(title="Pivot Lookback Left", defval=5)
rangeUpper = input.int(title="Max of Lookback Range", defval=60)
rangeLower = input.int(title="Min of Lookback Range", defval=5)
plotBull = input.bool(title="Plot Bullish", defval=true)
plotHiddenBull = input.bool(title="Plot Hidden Bullish", defval=false)
plotBear = input.bool(title="Plot Bearish", defval=true)
plotHiddenBear = input.bool(title="Plot Hidden Bearish", defval=false)
rsi = ta.rsi(src, len)

plot(rsi, title="RSI", linewidth=2, color=#8D1699)
hline(50, title="Middle Line", linestyle=hline.style_dotted)
obLevel = hline(70, title="Overbought", linestyle=hline.style_dotted)
osLevel = hline(30, title="Oversold", linestyle=hline.style_dotted)
fill(obLevel, osLevel, title="Background", color=#9915FF, transp=90)

plFound = na(ta.pivotlow(rsi, lbL, lbR)) ? false : true
phFound = na(ta.pivothigh(rsi, lbL, lbR)) ? false : true
_inRange(cond) =>
    bars = ta.barssince(cond == true)
    rangeLower <= bars and bars <= rangeUpper

//------------------------------------------------------------------------------
// Regular Bullish
// Osc: Higher Low

oscHL = rsi[lbR] > ta.valuewhen(plFound, rsi[lbR], 1) and _inRange(plFound[1])

// Price: Lower Low

priceLL = low[lbR] < ta.valuewhen(plFound, low[lbR], 1)
bullCond = plotBull and priceLL and oscHL and plFound

plot(
     plFound ? osc[lbR] : na,
     offset=-lbR,
     title="Regular Bullish",
     linewidth=2,
     color=(bullCond ? bullColor : noneColor),
     transp=0
     )
Y=ta.valuewhen(plFound, rsi[lbR], 1)     
plot(Y,color=color.yellow,offset=-lbR)// THIS SHOWS THE RSI'S FIRST POINT VALUE

q=0
if bullCond
    for i=0 to 50
        q:=q+1
        if ta.rsi(close,14)[i]==Y
            break
            
plot(bullCond?q:na,color=color.orange,offset=-lbR)// IT ALWAYS SHOWS 51 !

故障原因

q固定返回51是三个逻辑错误共同导致的:

  1. 浮点数相等判断永远不成立:RSI是经过平滑、除法运算得到的浮点型数值,哪怕视觉上两个值看起来一致,实际存储时小数末尾会存在极细微的精度误差,直接用==做绝对相等判断几乎不可能命中。循环内的break条件永远不会触发,代码会跑完0到50的全部51次循环,q从0开始每次循环加1,最终结果固定为51。
  2. 遍历逻辑和pivot的偏移规则不匹配:plFound标记的pivot点,实际对应的K线位置是信号出现位置往左偏移lbR根K线,不是信号出现的当根K线。循环从i=0(当前K线)开始回溯找RSI等于Y的位置,本身就找错了搜索范围。
  3. 重复计算RSI放大精度误差:循环内每次重新调用ta.rsi(close,14)[i]计算RSI,和全局提前计算好的rsi序列在回溯时会产生额外的精度偏差,进一步降低相等判断的命中概率。

修正方案

不需要通过遍历匹配RSI值的方式找pivot位置,直接通过pivot信号的时间偏移计算bar索引即可:

  • 利用ta.barssince直接获取上一次plFound成立的位置距离当前K线的根数,叠加lbR偏移量就能得到第一个背离点的准确bar索引
  • 如果需要做值校验,用差值阈值判断代替绝对相等判断,规避浮点数精度问题

修正后的核心代码替换原有的q计算逻辑即可:

Y=ta.valuewhen(plFound, rsi[lbR], 1)     
plot(Y,color=color.yellow,offset=-lbR)

q = 0
if bullCond
    // 上一个plFound信号距离当前的bar数 + pivot右偏移量 = 第一个背离点的bar索引
    lastPivotSignalBar = ta.barssince(plFound[1])
    q := lastPivotSignalBar + lbR
    // 可选精度校验,差值小于0.0001即认为匹配,过滤异常值
    // if math.abs(rsi[q] - Y) > 0.0001
    //     q := na
            
plot(bullCond?q:na,color=color.orange,offset=-lbR)

内容的提问来源于stack exchange,提问作者konkoori

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:22:10