使用ATR通道与valuewhen函数设置止损止盈的策略代码排查及咨询
策略代码检查与平仓异常问题解答
需求说明
- 自定义绘制ATR通道(上轨
upline、下轨bottomline) - 当某K线(bar1)收盘后触发10周期EMA与90周期EMA金叉的多单条件,在下一根K线(bar2)开盘价开仓
- 在bar2时保存当时的ATR上轨、下轨数值为静态值,不再随后续K线更新
- 将该静态值作为
strategy.exit的止损与止盈价格
提交代码
//@version=5 strategy("strategy learning", overlay=true, initial_capital=10000000) //Draw 2 EMA lines. ema1 = ta.ema(close, 10) ema2 = ta.ema(close, 90) plot(ema1, color=color.yellow) plot(ema2, color=color.blue) //Define a ATR band upline and bottom line. atr = ta.atr(14) upline = open + atr[1] bottomline = open - atr[1] plot(upline, color=color.white) plot(bottomline, color=color.white) //use "valuewhen()" function to grab the upline value and bottomline value at the moment of longcondition. It will be used for stoploss and takeprofit. longcondition = ta.crossover(ema1, ema2) longlimit = ta.valuewhen(longcondition, upline, 1) longstop = ta.valuewhen(longcondition, bottomline, 1) if(longcondition) strategy.entry("buy", strategy.long, qty=1) strategy.exit("buy", limit=longlimit, stop=longstop) //use "valuewhen()" function to grab the upline value and bottomline value at the moment of shortcondition. It will be used for stoploss and takeprofit. shortcondition = ta.crossunder(ema1, ema2) shortlimit = ta.valuewhen(shortcondition, bottomline, 1) shortstop = ta.valuewhen(shortcondition, upline, 1) if(shortcondition) strategy.entry("sell", strategy.short, qty=1) strategy.exit("sell", limit=shortlimit, stop=shortstop)
用户问题
- 请帮忙检查上述代码是否正确,是否符合我的需求?
- 我仔细查看回测订单列表后发现,许多订单并未按照预期价格平仓,此前咨询他人怀疑是滑点问题,但我无法验证,请求解答。
问题解答
问题1:代码正确性与需求匹配度检查
代码不完全符合需求,核心问题如下:
- 开仓时机错误:当前在
longcondition触发的K线(bar1)直接执行开仓,而非下一根K线(bar2)的开盘价。ta.crossover在bar1收盘时确认触发,此时执行strategy.entry会在bar1收盘价附近成交,不符合需求中“下一根K线开盘价开仓”的要求。 - 静态ATR值抓取错误:
- 多单逻辑中,
ta.valuewhen(longcondition, upline, 1)获取的是bar1的ATR上轨值,而非bar2的。因为longcondition在bar1触发,此时的upline对应bar1的open + atr[1],但需求要求保存的是bar2开盘时的ATR通道值。 - 空单部分存在相同的抓取时机错误。
- 多单逻辑中,
- 止损止盈绑定逻辑问题:当前
strategy.exit在每根K线都会执行,若旧订单未平仓,新信号触发时会覆盖旧的止损止盈价格,导致平仓价格混乱。
核心修正方向:
- 多单:用变量标记bar1的金叉信号,在bar2开盘时执行开仓,同时记录bar2的
upline和bottomline作为静态止盈止损价。 - 使用
var变量或ta.barssince跟踪开仓时机,确保仅在开仓时抓取一次静态ATR值。
问题2:订单未按预期价格平仓的原因
除滑点外,还有以下常见因素:
- 跳空缺口:行情跳空直接跳过止损/止盈价格时,订单会以跳空后的第一笔成交价格平仓。比如多单止盈价为100,下一根K线直接高开至105,订单会以105成交而非100。
- 止损止盈价格被覆盖:当前代码中
longlimit和longstop会在每次longcondition触发后更新,若旧订单未平仓,新信号会替换旧的止损止盈参数,导致平仓价格不符合预期。 - 回测填充模式设置:检查策略设置中的「订单填充模式」:
- 若选择「即时成交(Immediate or Cancel)」,止损/止盈价格在K线内未被触及则不会触发平仓;
- 若选择「市价成交(Market)」,则会在满足触发条件时以K线收盘价平仓。
- 滑点验证方法:在策略设置中开启固定滑点(如0.1),对比开启/关闭滑点时的平仓价格差异;同时查看回测的「订单详情」,里面会标注实际成交价格的触发原因(滑点、跳空等)。
内容的提问来源于stack exchange,提问作者tang_bohu
相关产品推荐
相关产品推荐

