为何设置flag后PineScript代码仍多次执行?
问题原因及解决方案
核心原因
timenow的实时性干扰:你使用的%timenow是脚本运行的实时系统时间,而非K线的时间戳。当开启calc_on_every_tick=true时,脚本每收到一个行情tick就会重新计算一次——只要实时时间超过1724003180000,这个条件就会持续为真。var变量可能被重置:var testalert = true确实会在脚本首次加载时仅初始化一次,但如果脚本因为重新编译、图表刷新、切换时间周期等原因重启,var变量会被重新赋值为true,导致逻辑再次触发。- 限价单的默认行为:即使
testalert被设为false,如果你的限价单(61000)始终未成交,strategy.order会在每个tick自动检查订单状态,若未成交则可能重复提交订单,这是策略订单的默认机制,和if块的执行次数无关。
解决方案
改用K线时间触发逻辑
如果你需要基于特定K线时间触发,用%time(当前K线开盘时间)或%timestamp()函数替代timenow,避免实时时间的持续干扰:var testalert = true // 示例:指定2024年8月18日0点的时间戳作为触发条件 if testalert and time > timestamp("2024-08-18T00:00:00") strategy.order("TestLong", strategy.long, limit=61000, qty=0.5, comment="ENTER-LONG_BINANCE-FUTURES_BTCUSDT_Ondrejs-Bot_30M_472398966e86382d84031451") label.new(x=bar_index, y = open, text=str.tostring(time), color=color.red, style=label.style_label_down, textcolor=color.white, size=size.large) testalert := false用订单状态替代内存flag
避免依赖易被重置的内存变量,直接通过策略的订单状态判断是否需要执行逻辑:// 当无持仓且时间条件满足时触发 if strategy.opentrades == 0 and time > timestamp("2024-08-18T00:00:00") strategy.order("TestLong", strategy.long, limit=61000, qty=0.5, comment="ENTER-LONG_BINANCE-FUTURES_BTCUSDT_Ondrejs-Bot_30M_472398966e86382d84031451") label.new(x=bar_index, y = open, text=str.tostring(time), color=color.red, style=label.style_label_down, textcolor=color.white, size=size.large)限制订单重复提交
新增一个变量标记订单是否已提交,彻底避免同一条件下的重复执行:var testalert = true var orderSubmitted = false if testalert and time > timestamp("2024-08-18T00:00:00") and not orderSubmitted strategy.order("TestLong", strategy.long, limit=61000, qty=0.5, comment="ENTER-LONG_BINANCE-FUTURES_BTCUSDT_Ondrejs-Bot_30M_472398966e86382d84031451") label.new(x=bar_index, y = open, text=str.tostring(time), color=color.red, style=label.style_label_down, textcolor=color.white, size=size.large) testalert := false orderSubmitted := true
内容的提问来源于stack exchange,提问作者Ondrej Tokar
相关产品推荐
相关产品推荐

