Pine Script v6能否实现?如何基于数组值正确绘制折线
问题:Pine Script中收盘价排名折线与标签显示不一致
你尝试实现以下逻辑:
- 将过去N根K线的收盘价存入数组并排序
- 在图表上用标签展示每个价格对应的排名
- 绘制排名(1-10)的折线图
但折线显示的排名与标签中正确的排名不匹配,核心问题在于原代码通过时间数组匹配排名的逻辑有误——Pine Script是逐bar运行的,每个bar的排名应该直接计算并在当前bar输出,而非通过事后的时间索引匹配,这会导致数据关联错位。
修正后的代码
//@version=5 indicator("收盘价排名折线", overlay=false) lookBack = input.int(10, '回溯周期') src = input.source(close, "数据源") // 存储标签的数组 var array<label> labelArray = array.new<label>() // 清除旧标签 size = array.size(labelArray) if size > 0 for i = 0 to size - 1 label.delete(array.get(labelArray, i)) array.clear(labelArray) // 计算当前bar在过去lookBack窗口中的排名 float currentRank = na if bar_index >= lookBack - 1 // 构建当前窗口的价格数组 array<float> priceArray = array.new_float() for i = 0 to lookBack - 1 array.push(priceArray, src[i]) // 获取排序后的索引(升序,排名1为最低价格) int[] sortedIndices = array.sort_indices(priceArray, order.ascending) // 找到当前价格在数组中的位置,获取对应的排名 int currentIdx = array.indexof(priceArray, src[0]) if currentIdx != -1 // 遍历排序后的索引,找到当前索引对应的排名 for i = 0 to lookBack - 1 if array.get(sortedIndices, i) == currentIdx currentRank := i + 1 break // 绘制当前窗口内每个价格的标签 for i = 0 to lookBack - 1 float price = array.get(priceArray, i) // 计算该价格在当前窗口的排名 int priceRank = na for j = 0 to lookBack - 1 if array.get(sortedIndices, j) == i priceRank := j + 1 break newLabel = label.new(bar_index - i, price, text = str.format("Price: {0:.2f}\nRank: {1}", price, priceRank), color = color.white, textcolor = color.black, size = size.small, style = label.style_label_down) array.push(labelArray, newLabel) // 绘制排名折线 plot(currentRank, title = '当前Bar排名', color = color.orange, linewidth = 2)
关键改动说明
- 移除冗余数组:删掉了
timeArray和rankValues,直接在每个bar计算当前价格的排名并输出,从根源避免时间索引匹配带来的错位问题。 - 同步标签与排名逻辑:标签绘制时,为窗口内每个价格单独计算其在当前窗口的排名,确保标签显示的排名与折线的排名逻辑完全一致。
- 简化数组操作:优化了排序后排名的匹配逻辑,通过遍历排序索引直接获取对应排名,逻辑更清晰。
内容的提问来源于stack exchange,提问作者TV_123
相关产品推荐
相关产品推荐

