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

TradingView PineScript:数组循环趋势线的交叉顺序异常问题

PineScript实时K线多次趋势线穿越时计数器顺序混乱问题

我编写了一段TradingView PineScript脚本,通过数组存储历史枢轴点并循环绘制趋势线,使用varip类型的计数器记录价格穿越各趋势线的顺序。

问题现象

  • 当单根实时K线仅发生一次趋势线穿越时,计数器顺序正常(如1→2→3);
  • 当单根实时K线内出现多次穿越时,计数器记录的顺序会随机混乱,可能出现反向顺序(3→2→1)或完全无序(如2→1→3→4)。

已尝试的排查与调整

  1. 联系TradingView技术支持,建议将数组循环顺序从for array_index = 0 to 24调整为for array_index = 24 to 0,调整后部分场景恢复正常,但其他场景问题依旧;
  2. 已排除价格方向、趋势线类型(红色阻力线基于ta.pivothigh,绿色支撑线基于ta.pivotlow)对顺序混乱的影响;
  3. 暂未定位到问题根源,若能明确触发条件,可通过分支判断执行不同循环逻辑规避,但目前无法确定触发逻辑。

完整脚本代码

//@version=5
indicator("auto-trend-lines-varIP-testing", 
 overlay=true, max_lines_count=500, max_labels_count=500, max_boxes_count=500, max_bars_back=1500, precision=5)

leftbars = input.int(5, minval=1, title='Auto TrendLines: pivot detection: Left Bars')
rightbars = input.int(5, minval=1, title='Auto TrendLines: pivot detection: Right Bars')

// Pivots
ph = ta.pivothigh(high, leftbars, rightbars)
pl = ta.pivotlow(low, leftbars, rightbars)
// High
phv1 = ta.valuewhen(ph, high[rightbars], 0)
phb1 = ta.valuewhen(ph, bar_index[rightbars], 0)
phv2 = ta.valuewhen(ph, high[rightbars], 1)
phb2 = ta.valuewhen(ph, bar_index[rightbars], 1)
// Low
plv1 = ta.valuewhen(pl, low[rightbars], 0)
plb1 = ta.valuewhen(pl, bar_index[rightbars], 0)
plv2 = ta.valuewhen(pl, low[rightbars], 1)
plb2 = ta.valuewhen(pl, bar_index[rightbars], 1)

// TRENDLINE CODE
// --------------
get_slope(x1, x2, y1, y2) =>
    m = (y2 - y1) / (x2 - x1)
    m

get_y_intercept(m, x1, y1) =>
    b = y1 - m * x1
    b

get_y(m, b, ts) =>
    Y = m * ts + b
    Y

// Resistance variables
int res_x1 = na
float res_y1 = na
int res_x2 = na
float res_y2 = na

// Support variables
int sup_x1 = na
float sup_y1 = na
int sup_x2 = na
float sup_y2 = na

// Resistance
res_x1 := ph ? phb1 : res_x1[1]
res_y1 := ph ? phv1 : res_y1[1]
res_x2 := ph ? phb2 : res_x2[1]
res_y2 := ph ? phv2 : res_y2[1]

res_m = get_slope(res_x1, res_x2, res_y1, res_y2)
res_b = get_y_intercept(res_m, res_x1, res_y1)
res_y = get_y(res_m, res_b, bar_index)

// Support
sup_x1 := pl ? plb1 : sup_x1[1]
sup_y1 := pl ? plv1 : sup_y1[1]
sup_x2 := pl ? plb2 : sup_x2[1]
sup_y2 := pl ? plv2 : sup_y2[1]

sup_m = get_slope(sup_x1, sup_x2, sup_y1, sup_y2)
sup_b = get_y_intercept(sup_m, sup_x1, sup_y1)
sup_y = get_y(sup_m, sup_b, bar_index)

//// ARRAY - history trend lines ////
var int [] phb1_arr = array.new_int(25, 2)
var float [] phv1_arr = array.new_float(25, 2)
var int [] res_x1_arr = array.new_int(25, 2)
var float [] res_y1_arr = array.new_float(25, 2)
var int [] res_x2_arr = array.new_int(25, 2)
var float [] res_y2_arr = array.new_float(25, 2)

var int [] plb1_arr = array.new_int(25, 2)
var float [] plv1_arr = array.new_float(25, 2)
var int [] sup_x1_arr = array.new_int(25, 2)
var float [] sup_y1_arr = array.new_float(25, 2)
var int [] sup_x2_arr = array.new_int(25, 2)
var float [] sup_y2_arr = array.new_float(25, 2)

// Push pivots high and low into an array every time new pivots appear, array.push pushes element at the end of the array every time it "happens"
if ph
    array.insert(phb1_arr, 0, phb1)
    array.insert(phv1_arr, 0, phv1)
    array.insert(res_x1_arr, 0, res_x1)
    array.insert(res_y1_arr, 0, res_y1)
    array.insert(res_x2_arr, 0, res_x2)
    array.insert(res_y2_arr, 0, res_y2)
if pl
    array.insert(plb1_arr, 0, plb1)
    array.insert(plv1_arr, 0, plv1)
    array.insert(sup_x1_arr, 0, sup_x1)
    array.insert(sup_y1_arr, 0, sup_y1)
    array.insert(sup_x2_arr, 0, sup_x2)
    array.insert(sup_y2_arr, 0, sup_y2)

// Declare the coordinates varibales which will be assigned coordinates from array
int phb1_from_array = 0
float phv1_from_array = 0.0
int res_x1_from_array = 0
float res_y1_from_array = 0.0
int res_x2_from_array = 0
float res_y2_from_array = 0.0

int plb1_from_array = 0
float plv1_from_array = 0.0
int sup_x1_from_array = 0
float sup_y1_from_array = 0.0
int sup_x2_from_array = 0
float sup_y2_from_array = 0.0

// Initiate the array loop
for array_index = 0 to 24
    if array.size(phb1_arr) > 0 and array.size(phv1_arr) > 0 and array.size(plb1_arr) > 0 and array.size(plv1_arr) > 0 and array.size(res_x1_arr) > 0 and
     array.size(res_y1_arr) > 0 and array.size(res_x2_arr) > 0 and array.size(res_y2_arr) > 0 and array.size(sup_x1_arr) > 0 and 
     array.size(sup_y1_arr) > 0 and array.size(sup_x2_arr) > 0 and array.size(sup_y2_arr) > 0
        phb1_from_array := array.get(phb1_arr, array_index)
        phv1_from_array := array.get(phv1_arr, array_index)
        res_x1_from_array := array.get(res_x1_arr, array_index)
        res_y1_from_array := array.get(res_y1_arr, array_index)
        res_x2_from_array := array.get(res_x2_arr, array_index)
        res_y2_from_array := array.get(res_y2_arr, array_index)

        plb1_from_array := array.get(plb1_arr, array_index)
        plv1_from_array := array.get(plv1_arr, array_index)
        sup_x1_from_array := array.get(sup_x1_arr, array_index)
        sup_y1_from_array := array.get(sup_y1_arr, array_index)
        sup_x2_from_array := array.get(sup_x2_arr, array_index)
        sup_y2_from_array := array.get(sup_y2_arr, array_index)

    // Re-calculate the trend lines stuff per newly grabbed coordinates from array
    res_m_from_array = get_slope(res_x1_from_array, res_x2_from_array, res_y1_from_array, res_y2_from_array)
    res_b_from_array = get_y_intercept(res_m_from_array, res_x1_from_array, res_y1_from_array)
    res_y_from_array = get_y(res_m_from_array, res_b_from_array, bar_index)

    sup_m_from_array = get_slope(sup_x1_from_array, sup_x2_from_array, sup_y1_from_array, sup_y2_from_array)
    sup_b_from_array = get_y_intercept(sup_m_from_array, sup_x1_from_array, sup_y1_from_array)
    sup_y_from_array = get_y(sup_m_from_array, sup_b_from_array, bar_index)

    // Draw the trend lines per coordinates/calculations grabbed from array, previous and all the history ones captured by the array
    //high (red) | per ARRAY
    red_line_arr = line.new(phb1_from_array, phv1_from_array, bar_index, res_y_from_array, color=color.rgb(143, 54, 54, 50), 
     extend=extend.none, width=5)
    //high (red) | per ARRAY | cross catch
    red_line_arr_coordinates = line.get_price(red_line_arr, bar_index)
    //line.delete(pivot_connector_high_arr[1])

    //low (green) | per ARRAY
    green_line_arr = line.new(plb1_from_array, plv1_from_array, bar_index, sup_y_from_array, color=color.rgb(9, 134, 36, 50), 
     extend=extend.none, width=5)
    //low (green) | per ARRAY | cross catch
    green_line_arr_coordinates = line.get_price(green_line_arr, bar_index)
    //line.delete(pivot_connector_low_arr[1])

    varip int position_order_counter = 0
    ////////////////////////////////////////////////
    // POSITION OPEN | LONG (red)
    if open > red_line_arr_coordinates and low <= red_line_arr_coordinates and high > red_line_arr_coordinates
        red_line_arr_cross_lbl = label.new(bar_index, red_line_arr_coordinates, text="red(↑)|price:" + 
         str.tostring(math.round(red_line_arr_coordinates, 2)) + "|Count:" + 
         str.tostring(position_order_counter), style=label.style_label_up, 
         color=color.rgb(193, 122, 0), textcolor=color.white, size=size.normal)
        position_order_counter += 1
    ////////////////////////////////////////////////
    // POSITION OPEN | SHORT (red)
    if open < red_line_arr_coordinates and high >= red_line_arr_coordinates and low < red_line_arr_coordinates
        red_line_arr_cross_lbl = label.new(bar_index, red_line_arr_coordinates, text="red(↓)|price:" + 
         str.tostring(math.round(red_line_arr_coordinates, 2)) + "|Count:" + 
         str.tostring(position_order_counter), style=label.style_label_down, 
         color=color.rgb(193, 122, 0), textcolor=color.white, size=size.normal)
        position_order_counter += 1
    ////////////////////////////////////////////////
    ////////////////////////////////////////////////
    // POSITION OPEN | LONG (green)
    if open > green_line_arr_coordinates and low <= green_line_arr_coordinates and high > green_line_arr_coordinates
        green_line_arr_cross_lbl = label.new(bar_index, green_line_arr_coordinates, text="grn(↑)|price:" + 
         str.tostring(math.round(green_line_arr_coordinates, 2)) + "|Count:" + 
         str.tostring(position_order_counter), style=label.style_label_up, 
         color=color.rgb(70, 112, 201), textcolor=color.white, size=size.normal)
        position_order_counter += 1
    ////////////////////////////////////////////////
    // POSITION OPEN | SHORT (green)
    if open < green_line_arr_coordinates and high >= green_line_arr_coordinates and low < green_line_arr_coordinates
        green_line_arr_cross_lbl = label.new(bar_index, green_line_arr_coordinates, text="grn(↓)|price:" + 
         str.tostring(math.round(green_line_arr_coordinates, 2)) + "|Count:" + 
         str.tostring(position_order_counter), style=label.style_label_down, 
         color=color.rgb(70, 112, 201), textcolor=color.white, size=size.normal)
        position_order_counter += 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:20:48