Pine Script自定义时间间隔执行代码异常:日志频繁输出求助
解决Pine Script自定义时间框架下重复触发执行的问题
我想在TradingView指标里按自定义时间框架的新K线出现时执行代码,用Pine Script开发时遇到异常:初始能正确等待间隔,但之后开始每秒记录日志,不遵循指定时间框架。
我的代码:
tf = input.timeframe("30S", "Timeframe", group="RSI Settings") var int lastAlertTimeBull = na var int lastAlertTimeBear = na intervalMillis = timeframe.in_seconds(tf) * 1000 if barstate.isrealtime currentMillis = time(tf) if na(lastAlertTimeBull) lastAlertTimeBull := currentMillis else if (currentMillis - lastAlertTimeBull >= intervalMillis) log.info(str.format("{0} - {1}", currentMillis - lastAlertTimeBull, intervalMillis)) lastAlertTimeBull := currentMillis // Update the last alert time only once
实际行为
未按指定的30秒间隔记录日志,首次间隔后开始每秒输出:
[2024-12-07T12:10:18.434-05:00]: 30,000 - 30,000 [2024-12-07T12:10:19.305-05:00]: 30,000 - 30,000 [2024-12-07T12:10:20.236-05:00]: 30,000 - 30,000 [2024-12-07T12:10:21.435-05:00]: 30,000 - 30,000 [2024-12-07T12:10:22.334-05:00]: 30,000 - 30,000 [2024-12-07T12:10:23.206-05:00]: 30,000 - 30,000 [2024-12-07T12:10:24.405-05:00]: 30,000 - 30,000 [2024-12-07T12:10:25.335-05:00]: 30,000 - 30,000 [2024-12-07T12:10:26.234-05:00]: 30,000 - 30,000 [2024-12-07T12:10:27.434-05:00]: 30,000 - 30,000 [2024-12-07T12:10:29.235-05:00]: 30,000 - 30,000
预期行为
仅按指定时间间隔(如30秒)记录日志,而非每秒输出。
已尝试方案
- 仅在条件满足时更新
lastAlertTimeBull变量 - 使用
time(tf)进行时间戳对比 - 调试
lastAlertTimeBull的初始化逻辑
但问题依旧存在,首次间隔后日志输出频率异常升高。
问题原因
核心问题是time(tf)在实时行情下的特性:当当前K线属于目标时间框架的K线时,time(tf)返回的是该目标K线的开盘时间,不会随实时tick更新。当你更新lastAlertTimeBull为当前time(tf)后,后续每个tick都会触发currentMillis - lastAlertTimeBull >= intervalMillis的条件(因为两者相等,差值等于间隔),导致每秒重复执行。
修正方案
需要判断目标时间框架的K线是否刚刚形成新K线,而不是用时间差对比。可以通过ta.change(time(tf))来检测目标时间框架的K线切换,这是Pine Script中检测跨时间框架新K线的标准方法。
修正后的代码:
tf = input.timeframe("30S", "Timeframe", group="RSI Settings") var int lastAlertTimeBull = na // 检测目标时间框架的新K线形成 isNewHigherTFBar = ta.change(time(tf)) if barstate.isrealtime // 初始化首次时间 if na(lastAlertTimeBull) lastAlertTimeBull := time(tf) // 仅在新K线出现时执行逻辑 if isNewHigherTFBar intervalMillis = timeframe.in_seconds(tf) * 1000 log.info(str.format("{0} - {1}", time(tf) - lastAlertTimeBull, intervalMillis)) lastAlertTimeBull := time(tf)
代码说明
ta.change(time(tf))会在目标时间框架的K线切换时返回true,仅在新K线形成的第一个tick触发一次- 避免了用时间差对比导致的重复触发问题,确保逻辑只在每个目标时间框架K线出现时执行一次
- 保留了初始化逻辑,确保首次运行能正确记录初始时间
替代思路
如果需要在目标时间框架K线的特定阶段执行(比如K线收盘时),可以结合barstate.isconfirmed使用:
if barstate.isrealtime and barstate.isconfirmed if ta.change(time(tf)) // 执行收盘时的逻辑
内容的提问来源于stack exchange,提问作者H Rajabi
相关产品推荐
相关产品推荐

