复盘模式下出现‘historical offset beyond historical buffer’错误求助
错误原因及修复办法
1. 「historical offset beyond historical buffer」错误根源
第47行的bar_index[highestBar]是问题核心。原代码里highestBar通过ta.highestbars(high, lookback)*-1得到正数偏移量,复盘时如果图表加载的历史数据不足,这个偏移量指向的bar会超出已加载的历史缓冲区范围,直接访问就触发越界错误。
2. 快速修复
把高低点对应的bar索引获取方式改成ta.valuewhen,它会自动在有效历史范围内取值,不会越界:
// 替换原代码中高低点bar的计算逻辑 highestBar := ta.valuewhen(high == ta.highest(high, lookback), bar_index, 0) lowestBar := ta.valuewhen(low == ta.lowest(low, lookback), bar_index, 0)
也可以加判断确保偏移量在有效范围内:
if highestBar < bar_index // 确保高点bar在当前bar之前存在 lineHigh := line.new(highestBar, highestHigh, bar_index, highestHigh, xloc=xloc.bar_index, width=2, color=labelBG)
简化版实现代码
原代码存在重复创建删除连线/标签的冗余操作,以下是逻辑更清晰、性能更优的简化版本:
//@version=6 indicator("高低点突破连线", overlay=true) // 输入参数 lookback = input.int(60, "回溯周期") day_offset = input.int(0, "日期偏移", maxval=0, tooltip="0=当天") time_start = input.time(timestamp("03:00"), "区间开始时间") time_end = input.time(timestamp("05:00"), "区间结束时间") line_color = input.color(color.red, "连线颜色") label_size = input.string("Small", "标签尺寸", options=["Tiny","Small","Normal","Large","Huge"]) // 计算目标日期的时间区间 target_date = timenow - day_offset * 86400000 session_start = timestamp(year(target_date), month(target_date), dayofmonth(target_date), hour(time_start), minute(time_start)) session_end = timestamp(year(target_date), month(target_date), dayofmonth(target_date), hour(time_end), minute(time_end)) // 标记是否在目标时间区间内 in_session = time >= session_start and time < session_end // 存储关键变量(用var仅初始化一次) var float session_high = na var float session_low = na var int high_bar = na var int low_bar = na var line high_line = na var line low_line = na var label high_label = na var label low_label = na // 区间结束时记录最终高低点,创建/更新连线和标签 if time == session_end // 获取区间内的高低点及对应bar session_high := ta.highest(high, lookback) high_bar := ta.valuewhen(high == session_high, bar_index, 0) session_low := ta.lowest(low, lookback) low_bar := ta.valuewhen(low == session_low, bar_index, 0) // 处理高点连线和标签 if na(high_line) high_line := line.new(high_bar, session_high, bar_index, session_high, width=2, color=line_color) high_label := label.new(bar_index, session_high, "高点", style=label.style_label_lower_right, size=label_size) else line.set_xy1(high_line, high_bar, session_high) line.set_xy2(high_line, bar_index, session_high) label.set_xy(high_label, bar_index, session_high) // 处理低点连线和标签 if na(low_line) low_line := line.new(low_bar, session_low, bar_index, session_low, width=2, color=line_color) low_label := label.new(bar_index, session_low, "低点", style=label.style_label_upper_right, size=label_size) else line.set_xy1(low_line, low_bar, session_low) line.set_xy2(low_line, bar_index, session_low) label.set_xy(low_label, bar_index, session_low) // 检测突破并更新连线终点 break_high = ta.crossover(high, session_high) break_low = ta.crossunder(low, session_low) // 高点突破逻辑 if break_high and not na(session_high) line.set_x2(high_line, bar_index) label.set_x(high_label, bar_index) else if not break_high and not na(session_high) and time > session_end line.set_x2(high_line, bar_index) label.set_x(high_label, bar_index) // 低点突破逻辑 if break_low and not na(session_low) line.set_x2(low_line, bar_index) label.set_x(low_label, bar_index) else if not break_low and not na(session_low) and time > session_end line.set_x2(low_line, bar_index) label.set_x(low_label, bar_index)
简化亮点
- 参数更直观:直接设置开始/结束时间,省去原代码复杂的时间偏移计算
- 对象复用:用
var声明连线和标签,仅在需要时更新,避免每bar重复创建删除的冗余操作 - 安全取值:用
ta.valuewhen获取高低点的bar索引,彻底解决历史偏移越界问题 - 逻辑清晰:仅在区间结束时记录最终高低点,减少不必要的计算量
内容的提问来源于stack exchange,提问作者Michael76
相关产品推荐
相关产品推荐

