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

Pine Script策略开发报错:array.get()索引-1越界问题求助

Pine Script 数组越界错误修复(第90行array.get()索引-1问题)

错误原因

第90行触发的Index -1 is out of bounds错误,核心原因是:
Pine Script会先计算条件中的所有子表达式,再执行整体判断。即使你加了array.size(highBoxArrayHTF) > 0的判断,代码仍会先执行array.get(highBoxArrayHTF, array.size(highBoxArrayHTF)-1)——当数组为空时,array.size()-1等于-1,直接触发索引越界。

修复方案

通过先判断数组状态,再安全获取元素的方式,避免空数组时执行array.get()。具体修改步骤如下:

1. 添加临时变量存储最后一个流动性盒子

在// Liquidity Break Conditions with Array Check注释上方,添加以下代码:

// 安全获取最后一个流动性盒子(空数组时返回na)
lastHighBox = array.size(highBoxArrayHTF) > 0 ? array.get(highBoxArrayHTF, array.size(highBoxArrayHTF)-1) : na
lastLowBox = array.size(lowBoxArrayHTF) > 0 ? array.get(lowBoxArrayHTF, array.size(lowBoxArrayHTF)-1) : na

2. 重构流动性突破条件

将原有的liquidityBreakShort和liquidityBreakLong条件替换为:

// Liquidity Break Conditions (安全版)
liquidityBreakShort = barstate.isconfirmed and not na(lastHighBox) and close > box.get_top(lastHighBox)
liquidityBreakLong = barstate.isconfirmed and not na(lastLowBox) and close < box.get_bottom(lastLowBox)

3. 修复警报模块的相同问题

将原有的警报代码替换为:

// Alerts for Liquidity Touch (Optional)
if barstate.isconfirmed and not na(lastHighBox)
    lastBuySideLiquidityBottom = box.get_bottom(lastHighBox)
    if high >= lastBuySideLiquidityBottom
        alert("Buy-Side Liquidity Touched", alert.freq_once_per_bar)

if barstate.isconfirmed and not na(lastLowBox)
    lastSellSideLiquidityTop = box.get_top(lastLowBox)
    if low <= lastSellSideLiquidityTop
        alert("Sell-Side Liquidity Touched", alert.freq_once_per_bar)

完整修复后代码

//@version=5
strategy("Market Structure Strategy with Liquidity, ChoCh, and Selectable MA", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10)

// User Inputs
internalLength = input.int(10, title="Internal Length")
externalLength = input.int(50, title="External Length")
length_option = input.string("ALL", title="Length Option", options=["INTERNAL", "EXTERNAL", "ALL","NONE"])
swingSize_swing = input.int(5, title="Swing Size")
liquidityLengthOption = input.string("MID", title="Liquidity Length Option", options=["SHORT", "MID", "LONG"])
liquidityswingLength = input.int(30)
liquidityLength = switch liquidityLengthOption
    "SHORT" => 10
    "MID" => 28
    "LONG" => 50

// Selectable Moving Average Parameters
ma_type = input.string("SMA", title="Moving Average Type", options=["SMA", "EMA", "WMA", "VWMA"])
ma_length = input.int(20, title="Moving Average Length")

// Function to select the moving average based on user input
get_moving_average(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "WMA" => ta.wma(source, length)
        "VWMA" => ta.vwma(source, length)
        => na  // Default to avoid errors if no type matches

// Apply the selected moving average
selected_ma = get_moving_average(close, ma_length, ma_type)

// Plot the selected moving average for visualization
plot(selected_ma, title="Selected Moving Average", color=color.blue, linewidth=2)

// Liquidity Detection Parameters
showInternalMS = (length_option == "INTERNAL" or length_option == "ALL" ) and length_option != "NONE"
showExternalMS = (length_option == "EXTERNAL" or length_option == "ALL" or length_option != "NONE")

// Adjusted Left Bars Based on Timeframe
adjustedLeftBars(tf, baseLeftBars) =>
    tf_seconds = timeframe.in_seconds(tf)
    if tf_seconds <= 60 
        10
    else if tf_seconds <= 300 
        20
    else
        baseLeftBars

leftBars = adjustedLeftBars("D", liquidityLength)  // Daily timeframe adjustment
secondLeftBars = adjustedLeftBars("W", liquidityLength)  // Weekly timeframe adjustment

// Liquidity detection variables
var highLineArrayHTF = array.new_line()
var lowLineArrayHTF  = array.new_line()
var highBoxArrayHTF  = array.new_box()
var lowBoxArrayHTF   = array.new_box()

// Persistent variables for liquidity levels
var float lastBuySideLiquidityTop = na
var float lastSellSideLiquidityBottom = na

// Detect liquidity pivots
pivotHighHTF  = ta.pivothigh(high, leftBars, leftBars)
pivotLowHTF   = ta.pivotlow(low, leftBars, leftBars)

// Populate highBoxArrayHTF and lowBoxArrayHTF when pivots are detected
if (pivotHighHTF)
    highBox = box.new(bar_index - leftBars, high[pivotHighHTF], bar_index, high)  // Create box for pivot high
    array.push(highBoxArrayHTF, highBox)

if (pivotLowHTF)
    lowBox = box.new(bar_index - leftBars, low[pivotLowHTF], bar_index, low)  // Create box for pivot low
    array.push(lowBoxArrayHTF, lowBox)

// Track Highs and Lows for ChoCh
var float recentHigh = na
var float recentLow = na

// Identify highs and lows for ChoCh
if ta.highestbars(high, swingSize_swing) == 0
    recentHigh := high
if ta.lowestbars(low, swingSize_swing) == 0
    recentLow := low

// ChoCh Conditions
chochToDowntrend = close < recentLow and ta.highestbars(low, swingSize_swing) > 0
chochToUptrend = close > recentHigh and ta.lowestbars(high, swingSize_swing) > 0

// 安全获取最后一个流动性盒子(空数组时返回na)
lastHighBox = array.size(highBoxArrayHTF) > 0 ? array.get(highBoxArrayHTF, array.size(highBoxArrayHTF)-1) : na
lastLowBox = array.size(lowBoxArrayHTF) > 0 ? array.get(lowBoxArrayHTF, array.size(lowBoxArrayHTF)-1) : na

// Liquidity Break Conditions (安全版)
liquidityBreakShort = barstate.isconfirmed and not na(lastHighBox) and close > box.get_top(lastHighBox)
liquidityBreakLong = barstate.isconfirmed and not na(lastLowBox) and close < box.get_bottom(lastLowBox)

// Combined Entry Conditions (including Moving Average filter)
longEntryCondition = chochToUptrend and liquidityBreakLong and close > selected_ma
shortEntryCondition = chochToDowntrend and liquidityBreakShort and close < selected_ma

// Stop Loss Levels
longStopLoss = recentLow - swingSize_swing
shortStopLoss = recentHigh + swingSize_swing

// Execute Trades
if (longEntryCondition)
    strategy.entry("Long Entry", strategy.long, stop=longStopLoss)

if (shortEntryCondition)
    strategy.entry("Short Entry", strategy.short, stop=shortStopLoss)

// Configure trail stop level with input options (optional)
longTrailPerc = input.float(3, title="Trail Long Loss (%)",
     minval=0.0, step=0.1) * 0.01

shortTrailPerc = input.float(3, title="Trail Short Loss (%)",
     minval=0.0, step=0.1) * 0.01

// Alerts for Liquidity Touch (Optional)
if barstate.isconfirmed and not na(lastHighBox)
    lastBuySideLiquidityBottom = box.get_bottom(lastHighBox)
    if high >= lastBuySideLiquidityBottom
        alert("Buy-Side Liquidity Touched", alert.freq_once_per_bar)

if barstate.isconfirmed and not na(lastLowBox)
    lastSellSideLiquidityTop = box.get_top(lastLowBox)
    if low <= lastSellSideLiquidityTop
        alert("Sell-Side Liquidity Touched", alert.freq_once_per_bar)

内容的提问来源于stack exchange,提问作者Amon Hinson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:29:53