Pine Script调用request.security时全局变量更新及条件计数问题
Pine Script 全局计数器不更新问题排查与修复
问题场景
编写筛选器代码用于统计指定时间范围内多只证券的RSI均线交叉触发次数,但全局计数器变量始终无法更新,表格中计数显示为0。
核心问题分析
- 计数器传递逻辑错误:每次调用
request.security()时,传入的是全局计数器的初始值(0),而非累计后的数值,导致目标证券的上下文里计数器每次都从0开始计算,无法累计交叉次数。 - 时间范围判断失效:
last_bar_index在request.security()的上下文里指向目标证券的最后bar索引,和主图表的last_bar_index不一致,导致bar_index >= (last_bar_index - lookback_period)的判断逻辑无法正确筛选指定时间范围的交叉信号。 - 函数内计数逻辑缺陷:原函数仅在交叉发生时返回计数器+1,否则返回原计数器,但由于每次传入的都是初始0,最终无法累计有效次数。
修复后的代码
//@version=5 indicator("SMA 50 Crossover (N)", overlay = true) lookback_period = input.int(50, title = "Lookback Period") thres = input.int(2, title = "Threshold") sym1 = input.symbol("NSE:DABUR", 'Symbol 1') sym2 = input.symbol("NSE:RELIANCE", 'Symbol 2') // 定义获取RSI均线交叉计数的函数,内部维护计数器 method get_ma_rsi() => var int counter = 0 rsi = ta.rsi(close, 13) ma_rsi = ta.sma(rsi, 13) crossover = ta.cross(ma_rsi, rsi) // 使用ta.barssince(barstate.islast)判断是否在回溯周期内 if crossover and ta.barssince(barstate.islast) <= lookback_period counter += 1 [rsi, ma_rsi, counter] // 请求目标证券的数据,无需传递全局计数器 [sym1RSI, sym1MARSI, sym1CounterValue] = request.security(sym1, timeframe.period, get_ma_rsi()) [sym2RSI, sym2MARSI, sym2CounterValue] = request.security(sym2, timeframe.period, get_ma_rsi()) // 创建筛选器表格 var table screener = table.new(position.top_right, 2, 10, bgcolor = color.white, border_color = color.black, border_width = 2, frame_color = color.black, frame_width = 2) if barstate.islast screener.cell(0,0, "Symbol") screener.cell(1,0, "Crossovers") screener.cell(0,1, str.tostring(sym1)) screener.cell(1,1, str.tostring(sym1CounterValue)) screener.cell(0,2, str.tostring(sym2)) screener.cell(1,2, str.tostring(sym2CounterValue)) // 调试用(可选保留) plotchar(last_bar_index, "Last Bar Index") plotchar(last_bar_index - lookback_period, "Lookback period")
关键改动说明
- 函数内维护计数器:在
get_ma_rsi函数内部使用var int counter = 0声明计数器,确保每次调用request.security()时,目标证券的上下文会保留之前的累计值,而非每次重置为0。 - 修正时间范围判断:使用
ta.barssince(barstate.islast) <= lookback_period替代原逻辑,该函数会计算当前bar距离最后一个bar的周期数,在目标证券的上下文里也能正确判断是否在指定回溯范围内。 - 移除全局计数器传递:不再将全局计数器传入函数,避免上下文不一致导致的计数重置问题,每个证券的计数在自身的
security上下文内独立维护。
内容的提问来源于stack exchange,提问作者Utkarsh Dhawan
相关产品推荐
相关产品推荐

