如何为ta.highest/ta.lowest设置动态长度以实现追踪止损
问题原因
你遇到的报错是因为bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades -1)这个表达式可能返回NaN或小于等于0的值:
- 无持仓时,
strategy.opentrades为0,strategy.opentrades -1等于-1,调用entry_bar_index(-1)会返回NaN - 刚开仓的第一根K线,
bar_index等于entry_bar_index,计算结果为0,而ta.highest/ta.lowest要求长度必须大于0
修复后的代码
// 配置追踪止损比例 longTrailPerc = input.float(title='多头追踪止损比例(%)', minval=0.0, step=0.1, defval=2.2) * 0.01 shortTrailPerc = input.float(title='空头追踪止损比例(%)', minval=0.0, step=0.1, defval=2.2) * 0.01 // 初始化止损价格 longStopPrice = strategy.position_avg_price * 0.95 shortStopPrice = strategy.position_avg_price * 1.05 // 处理多头持仓的追踪止损 if strategy.position_size > 0 // 安全计算持仓以来的K线数量:确保长度>0,避免NaN entryBar = strategy.opentrades.entry_bar_index(strategy.opentrades - 1) barCount = bar_index - entryBar validLength = math.max(barCount, 1) // 强制长度至少为1 // 获取开仓以来的收盘价最高价 highestSinceEntry = ta.highest(close, validLength) if highestSinceEntry > strategy.position_avg_price * 1.02 stopValue = close * (1 - longTrailPerc) longStopPrice := math.max(stopValue, longStopPrice[1]) // 处理空头持仓的追踪止损 if strategy.position_size < 0 // 安全计算持仓以来的K线数量 entryBar = strategy.opentrades.entry_bar_index(strategy.opentrades - 1) barCount = bar_index - entryBar validLength = math.max(barCount, 1) // 获取开仓以来的收盘价最低价 lowestSinceEntry = ta.lowest(close, validLength) if lowestSinceEntry < strategy.position_avg_price * 0.98 stopValue = close * (1 + shortTrailPerc) shortStopPrice := math.min(stopValue, shortStopPrice[1])
关键修改说明
- 安全计算持仓K线数:
- 单独提取
entryBar变量,避免重复计算 - 用
math.max(barCount, 1)强制长度至少为1,彻底解决长度<=0的问题
- 单独提取
- 前置持仓判断:
- 外层的
strategy.position_size > 0已经确保有持仓,所以strategy.opentrades -1是有效的索引,但仍保留长度安全处理以防极端情况
- 外层的
- 修复逻辑漏洞:
- 原代码空头部分的判断条件逻辑有误,空头场景下需价格下跌到开仓价0.98以下才触发追踪止损,因此将
>修正为<(若你的业务逻辑确实需要大于,请忽略此修改)
- 原代码空头部分的判断条件逻辑有误,空头场景下需价格下跌到开仓价0.98以下才触发追踪止损,因此将
内容的提问来源于stack exchange,提问作者TheTowel31
相关产品推荐
相关产品推荐

