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

解决TradingView多证券DIPlus值显示NaN问题的方案

TradingView多证券DI值表格展示问题与解决方案

需求说明

需要在TradingView中以表格形式展示5只证券的DI值,基于v4版本的《ADX and DI》指标编写Pine Script v5代码。初始实现中DIPlus值显示为NaN,经重构后解决该问题。

初始代码(存在NaN问题)

//@version=5
indicator("table-di-plus", overlay = true)
// ----------------------------------------------------------------------
type result
    float close_
    float high_
    float low_
    float DIPlus
// ----------------------------------------------------------------------
// parameters
// ----------------------------------------------------------------------
len = input(14)
th = input(20)    
// ----------------------------------------------------------------------
sym1 = input.symbol('PG',   'Symbol 1')
sym2 = input.symbol('MMM',  'Symbol 2')
sym3 = input.symbol('CYBR', 'Symbol 3')
sym4 = input.symbol('QCOM', 'Symbol 4')
sym5 = input.symbol('FTNT', 'Symbol 5')

obj1 = result.new()
obj2 = result.new()
obj3 = result.new()
obj4 = result.new()
obj5 = result.new()

obj1.close_ := request.security(sym1, '', close)
obj2.close_ := request.security(sym2, '', close)
obj3.close_ := request.security(sym3, '', close)
obj4.close_ := request.security(sym4, '', close)
obj5.close_ := request.security(sym5, '', close)

obj1.high_ := request.security(sym1, '', high)
obj2.high_ := request.security(sym2, '', high)
obj3.high_ := request.security(sym3, '', high)
obj4.high_ := request.security(sym4, '', high)
obj5.high_ := request.security(sym5, '', high)

obj1.high_ := request.security(sym1, '', low)
obj2.high_ := request.security(sym2, '', low)
obj3.high_ := request.security(sym3, '', low)
obj4.high_ := request.security(sym4, '', low)
obj5.high_ := request.security(sym5, '', low)
// ----------------------------------------------------------------------

calc(result obj) =>

    close_ = obj.close_
    high_ = obj.high_
    low_ = obj.low_

    TrueRange = math.max(math.max(high_-low_, math.abs(high_-nz(close_[1]))), math.abs(low_-nz(close_[1])))
    DirectionalMovementPlus = high_-nz(high_[1]) > nz(low_[1])-low_ ? math.max(high_-nz(high_[1]), 0): 0
    DirectionalMovementMinus = nz(low_[1])-low_ > high_-nz(high_[1]) ? math.max(nz(low_[1])-low_, 0): 0

    SmoothedTrueRange = 0.0
    SmoothedTrueRange := nz(SmoothedTrueRange[1]) - (nz(SmoothedTrueRange[1])/len) + TrueRange

    SmoothedDirectionalMovementPlus = 0.0
    SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - (nz(SmoothedDirectionalMovementPlus[1])/len) + DirectionalMovementPlus

    SmoothedDirectionalMovementMinus = 0.0
    SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - (nz(SmoothedDirectionalMovementMinus[1])/len) + DirectionalMovementMinus

    DIPlus  = SmoothedDirectionalMovementPlus  / SmoothedTrueRange * 100
    DIMinus = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100

    obj.DIPlus := DIPlus
// ----------------------------------------------------------------------
calc(obj1)
calc(obj2)
calc(obj3)
calc(obj4)
calc(obj5)
// ----------------------------------------------------------------------
var table tbl = table.new(
     position = position.top_right, 
     columns = 20, 
     rows = 10, 
     bgcolor = color.white, 
     frame_color = color.black, 
     frame_width = 2, 
     border_color = color.black, 
     border_width = 2)
// ----------------------------------------------------------------------
tbl.cell(0, 1, sym1)
tbl.cell(0, 2, sym2)
tbl.cell(0, 3, sym3)
tbl.cell(0, 4, sym4)
tbl.cell(0, 5, sym5)

tbl.cell(1, 1, str.tostring(obj1.DIPlus))
tbl.cell(1, 2, str.tostring(obj2.DIPlus))
tbl.cell(1, 3, str.tostring(obj3.DIPlus))
tbl.cell(1, 4, str.tostring(obj4.DIPlus))
tbl.cell(1, 5, str.tostring(obj5.DIPlus))
// ----------------------------------------------------------------------

优化后代码(解决NaN问题)

//@version=5
indicator("table-di-plus", overlay = true)
// ----------------------------------------------------------------------
// parameters
// ----------------------------------------------------------------------
len = input(14)
th = input(20)    
// ----------------------------------------------------------------------
di_screener_function() =>
    
    TrueRange = math.max(math.max(high-low, math.abs(high-nz(close[1]))), math.abs(low-nz(close[1])))
    DirectionalMovementPlus = high-nz(high[1]) > nz(low[1])-low ? math.max(high-nz(high[1]), 0): 0
    DirectionalMovementMinus = nz(low[1])-low > high-nz(high[1]) ? math.max(nz(low[1])-low, 0): 0

    SmoothedTrueRange = 0.0
    SmoothedTrueRange := nz(SmoothedTrueRange[1]) - (nz(SmoothedTrueRange[1])/len) + TrueRange

    SmoothedDirectionalMovementPlus = 0.0
    SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - (nz(SmoothedDirectionalMovementPlus[1])/len) + DirectionalMovementPlus

    SmoothedDirectionalMovementMinus = 0.0
    SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - (nz(SmoothedDirectionalMovementMinus[1])/len) + DirectionalMovementMinus

    DIPlus = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100
    DIMinus = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100

    [DIPlus, DIMinus]
    
// ----------------------------------------------------------------------
sym1 = input.symbol('PG',   'Symbol 1')
sym2 = input.symbol('MMM',  'Symbol 2')
sym3 = input.symbol('CYBR', 'Symbol 3')
sym4 = input.symbol('QCOM', 'Symbol 4')
sym5 = input.symbol('FTNT', 'Symbol 5')

[sym1_DIPlus, sym1_DIMinus] = request.security(sym1, '', di_screener_function())
[sym2_DIPlus, sym2_DIMinus] = request.security(sym2, '', di_screener_function())
[sym3_DIPlus, sym3_DIMinus] = request.security(sym3, '', di_screener_function())
[sym4_DIPlus, sym4_DIMinus] = request.security(sym4, '', di_screener_function())
[sym5_DIPlus, sym5_DIMinus] = request.security(sym5, '', di_screener_function())
// ----------------------------------------------------------------------
var table tbl = table.new(
     position = position.top_right, 
     columns = 20, 
     rows = 10, 
     bgcolor = color.white, 
     frame_color = color.black, 
     frame_width = 2, 
     border_color = color.black, 
     border_width = 2)
// ----------------------------------------------------------------------
tbl.cell(0, 1, sym1)
tbl.cell(0, 2, sym2)
tbl.cell(0, 3, sym3)
tbl.cell(0, 4, sym4)
tbl.cell(0, 5, sym5)

tbl.cell(1, 1, str.tostring(sym1_DIPlus))
tbl.cell(1, 2, str.tostring(sym2_DIPlus))
tbl.cell(1, 3, str.tostring(sym3_DIPlus))
tbl.cell(1, 4, str.tostring(sym4_DIPlus))
tbl.cell(1, 5, str.tostring(sym5_DIPlus))
// ----------------------------------------------------------------------

问题原因与解决方案

  • 问题根源:初始代码中,通过request.security仅获取单根K线的价格数据(close/high/low),无法获取完整的历史序列。计算DIPlus时需要调用close_[1]、high_[1]等历史值,这些值不存在导致计算结果为NaN。
  • 解决方案:将DI计算逻辑封装为独立函数di_screener_function,通过request.security在目标证券的完整数据上下文执行该函数。此时函数可以访问目标证券的全部历史序列数据,正常完成DIPlus的计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:35:57