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

Pine Script止盈止损策略在禁交易时段异常触发问题排查

问题分析与解决方案

核心问题原因

你当前的止盈止损时间限制失效,是因为**strategy.exit 指令一旦在允许时段被调用,生成的挂单会持续生效直到成交或被主动取消**。即使进入禁止时段(04:00-07:00),之前生成的止盈止损挂单依然存在,若价格在此期间触发条件,就会执行平仓并触发警报。

而开平仓条件的时间限制有效,是因为这些指令仅在允许时段触发一次,不会留下持续生效的挂单。

解决思路

  1. 明确禁止时段:定义04:00-07:00为禁止触发止盈止损的窗口。
  2. 动态管理挂单:在进入禁止时段时取消所有止盈止损挂单;回到允许时段时重新生成挂单。
  3. 延迟触发处理:记录禁止时段内是否触发了止盈止损条件,若触发则在允许时段开始时执行平仓。

修改后的代码

//@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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:40:57