Pine Script止盈止损策略在禁交易时段异常触发问题排查
问题分析与解决方案
核心问题原因
你当前的止盈止损时间限制失效,是因为**strategy.exit 指令一旦在允许时段被调用,生成的挂单会持续生效直到成交或被主动取消**。即使进入禁止时段(04:00-07:00),之前生成的止盈止损挂单依然存在,若价格在此期间触发条件,就会执行平仓并触发警报。
而开平仓条件的时间限制有效,是因为这些指令仅在允许时段触发一次,不会留下持续生效的挂单。
解决思路
- 明确禁止时段:定义04:00-07:00为禁止触发止盈止损的窗口。
- 动态管理挂单:在进入禁止时段时取消所有止盈止损挂单;回到允许时段时重新生成挂单。
- 延迟触发处理:记录禁止时段内是否触发了止盈止损条件,若触发则在允许时段开始时执行平仓。
修改后的代码
//@version=5 strategy("TEST", overlay=true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, initial_capital = 50000, max_labels_count = 300) // --- Input parameters --- var longTrailPerc = 2 * 0.01 // --- Time range filter --- timeAllowed = input.session("0600-1900", "开平仓允许时段") timeIsAllowed = time(timeframe.period, timeAllowed + ":1234567") // 定义止盈止损允许时段(排除04:00-07:00) tpSlAllowedSession = input.session("0700-0400", "止盈止损允许时段") tpSlIsAllowed = time(timeframe.period, tpSlAllowedSession + ":1234567") // 禁止时段标记(04:00-07:00) isForbidden = not tpSlIsAllowed // === INPUT BACKTEST RANGE === i_from = input.time(defval = timestamp("20 Jun 2021 00:00 +0000"), title = "回测起始时间") i_thru = input.time(defval = timestamp("01 Mar 2025 00:00 +0000"), title = "回测结束时间") // === FUNCTION EXAMPLE === date() => time >= i_from and time <= i_thru // 回测时间窗口判断 // --- Entry and exit conditions --- long_condition = close > ta.ema(close,9) and date() exit_condition = close < ta.ema(close,18) and date() // Determine trail stop loss prices var float longStopPrice = 0.0 longStopPrice := if (strategy.position_size > 0) stopValue = close * (1 - longTrailPerc) math.max(stopValue, longStopPrice[1]) else 0 // 记录禁止时段内是否触发了止盈止损条件 var bool tp1TriggeredForbidden = false var bool tp2TriggeredForbidden = false var bool tp3TriggeredForbidden = false var bool slTriggeredForbidden = false // 计算止盈点位(转换为点数) percentAsPoints(pcnt) => strategy.position_size != 0 ? (pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na) tp1Level = strategy.position_avg_price + percentAsPoints(2) * syminfo.mintick tp2Level = strategy.position_avg_price + percentAsPoints(3) * syminfo.mintick tp3Level = strategy.position_avg_price + percentAsPoints(4) * syminfo.mintick // 检查禁止时段内的触发情况 if strategy.position_size > 0 and isForbidden tp1TriggeredForbidden := high >= tp1Level tp2TriggeredForbidden := high >= tp2Level tp3TriggeredForbidden := high >= tp3Level slTriggeredForbidden := low <= longStopPrice // 取消所有止盈止损挂单 strategy.cancel("PT1") strategy.cancel("PT2") strategy.cancel("PT3") strategy.cancel("TRLSTP") else // 允许时段:重置触发标记,重新生成挂单 tp1TriggeredForbidden := false tp2TriggeredForbidden := false tp3TriggeredForbidden := false slTriggeredForbidden := false if strategy.position_size > 0 strategy.exit("PT1", qty_percent = 30, profit = percentAsPoints(2), stop = longStopPrice, alert_profit = "PT1", alert_loss = "TRLSTP") strategy.exit("PT2", qty_percent = 30, profit = percentAsPoints(3), stop = longStopPrice, alert_profit = "PT2", alert_loss = "TRLSTP") strategy.exit("PT3", qty_percent = 30, profit = percentAsPoints(4), stop = longStopPrice, alert_profit = "PT3", alert_loss = "TRLSTP") strategy.exit("TRLSTP", profit = percentAsPoints(100), stop = longStopPrice, alert_loss = "TRLSTP") // 处理禁止时段触发的条件:在允许时段开始时执行平仓 if strategy.position_size > 0 and not isForbidden and isForbidden[1] if tp1TriggeredForbidden strategy.close("Long", qty_percent=30, comment="PT1_Delayed", alert_message="PT1") if tp2TriggeredForbidden strategy.close("Long", qty_percent=30, comment="PT2_Delayed", alert_message="PT2") if tp3TriggeredForbidden strategy.close("Long", qty_percent=30, comment="PT3_Delayed", alert_message="PT3") if slTriggeredForbidden strategy.close("Long", comment="TRLSTP_Delayed", alert_message="TRLSTP") // --- 原有开平仓逻辑 --- if long_condition and strategy.position_size == 0 and timeIsAllowed strategy.entry("Long", strategy.long) if exit_condition and strategy.position_size > 0 and timeIsAllowed strategy.close("Long", comment = "Exit1", qty = strategy.position_size)
关键修改说明
- 禁止时段管理:新增
isForbidden变量标记04:00-07:00窗口,进入该时段时取消所有止盈止损挂单,避免触发。 - 触发状态记录:用变量记录禁止时段内是否触及止盈止损点位,确保条件满足时在允许时段开始时执行。
- 延迟执行机制:当从禁止时段切换到允许时段时,检查之前的触发记录,执行对应的平仓操作并触发警报。
内容的提问来源于stack exchange,提问作者Ahmad Shehab
相关产品推荐
相关产品推荐

