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

TradingView中security函数调用自定义函数的状态保持问题问询

在Pine Script的security函数中实现跨时间框架的状态保存

问题背景

我们构建的指标逻辑基于价格突破特定水平,需先在CTF(当前时间框架)验证,再应用到多个HTF(更高时间框架)。为复用逻辑编写了包含前期价格水平参数的自定义函数,该函数在CTF中运行正常,但通过request.security()调用时完全失效——HTF输出的价格水平与CTF重叠,仿佛未调用HTF。

排查过程中尝试多种方式获取HTF首根K线均未得到预期结果,编写的GetHTFHighestHigh()函数在security调用中也无法正常运行。核心需求是:如何在security调用的自定义函数中实现跨K线的数据状态保存?

测试代码

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/

//@version=5
indicator("Test HTF", overlay = true)

sHtfGroup = "HTF Settings"
useHTF1 = input.bool(title='Use HTF', defval=true, group=sHtfGroup, tooltip='Check this if you want to use the higher time frame.')
htfRes1 = input.timeframe(title='  HTF Resolution', defval='5', group=sHtfGroup, tooltip='Choose the higher time frame.')

//1st try - DOESN'T WORK
firstbar0()=>
    var barIndex = 0
    if(barIndex == 0)
        barIndex := bar_index
    barIndex

//2nd try - DOESN'T WORK
var TheBarNumber1 = 0
firstbar1(barNumber)=>
    barIndex = 0
    if(barNumber == 0)
        barIndex := bar_index
    barIndex

//3rd try - DOESN'T WORK
var TheBarNumber2 = 0
firstbar2(barNumber)=>
    var barIndex = 0
    if(barNumber == 0)
        barIndex := bar_index
    barIndex

//4th try - DOESN'T WORK
IsFirstBar = false
if barstate.isfirst
    IsFirstBar := true

firstbar3(firstBar)=>
    barIndex = 0
    if(firstBar)
        barIndex := bar_index
    barIndex

//5th try - DOESN'T WORK
HtfBarIndex = request.security(syminfo.tickerid, htfRes1, bar_index)
mn = 0
if barstate.isfirst
    mn := HtfBarIndex

firstbar4(firstBar)=>
    barIndex = 0
    if(firstBar == bar_index)
        barIndex := bar_index
    barIndex

//6th try - DOESN'T WORK
TheTime = 0
if barstate.isfirst
    TheTime := time
firstbar5(Time)=>
    barIndex = 0
    if(Time == time)
        barIndex := bar_index
    barIndex

//7th try - DOESN'T WORK
var IsFirstBar6 = false
if barstate.isfirst
    IsFirstBar6 := true
else
    IsFirstBar6 := false

firstbar6(firstBar)=>
    barIndex = 0
    if(firstBar)
        barIndex := bar_index
    barIndex


[HtfIsFirstBar, HtfFirstBarNumber0, HtfFirstBarNumber1, HtfFirstBarNumber2, HtfFirstBarNumber3, HtfFirstBarNumber4, HtfFirstBarNumber6, HtfBarNumber] = request.security(syminfo.tickerid, htfRes1, [barstate.isfirst, firstbar0(), firstbar1(TheBarNumber1), firstbar2(TheBarNumber2), firstbar3(IsFirstBar), firstbar4(mn), firstbar6(IsFirstBar6), bar_index])


plot(HtfIsFirstBar ? 1 : 0)
plot(HtfFirstBarNumber0)
plot(TheBarNumber1, color = color.red)
plot(HtfFirstBarNumber1, color = color.red)
plot(TheBarNumber2, color = color.lime)
plot(HtfFirstBarNumber2, color = color.lime)
plot(HtfFirstBarNumber3, color = color.purple)
plot(HtfFirstBarNumber4, color = color.fuchsia)
plot(HtfFirstBarNumber6, color = color.aqua)
plot(HtfBarNumber)

TheBarNumber1 := HtfFirstBarNumber1
TheBarNumber2 := HtfFirstBarNumber2

补充测试函数

GetHTFHighestHigh()=>
    var previousHigh = 0
    if(high > previousHigh)
        previousHigh := high
    previousHigh

问题根源

在Pine Script中,request.security()调用的函数内部的var变量,是绑定在**当前时间框架(CTF)**的上下文里,而非目标HTF的上下文。这意味着每次security调用时,函数内的var变量不会在HTF的K线周期内持续保存状态,而是跟着CTF的K线重置或复用错误的状态,导致HTF的计算结果和CTF重叠。

解决方法

方法1:将状态逻辑完全封装在security调用内部

要让状态变量绑定到HTF的上下文,必须在request.security()的参数表达式内部声明var变量并编写逻辑。以下是获取HTF首根K线和最高高点的示例:

//@version=5
indicator("HTF 状态保存示例", overlay=true)

htfRes = input.timeframe("D", "更高时间框架")

// 获取HTF首根K线索引
htfFirstBarIndex = request.security(syminfo.tickerid, htfRes, 
    var int firstBar = na
    if barstate.isfirst
        firstBar := bar_index
    firstBar
)

// 获取HTF历史最高高点
htfHighestHigh = request.security(syminfo.tickerid, htfRes, 
    var float hh = ta.low
    hh := math.max(hh, high)
    hh
)

plot(htfHighestHigh, color=color.new(color.blue, 0), title="HTF 最高高点")
plotshape(htfFirstBarIndex == bar_index, title="HTF首根K线", location=location.belowbar, color=color.green, style=shape.labelup, text="HTF首K")

方法2:使用varip实现多HTF状态隔离

如果需要同时处理多个不同的HTF,可使用varip(可变实例变量)创建字典结构,用时间框架字符串作为键来存储对应状态:

//@version=5
indicator("多HTF状态保存示例", overlay=true)

htfRes1 = input.timeframe("4H", "HTF1")
htfRes2 = input.timeframe("D", "HTF2")

// 封装HTF最高高点函数,用varip字典存储不同时间框架的状态
getHtfHighestHigh(tf)=>
    varip dict hhDict = na
    if na(hhDict)
        hhDict := dict.new()
    // 获取当前HTF的最高高点
    currentHh = request.security(syminfo.tickerid, tf, 
        var float hh = ta.low
        hh := math.max(hh, high)
        hh
    )
    // 将结果存入字典
    dict.set(hhDict, tf, currentHh)
    currentHh

// 获取两个HTF的最高高点
htf1Hh = getHtfHighestHigh(htfRes1)
htf2Hh = getHtfHighestHigh(htfRes2)

plot(htf1Hh, color=color.orange, title="4H 最高高点")
plot(htf2Hh, color=color.blue, title="日线 最高高点")

关键注意事项

  • 禁止在security外部声明状态变量再传入函数,必须在security的参数表达式内部声明var变量,确保状态绑定到HTF上下文。
  • varip变量是全局可变的,适合多HTF场景下的状态隔离,Pine Script中request.security是串行执行的,无需担心线程安全问题。
  • 测试HTF状态时,可通过barstate.islast或打印time戳验证,避免CTF和HTF的K线混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:01:04