优化PineScript效率:数组计算与绘图性能提升求助
优化Pine Script中RSI值频次统计与线条绘制效率问题
我写了一段Pine Script代码,用来统计RSI(14周期)四舍五入后各数值(0-100)的出现次数,再绘制对应线条。但当前代码极度冗长,运行效率极低,还经常崩溃。我知道只在最新K线计算能节省算力,但没找到实现方法。尝试用循环+数组来简化代码,但多次尝试都失败了,只能保留冗长版本。
原冗长代码
freq_50 = ta.cum(math.round(ta.rsi(close, 14)) == 50 ? 1 : 0) freq_49 = ta.cum(math.round(ta.rsi(close, 14)) == 49 ? 1 : 0) // 从100到0依次定义所有freq变量 ratio_sort = array.from(freq_100, freq_99, freq_98, freq_97, freq_96, freq_95, freq_94, freq_93, freq_92, freq_91, freq_90, freq_89, freq_88, freq_87, freq_86, freq_85, freq_84, freq_83, freq_82, freq_81, freq_80, freq_79, freq_78, freq_77, freq_76, freq_75, freq_74, freq_73, freq_72, freq_71, freq_70, freq_69, freq_68, freq_67, freq_66, freq_65, freq_64, freq_63, freq_62, freq_61, freq_60, freq_59, freq_58, freq_57, freq_56, freq_55, freq_54, freq_53, freq_52, freq_51, freq_50, freq_49, freq_48, freq_47, freq_46, freq_45, freq_44, freq_43, freq_42, freq_41, freq_40, freq_39, freq_38, freq_37, freq_36, freq_35, freq_34, freq_33, freq_32, freq_31, freq_30, freq_29, freq_28, freq_27, freq_26, freq_25, freq_24, freq_23, freq_22, freq_21, freq_20, freq_19, freq_18, freq_17, freq_16, freq_15, freq_14, freq_13, freq_12, freq_11, freq_10, freq_9, freq_8, freq_7, freq_6, freq_5, freq_4, freq_3, freq_2, freq_1, freq_0) ratio_max = array.max(ratio_sort, 0) line_50 = line.new(0, array.percentile_linear_interpolation(ratio_rank, 50), bar_index, array.percentile_linear_interpolation(ratio_rank, 50)) line.set_x1(line_50, bar_index + (math.round(ratio_max) - math.round(freq_50))) line.set_x2(line_50, bar_index + math.round(ratio_max)) line.delete(line_50[1]) line_49 = line.new(0, array.percentile_linear_interpolation(ratio_rank, 49), bar_index, array.percentile_linear_interpolation(ratio_rank, 49)) line.set_x1(line_49, bar_index + (math.round(ratio_max) - math.round(freq_49))) line.set_x2(line_49, bar_index + math.round(ratio_max)) line.delete(line_49[1]) // 再次从100到0依次绘制所有线条
我的尝试(无线条显示)
lineArr = array.new_line() ratio_max = math.max(array.percentile_linear_interpolation(ta.rsi(close, 14), 0), array.percentile_linear_interpolation(ta.rsi(close, 14), 100)) if barstate.isconfirmed for i = 100 to 0 freq = ta.cum(math.round(ta.rsi(close, 14)) == i ? 1 : 0) line_var = line.new(bar_index, array.percentile_linear_interpolation(ta.rsi(close, 14), i), bar_index + math.round(freq), array.percentile_linear_interpolation(ta.rsi(close, 14), i)) array.push(lineArr, line_var) for i = 1 to array.size(lineArr) - 1 line.delete(array.get(lineArr, i)) for i = 0 to array.size(lineArr) - 1 line_var = array.get(lineArr, i) line.set_x1(line_var, bar_index) line.set_x2(line_var, bar_index + math.round(line.get_x2(line_var) - bar_index))
优化后的解决方案
//@version=5 indicator("RSI频次统计与线条绘制", overlay=false) // 计算当前RSI四舍五入值 rsi_val = math.round(ta.rsi(close, 14)) // 初始化频次数组,存储0-100的出现次数(仅初始化一次) var freq_array = array.new_int(101, 0) // 仅在K线确认时更新频次,避免重复计算 if barstate.isconfirmed // 确保RSI值在合法范围内,防止数组越界 if rsi_val >= 0 and rsi_val <= 100 array.set(freq_array, rsi_val, array.get(freq_array, rsi_val) + 1) // 计算最大频次 ratio_max = array.max(freq_array) // 存储线条的数组,仅初始化一次 var line_array = array.new_line(101) // 循环更新0-100对应的线条 for i = 0 to 100 freq = array.get(freq_array, i) // 获取当前RSI数值对应的Y轴位置 y_val = array.percentile_linear_interpolation(ta.rsi(close, 14), i) current_line = array.get(line_array, i) // 线条不存在则创建,存在则直接更新位置 if na(current_line) current_line = line.new(bar_index, y_val, bar_index + math.round(freq), y_val, color=color.gray) array.set(line_array, i, current_line) else line.set_x1(current_line, bar_index + math.round(ratio_max - freq)) line.set_x2(current_line, bar_index + math.round(ratio_max))
核心优化点
- 数组替代单独变量:用一个数组存储0-100所有RSI值的频次,彻底删除冗余的变量定义代码。
- 限制计算时机:仅在
barstate.isconfirmed时更新频次,避免每根K线重复计算,大幅节省算力。 - 复用线条对象:初始化一次线条数组,后续仅更新线条位置,而非反复创建/删除线条,避免资源过载导致崩溃。
- 边界值校验:增加RSI值的范围检查,防止数组越界错误。
内容的提问来源于stack exchange,提问作者Oxelo
相关产品推荐
相关产品推荐

