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
相关产品推荐
相关产品推荐

