止损未完全离场:多止盈交易策略止损仅部分平仓求助
问题分析
你的问题根源在于多个strategy.exit指令同时生效:当止损触发时,虽然设置了qty_percent=100,但之前挂出的止盈订单仍然存在,容易引发平仓逻辑冲突;同时没有标记止损触发状态,后续K线里止盈代码还会继续执行,导致无法完全离场。
解决方案
通过全局状态标记+挂单清除的组合逻辑,实现止损触发后完全平仓且后续不再执行止盈:
1. 定义全局状态变量
在代码最顶部添加,用于跟踪止损是否已触发:
var bool slTriggered = false // 标记止损触发状态
2. 修改止损逻辑
替换原止损代码,触发时直接平仓并清除所有挂单,同时标记状态:
// 空头止损 if(ta.cross(close, current_top_box) and strategy.position_size < 0) strategy.cancel_all() // 清除所有未成交的止盈挂单 strategy.close("ShortSell", comment="Exit short SL") // 完全平仓空头持仓 slTriggered := true // 标记止损已触发 // 多头止损 if(ta.cross(close, current_bottom_box) and strategy.position_size > 0) strategy.cancel_all() // 清除所有未成交的止盈挂单 strategy.close("LongBuy", comment="Exit long SL") // 完全平仓多头持仓 slTriggered := true // 标记止损已触发
这里用strategy.close直接平仓,替代strategy.exit的挂单式平仓,避免和止盈订单冲突;同时用strategy.cancel_all()确保所有未成交的止盈挂单被清除。
3. 修改止盈逻辑
给所有止盈的if条件加上not slTriggered判断,确保止损触发后不再生成新的止盈挂单:
if(selectedCheackBoxTP1 and not slTriggered) strategy.exit ("Exit long TP1 " , "LongBuy", limit=entryPrice * (1 + tp1_percent), qty_percent=25) strategy.exit ("Exit short TP1", "ShortSell", limit=entryPrice * (1 - tp1_percent), qty_percent=25) if(selectedCheackBoxTP2 and not slTriggered) strategy.exit ("Exit long TP2", "LongBuy", limit=entryPrice * (1 + tp2_percent), qty_percent=25) strategy.exit ("Exit short TP2", "ShortSell", limit=entryPrice * (1 - tp2_percent), qty_percent=25) if(selectedCheackBoxTP3 and not slTriggered) strategy.exit ("Exit long TP3", "LongBuy", limit=entryPrice * (1 + tp3_percent), qty_percent=50) strategy.exit ("Exit short TP3", "ShortSell", limit=entryPrice * (1 - tp3_percent), qty_percent=50)
4. 重置止损状态(可选)
如果需要在新持仓建立时重置止损标记,在开仓逻辑后添加状态重置:
if(signals_view == "Buy/Sell") strategy.entry("LongBuy", strategy.long) slTriggered := false // 开仓后重置止损标记 if(signals_view == "All") strategy.entry("ShortSell", strategy.short) slTriggered := false // 开仓后重置止损标记
完整修正代码
//@version=5 strategy("3TP + 1SL Strategy", overlay=true) // 全局状态变量 var bool slTriggered = false // 假设你已定义以下变量(可根据实际调整) signals_view = input.string("Buy/Sell", "Signal View", options=["Buy/Sell", "All"]) current_top_box = input(1.2, "Current Top Box") current_bottom_box = input(0.8, "Current Bottom Box") selectedCheackBoxTP1 = input.bool(true, "Enable TP1") selectedCheackBoxTP2 = input.bool(true, "Enable TP2") selectedCheackBoxTP3 = input.bool(true, "Enable TP3") tp1_percent = input.float(0.01, "TP1 Percent", step=0.001) tp2_percent = input.float(0.02, "TP2 Percent", step=0.001) tp3_percent = input.float(0.04, "TP3 Percent", step=0.001) entryPrice = strategy.entry_price // 开仓逻辑 if(signals_view == "Buy/Sell") strategy.entry("LongBuy", strategy.long) slTriggered := false if(signals_view == "All") strategy.entry("ShortSell", strategy.short) slTriggered := false // 止损逻辑 if(ta.cross(close, current_top_box) and strategy.position_size < 0) strategy.cancel_all() strategy.close("ShortSell", comment="Exit short SL") slTriggered := true if(ta.cross(close, current_bottom_box) and strategy.position_size > 0) strategy.cancel_all() strategy.close("LongBuy", comment="Exit long SL") slTriggered := true // 止盈逻辑 if(selectedCheackBoxTP1 and not slTriggered) strategy.exit ("Exit long TP1 " , "LongBuy", limit=entryPrice * (1 + tp1_percent), qty_percent=25) strategy.exit ("Exit short TP1", "ShortSell", limit=entryPrice * (1 - tp1_percent), qty_percent=25) if(selectedCheackBoxTP2 and not slTriggered) strategy.exit ("Exit long TP2", "LongBuy", limit=entryPrice * (1 + tp2_percent), qty_percent=25) strategy.exit ("Exit short TP2", "ShortSell", limit=entryPrice * (1 - tp2_percent), qty_percent=25) if(selectedCheackBoxTP3 and not slTriggered) strategy.exit ("Exit long TP3", "LongBuy", limit=entryPrice * (1 + tp3_percent), qty_percent=50) strategy.exit ("Exit short TP3", "ShortSell", limit=entryPrice * (1 - tp3_percent), qty_percent=50)
关键说明
strategy.cancel_all():止损触发时立即清除所有未成交的止盈挂单,避免后续部分平仓slTriggered变量:从根源上阻止止损触发后,止盈逻辑继续生成新的挂单strategy.close:直接平仓对应持仓,确保100%离场,避免strategy.exit的挂单冲突
内容的提问来源于stack exchange,提问作者Alexander Kurinnoy
相关产品推荐
相关产品推荐

