Pine Script策略:部分止盈与追踪止损共存失效问题求助
Pine Script 部分止盈与追踪止损共存问题解决
在Pine Script策略中同时设置部分止盈和追踪止损时,两者无法同时生效:将追踪止损代码放在部分止盈前,追踪止损有效但部分止盈失效;反之则部分止盈有效但追踪止损失效。以下是原问题代码:
//@version=5 strategy("BASE", overlay=true, initial_capital = 1000) //######################################################################################## TIME RANGE ###################################################################################### FromDay=input.int(defval=18,title="FromDay",minval=1,maxval=31) FromMonth=input.int(defval=8,title="FromMonth",minval=1,maxval=12) FromYear=input.int(defval=2021,title="FromYear",minval=2016) dateCond = (time >= timestamp('GMT+10', FromYear,FromMonth, FromDay, 00, 00)) //######################################################################################## TIME RANGE ###################################################################################### //######################################################################################## STRATEGY ######################################################################################## // 3 rsi strategy , when all of them are overbought we sell, and vice versa if ta.crossover(ta.ema(close,20),ta.ema(close,100)) and dateCond strategy.entry("BUY", strategy.long) if ta.crossunder(ta.ema(close,20),ta.ema(close,100)) and dateCond strategy.entry("SELL", strategy.short) //######################################################################################## STRATEGY ######################################################################################## //######################################################################################## TRAILING STOP AND TAKE PROFIT ################################################################# //Trailing Stop longTrailPerc = input.float(title='Trailing Long Loss (%)', minval=0.0, step=0.1, defval=1) * 0.01 shortTrailPerc = input.float(title='Trailing Short Loss (%)', minval=0.0, step=0.1, defval=1) * 0.01 longStopPrice = 0.0 shortStopPrice = 0.0 longStopPrice := if strategy.position_size > 0 stopValue = close * (1 - longTrailPerc) math.max(stopValue, longStopPrice[1]) else 0 shortStopPrice := if strategy.position_size < 0 stopValue = close * (1 + shortTrailPerc) math.min(stopValue, shortStopPrice[1]) else 999999 //################################################################### Partial Take Profit ############################ percentAsPoints(pcnt) => strategy.position_size != 0 ? math.round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na) lossPnt = percentAsPoints(2) strategy.exit("x1", qty_percent = 50, profit = percentAsPoints(5), comment = "Loss")//, loss = lossPnt) strategy.exit("x2", qty_percent = 25, profit = percentAsPoints(20), comment = "Loss")//, loss = lossPnt) strategy.exit("x3", qty_percent = 25, profit = percentAsPoints(30), comment = "Loss")//, loss = lossPnt) strategy.exit("x4", profit = percentAsPoints(4), comment = "Loss")//, loss = lossPnt) profitPercent(price) => posSign = strategy.position_size > 0 ? 1 : strategy.position_size < 0 ? -1 : 0 (price - strategy.position_avg_price) / strategy.position_avg_price * posSign * 100 p1 = plot(profitPercent(high), style=plot.style_linebr, title = "open profit % upper bound") p2 = plot(profitPercent(low), style=plot.style_linebr, title = "open profit % lower bound") fill(p1, p2, color = color.red) //####################################################################### Execution ################################ if strategy.position_size > 0 strategy.exit(id='Trailing', stop=longStopPrice, alert_message="close BTCUSDT a=usdm") if strategy.position_size < 0 strategy.exit(id='Trailing', stop=shortStopPrice, alert_message="close BTCUSDT a=usdm")
问题根源
Pine Script中,同一仓位的多个strategy.exit指令会互相覆盖:每个退出指令默认绑定最近的入场单,重复的退出逻辑会抢占仓位控制权,导致其中一方失效。原代码中独立的追踪止损退出指令和部分止盈指令冲突,无法同时生效。
修复方案
将部分止盈与追踪止损整合到同一套退出逻辑中,给每个分批止盈指令绑定对应的入场ID和实时追踪止损价,消除指令冲突。修改后的完整代码如下:
//@version=5 strategy("BASE", overlay=true, initial_capital = 1000) // 时间范围设置 FromDay=input.int(defval=18,title="FromDay",minval=1,maxval=31) FromMonth=input.int(defval=8,title="FromMonth",minval=1,maxval=12) FromYear=input.int(defval=2021,title="FromYear",minval=2016) dateCond = (time >= timestamp('GMT+10', FromYear,FromMonth, FromDay, 00, 00)) // 入场逻辑 if ta.crossover(ta.ema(close,20),ta.ema(close,100)) and dateCond strategy.entry("BUY", strategy.long) if ta.crossunder(ta.ema(close,20),ta.ema(close,100)) and dateCond strategy.entry("SELL", strategy.short) // 追踪止损配置 longTrailPerc = input.float(title='多单追踪止损(%)', minval=0.0, step=0.1, defval=1) * 0.01 shortTrailPerc = input.float(title='空单追踪止损(%)', minval=0.0, step=0.1, defval=1) * 0.01 // 初始化并更新追踪止损价 var float longStopPrice = 0.0 var float shortStopPrice = 999999.0 longStopPrice := strategy.position_size > 0 ? math.max(close * (1 - longTrailPerc), longStopPrice[1]) : 0.0 shortStopPrice := strategy.position_size < 0 ? math.min(close * (1 + shortTrailPerc), shortStopPrice[1]) : 999999.0 // 百分比转点数工具函数 percentAsPoints(pcnt) => strategy.position_size != 0 ? math.round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na) // 整合部分止盈与追踪止损:每个分批止盈绑定对应入场单和追踪止损 strategy.exit("x1", "BUY", qty_percent = 50, profit = percentAsPoints(5), stop = longStopPrice, comment = "50%止盈/追踪止损") strategy.exit("x2", "BUY", qty_percent = 25, profit = percentAsPoints(20), stop = longStopPrice, comment = "25%止盈/追踪止损") strategy.exit("x3", "BUY", qty_percent = 25, profit = percentAsPoints(30), stop = longStopPrice, comment = "25%止盈/追踪止损") strategy.exit("x1_short", "SELL", qty_percent = 50, profit = percentAsPoints(5), stop = shortStopPrice, comment = "50%止盈/追踪止损") strategy.exit("x2_short", "SELL", qty_percent = 25, profit = percentAsPoints(20), stop = shortStopPrice, comment = "25%止盈/追踪止损") strategy.exit("x3_short", "SELL", qty_percent = 25, profit = percentAsPoints(30), stop = shortStopPrice, comment = "25%止盈/追踪止损") // 持仓盈利百分比可视化 profitPercent(price) => posSign = strategy.position_size > 0 ? 1 : strategy.position_size < 0 ? -1 : 0 (price - strategy.position_avg_price) / strategy.position_avg_price * posSign * 100 p1 = plot(profitPercent(high), style=plot.style_linebr, title = "持仓盈利上限(%)") p2 = plot(profitPercent(low), style=plot.style_linebr, title = "持仓盈利下限(%)") fill(p1, p2, color = color.red)
关键修改点
- 绑定入场ID:给每个
strategy.exit指定对应的入场单ID(如"BUY"、"SELL"),避免退出指令绑定混乱 - 整合止损逻辑:将实时计算的追踪止损价作为
stop参数传入每个分批止盈指令,确保所有分批仓位都受止损保护 - 变量持久化:用
var关键字初始化止损价变量,避免每次重新计算时重置数值 - 消除冲突:移除独立的追踪止损退出指令,避免多个退出指令抢占仓位控制权
内容的提问来源于stack exchange,提问作者xBruV
相关产品推荐
相关产品推荐

