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

Indicator运行报错‘Internal Server Study Error’,求代码排查指导

排查Pine Script v5「Internal Server Study Error」问题及修复方案

以下是导致错误的核心问题及对应的修复步骤:

1. 未初始化symbolList数组

代码中直接调用array.push(symbolList, ...)但从未创建该数组,这会触发运行时错误。
修复:在添加标的前初始化字符串数组:

// 自选列表初始化
var array<string> symbolList = array.new_string()
array.push(symbolList,'BINANCE:ADAUSDT')
array.push(symbolList,'BINANCE:ATOMUSDT')
array.push(symbolList,'BINANCE:BNBUSDT')
array.push(symbolList,'BINANCE:BTCUSDT')
array.push(symbolList,'BINANCE:CHRUSDT')
array.push(symbolList,'BINANCE:COCOSUSDT')
array.push(symbolList,'BINANCE:COTIUSDT')
array.push(symbolList,'BINANCE:DGBUSDT')
array.push(symbolList,'BINANCE:DOGEUSDT')
array.push(symbolList,'BINANCE:EOSUSDT')

2. 错误调用time_close

time_close是Pine Script内置变量(当前K线的收盘时间),并非可传入参数的函数。原代码中time_close(timeperiod, syminfo.session, syminfo.timezone)属于语法错误,会触发服务器异常。
修复:通过request.security获取目标标的对应时间框架的收盘时间:

// 替换原entry_time行
entry_time = str.format('{0,date,yyyy.MM.dd HH:mm:ss}', request.security(symbol, timeperiod, time_close))

3. 高频创建表格导致资源过载

print_table函数在barstate.islast时每次tick都创建新表格,会导致内存泄漏和服务器压力过大。
修复:使用var关键字创建持久化表格,仅初始化一次,后续更新内容即可:

// 全局定义持久化表格
var table t = na

print_table() =>
    // 仅在表格未初始化时创建
    if na(t)
        t := table.new(position = tableLocation, columns = 5, rows = array.size(results), border_width = 1, border_color = color.black)
    // 先清除旧内容
    table.clear(t)
    // 重新设置行数(如果结果数量变化)
    table.set_row_count(t, array.size(results))
    // 遍历结果填充表格
    for i = 0 to array.size(results)-1
        eachResult = array.get(results, i)
        bg_color = i == array.size(results)-1 ? color.yellow : color.new(color.yellow,80)
        table.cell(table_id = t, column = 0, row = i, text = str.tostring(eachResult.s), bgcolor = bg_color)
        table.cell(table_id = t, column = 1, row = i, text = eachResult.sym, bgcolor = bg_color)
        table.cell(table_id = t, column = 2, row = i, text = str.tostring(eachResult.ent), bgcolor = bg_color)
        table.cell(table_id = t, column = 3, row = i, text = eachResult.rsn, bgcolor = bg_color)
        table.cell(table_id = t, column = 4, row = i, text = eachResult.dt, bgcolor = bg_color)

4. 其他逻辑优化(避免潜在错误)

  • 冗余数组初始化:将results数组的初始化简化为一行:
    var array<resultItem> results = array.new<resultItem>()
    
  • 结果序号错误:原代码中resultNo仅在最后一根K线更新,导致所有信号序号相同。改为每次添加新结果时递增序号,并在每次筛选前重置:
    // 在calculate_rsi_div函数中创建resultItem时
    resultNo += 1
    ri = resultItem.new(resultNo, symbol, entryPrice, entry_reason, entry_time)
    array.push(results, ri)
    
    // 在barstate.islast中重置序号
    resultNo := 0
    
  • 数组无限增长:在每次执行筛选前清空results数组,避免内存占用过高:
    if barstate.islast
        array.clear(results) // 清空旧结果
    
  • 遍历自选列表:原代码仅调用了单个标的,修复后遍历整个symbolList执行筛选:
    if screenerStrategy1
        // 遍历所有自选标的
        for sym in symbolList
            calculate_rsi_div(sym, timeframe)
    

完整修复后的代码

//@version=5
indicator(title = 'ps_screener', shorttitle = 'PS',overlay = true)

var int resultNo = 0     // 初始化结果序号
var int prevResultNo = 0 // 上一次执行的结果数量

// 定义结果对象类型
type resultItem
    int s
    string sym
    float ent
    string rsn
    string dt

// 初始化结果数组
var array<resultItem> results = array.new<resultItem>()

// 筛选策略设置
screeningStrategy = '=====筛选策略==============='
screenerStrategy1 = input.bool(title = 'RSI背离', defval = true, tooltip = '启用RSI背离筛选', group = screeningStrategy)

// 时间框架设置
timeframeHeader = '=======时间框架====================='
timeframe = input.timeframe(defval = '15', title = '时间框架', options = ['5','15','30','60','D','W','M'], group = timeframeHeader)

// 表格位置设置
tableLocationHeader = '=========表格位置==============='
location = input.string(defval = '顶部', title = '表格位置', options = ['顶部', '中部','底部'], group = tableLocationHeader)
tableLocation = location == '顶部' ? position.top_right : location == '中部' ? position.middle_right : position.bottom_right

// 全局持久化表格
var table t = na

// 打印表格函数
print_table() =>
    if na(t)
        t := table.new(position = tableLocation, columns = 5, rows = array.size(results), border_width = 1, border_color = color.black)
    table.clear(t)
    table.set_row_count(t, array.size(results))
    for i = 0 to array.size(results)-1
        eachResult = array.get(results, i)
        bg_color = i == array.size(results)-1 ? color.yellow : color.new(color.yellow,80)
        table.cell(table_id = t, column = 0, row = i, text = str.tostring(eachResult.s), bgcolor = bg_color)
        table.cell(table_id = t, column = 1, row = i, text = eachResult.sym, bgcolor = bg_color)
        table.cell(table_id = t, column = 2, row = i, text = str.tostring(eachResult.ent), bgcolor = bg_color)
        table.cell(table_id = t, column = 3, row = i, text = eachResult.rsn, bgcolor = bg_color)
        table.cell(table_id = t, column = 4, row = i, text = eachResult.dt, bgcolor = bg_color)

// 判断条件是否在指定K线范围内
inRange(cond) =>
    rangeUpper = 60
    rangeLower = 5
    bars = ta.barssince(cond == true)
    not na(bars) and rangeLower <= bars and bars <= rangeUpper

// RSI背离计算函数
calculate_rsi_div(symbol, timeperiod) =>
    len = 14 
    src = request.security(symbol, timeperiod, close)
    lbR = 5
    lbL = 5
    osc = ta.rsi(src, len)
    plFound = not na(ta.pivotlow(osc, lbL, lbR))
    phFound = not na(ta.pivothigh(osc, lbL, lbR))

    entry_reason = ""
    // 常规看涨背离
    oscHL = osc[lbR] > ta.valuewhen(plFound, osc[lbR], 1) and inRange(plFound[1])
    priceLL = request.security(symbol, timeperiod, low[lbR]) < ta.valuewhen(plFound, request.security(symbol, timeperiod, low[lbR]), 1)
    bullCond = priceLL and oscHL and plFound
    
    // 隐藏看涨背离
    oscLL = osc[lbR] < ta.valuewhen(plFound, osc[lbR], 1) and inRange(plFound[1])
    priceHL = request.security(symbol, timeperiod, low[lbR]) > ta.valuewhen(plFound, request.security(symbol, timeperiod, low[lbR]), 1)
    hiddenBullCond = priceHL and oscLL and plFound

    // 常规看跌背离
    oscLH = osc[lbR] < ta.valuewhen(phFound, osc[lbR], 1) and inRange(phFound[1])
    priceHH = request.security(symbol, timeperiod, high[lbR]) > ta.valuewhen(phFound, request.security(symbol, timeperiod, high[lbR]), 1)
    bearCond = priceHH and oscLH and phFound

    // 隐藏看跌背离
    oscHH = osc[lbR] > ta.valuewhen(phFound, osc[lbR], 1) and inRange(phFound[1])
    priceLH = request.security(symbol, timeperiod, high[lbR]) < ta.valuewhen(phFound, request.security(symbol, timeperiod, high[lbR]), 1)
    hiddenBearCond = priceLH and oscHH and phFound

    if bullCond
        entry_reason := '看涨'
    else if hiddenBullCond
        entry_reason := '隐性看涨'
    else if bearCond
        entry_reason := '看跌'
    else if hiddenBearCond
        entry_reason := '隐性看跌'

    entryPrice = request.security(symbol, timeperiod, open, ignore_invalid_symbol = true)

    if bullCond or hiddenBullCond or bearCond or hiddenBearCond
        entry_time = str.format('{0,date,yyyy.MM.dd HH:mm:ss}', request.security(symbol, timeperiod, time_close))
        resultNo += 1
        ri = resultItem.new(resultNo, symbol, entryPrice, entry_reason, entry_time)
        array.push(results, ri)

// 自选列表初始化
var array<string> symbolList = array.new_string()
array.push(symbolList,'BINANCE:ADAUSDT')
array.push(symbolList,'BINANCE:ATOMUSDT')
array.push(symbolList,'BINANCE:BNBUSDT')
array.push(symbolList,'BINANCE:BTCUSDT')
array.push(symbolList,'BINANCE:CHRUSDT')
array.push(symbolList,'BINANCE:COCOSUSDT')
array.push(symbolList,'BINANCE:COTIUSDT')
array.push(symbolList,'BINANCE:DGBUSDT')
array.push(symbolList,'BINANCE:DOGEUSDT')
array.push(symbolList,'BINANCE:EOSUSDT')

// 仅在最后一根K线执行筛选和表格更新
if barstate.islast
    array.clear(results) // 清空旧结果
    resultNo := 0 // 重置序号
    if screenerStrategy1
        // 遍历所有自选标的
        for sym in symbolList
            calculate_rsi_div(sym, timeframe)
    // 处理结果数量变化
    currentResultNo = array.size(results)
    if prevResultNo == 0
        prevResultNo := currentResultNo
    else if currentResultNo - prevResultNo > 1
        array.shift(results)
        prevResultNo := currentResultNo
    // 打印表格
    print_table()

内容的提问来源于stack exchange,提问作者Partha Sarkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 06:39:55