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
相关产品推荐
相关产品推荐

