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

Pine Script中box.new()的left参数索引越界问题求助

Pine Script box.new()索引越界错误的解决思路

错误信息:Study Error: box.new()的'left'参数的K线索引值(-1.0000)与当前K线索引差距过大,建议改用'time'。

该错误在K线数量较多的图表中触发,核心原因是代码中索引获取逻辑错误+赋值操作写错,导致box.new()的left参数出现无效的-1值。以下是具体解决思路:

1. 修复索引获取的核心问题

代码循环中使用array.shift(all_ohlc)移除数组首元素,之后再用array.indexof(all_ohlc, highvalue)查找价格对应的索引——此时highvalue已被移出数组,indexof必然返回-1,直接让boxindex变成无效值。

解决方法:不要只存储价格,同时保存价格对应的K线索引/时间,用结构体数组维持对应关系(Pine Script v5支持):

// 定义结构体存储价格、对应bar索引和时间
type PriceBar
    float price
    int barIdx
    int barTime

// 收集数据时同时记录价格与bar信息
if barstate.isconfirmed and bar_index >= min_barindex
    array.push(all_ohlc, PriceBar.new(open, bar_index, time))
    array.push(all_ohlc, PriceBar.new(close, bar_index, time))
    if not ignore_hl
        array.push(all_ohlc, PriceBar.new(high, bar_index, time))
        array.push(all_ohlc, PriceBar.new(low, bar_index, time))

// 排序时保持结构体对应关系
array.sort(all_ohlc, (a, b) => a.price > b.price ? 1 : -1)

后续循环中可直接从结构体中获取有效bar索引,不会出现找不到的情况。

2. 修正无效的赋值操作

代码中这两行是比较操作(==)而非赋值(:=),完全没起到限制boxindex的作用:

if bar_index - 50 > boxindex
    boxindex ==  bar_index - 50
if boxindex < 1
    boxindex ==  1

必须改成赋值操作才能生效:

if bar_index - 50 > boxindex
    boxindex := bar_index - 50
if boxindex < 1
    boxindex := 1

3. 按提示改用time定位(可选但推荐)

当图表K线数量极大时,bar_index可能超出Pine Script有效索引范围,改用time值定位更稳定。创建box时切换为xloc=xloc.bar_time:

box.new(currBar.barTime, boxtop, time, boxbottom, xloc=xloc.bar_time, bgcolor=color.new(zone_col, trans), border_color=color.new(zone_col, trans), extend=extend.right)

修改后的完整代码示例

//@version=5
indicator("Horizontal Support and Resistance zones", overlay=true, max_bars_back=75)

// 定义结构体存储价格、对应bar索引和时间
type PriceBar
    float price
    int barIdx
    int barTime

var PriceBar[] all_ohlc = array.new<PriceBar>()
var float[] box_array = array.new_float()
var float[] allvalues = array.new_float()

deviation_allowed_perc = input.float(5, "Percentage Deviation Allowed", 0.0, 100.0, 0.1)
min_count_perc = input.float(5, "Minimum touchpoints  as % of total bars", 1, 10, 0.1)
max_lookback = input.int(500, "Maximum bars lookback", 1, 1000, 1)
ignore_hl = input.bool(true, "Ignore High & Lows")
debug = input.bool(true, "Debug")
zone_col = input.color(color.new(color.aqua,0), 'Colors',inline='col')
trans  =  input.int(90,title="",inline='col',minval=0,maxval=100)

// 调试标签
var barsLabel = label.new(x=na, y=na, style=label.style_label_left,
     color=color.teal, textcolor=color.white, size=size.large)
     
var loopcount1 = 0
var loopcount2 = 0
var loopcount3 = 0
var loopcount4 = 0
     
var boxcount = 0
var boxindex = last_bar_index

var min_barindex = math.max(0, last_bar_index-max_lookback)
var min_count = (last_bar_index-min_barindex) * min_count_perc / 100

// 收集价格及对应bar信息
if barstate.isconfirmed and bar_index >= min_barindex
    array.push(all_ohlc, PriceBar.new(open, bar_index, time))
    array.push(all_ohlc, PriceBar.new(close, bar_index, time))
    if not ignore_hl
        array.push(all_ohlc, PriceBar.new(high, bar_index, time))
        array.push(all_ohlc, PriceBar.new(low, bar_index, time))
            
if barstate.islast
    // 按价格降序排序
    array.sort(all_ohlc, (a, b) => a.price > b.price ? 1 : -1)
    
    // 初始化变量
    highBar = array.shift(all_ohlc)
    boxtop = 0.0
    boxbottom = 0.0
    count = 0
    min_box_idx = last_bar_index

    for i = 0 to array.size(all_ohlc) - 1
        loopcount1 := loopcount1 + 1
        currBar = array.shift(all_ohlc)
        array.push(allvalues, currBar.price)
        
        // 判断价格是否在偏差范围内
        if highBar.price / currBar.price <= (1+deviation_allowed_perc/100)
            count := count + 1
            loopcount2 := loopcount2 + 1
            if count == 1
                boxtop := highBar.price
                min_box_idx := math.min(highBar.barIdx, min_box_idx)
            boxbottom := currBar.price
            min_box_idx := math.min(currBar.barIdx, min_box_idx)

        else
            loopcount3 := loopcount3 + 1
            if count >= min_count 
                loopcount4 := loopcount4 + 1
                boxcount := boxcount + 1
                // 修正赋值操作,限制box索引范围
                if bar_index - 50 > min_box_idx
                    min_box_idx := bar_index - 50
                if min_box_idx < 1
                    min_box_idx := 1
                array.push(box_array, boxtop)
                array.push(box_array, boxbottom)
                // 使用bar索引创建box,或改用time
                box.new(min_box_idx, boxtop, bar_index, boxbottom, xloc=xloc.bar_index, bgcolor=color.new(zone_col, trans), border_color=color.new(zone_col, trans), extend=extend.right)

            // 重置参数
            count := 0
            highBar := currBar
            
    // 更新调试标签
    labelText = "This " + syminfo.ticker + " chart has\n"
         + "Price bars: " + str.tostring(bar_index + 1, "##,###") + "\n"
         + "Min Bar Index: " + str.tostring(min_barindex) + "\n"
         + "Min Count: " + str.tostring(min_count) + "\n"
         + "Array size: " + str.tostring(array.size(all_ohlc)) + "\n"
         + "Loop1: " + str.tostring(loopcount1) + "\n"
         + "Loop2: " + str.tostring(loopcount2) + "\n"
         + "Loop3: " + str.tostring(loopcount3) + "\n"
         + "Loop4: " + str.tostring(loopcount4) + "\n"
         + "Boxcount: " + str.tostring(boxcount) + "\n"
         + "All Values: " + str.tostring(array.slice(allvalues, 0, 50)) + "\n"
         + "Box Values: " + str.tostring(str.substring(str.tostring(box_array), 0, 50)) + "\n"
    label.set_text(barsLabel, labelText)
    if debug
        label.set_xy(barsLabel, x=bar_index + 2, y=close*2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 17:50:29