PineScript 5策略延迟K线入场后仓位立即平仓问题求助
PineScript 5 延迟1根K线入场后立即平仓问题解决
问题根源
你的代码中,startprice、pm3、takeprofit、stoploss的计算依赖当前K线的goLong/goShort状态。当延迟1根K线入场时,触发信号的K线已经过去,当前K线的goLong/goShort为false,导致:
pm3计算错误(会取1 / math.sign(strategy.position_size),但刚入场时仓位还没更新,可能得到错误的方向)startprice取到的是更早的信号价格,和入场价格不匹配,导致止损止盈价格直接触发平仓
解决方案
需要在触发信号时,把对应的入场基准价和交易方向存储下来,延迟入场时调用这些存储的值来计算止损止盈,而不是依赖当前K线的信号状态。
修正后的MACD策略代码
//@version=5 strategy('Moving Regression Band Breakout strategy', shorttitle='MRBS', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=3) issl = input.bool(title='SL', inline='linesl1', group='Stop Loss / Take Profit:', defval=true) slpercent = input.float(title=', %', inline='linesl1', group='Stop Loss / Take Profit:', defval=5, minval=0.0) istrailing = input.bool(title='Trailing', inline='linesl1', group='Stop Loss / Take Profit:', defval=false) istp = input.bool(title='TP', inline='linetp1', group='Stop Loss / Take Profit:', defval=true) tppercent = input.float(title=', %', inline='linetp1', group='Stop Loss / Take Profit:', defval=2) // fastLength = input.int(title='Fast Length', defval=12) slowLength = input.int(title='Slow Length', defval=26) signalLength = input.int(title='Signal Length', defval=9) [macdLine, signalLine, _] = ta.macd(close, fastLength, slowLength, signalLength) longCondition = ta.crossover(macdLine, signalLine) shortCondition = ta.crossunder(macdLine, signalLine) // D-RSI signals goLong = longCondition goShort = shortCondition // 存储触发信号时的基准价和方向 var float stored_startprice = na var int stored_dir = 0 // 1=多, -1=空 var float position_size = 0.0 if strategy.position_size != 0 position_size := strategy.position_size var nb = 0 //Entrys if goLong if position_size < 0 strategy.close('Short', comment='Exit S', qty=math.abs(position_size)) nb := 1 // 记录多单信号的基准价和方向 stored_startprice := close stored_dir := 1 label.new(bar_index, low, 'C', xloc=xloc.bar_index, yloc=yloc.price, color=color.rgb(200, 250, 64), style=label.style_label_up, size=size.small) if nb[1] == 1 nb := 0 alert(syminfo.tickerid + ' Long Signal', alert.freq_once_per_bar_close) label.new(bar_index, low, 'L', xloc=xloc.bar_index, yloc=yloc.price, color=color.green, style=label.style_label_up, size=size.small) strategy.entry('Long', strategy.long) // 用存储的值计算多单止损止盈 long_tp = stored_startprice * (1 + stored_dir * tppercent * 0.01) long_sl = stored_startprice * (1 - stored_dir * slpercent * 0.01) strategy.exit(id='s/t L', from_entry='Long', stop=issl ? long_sl : na, limit=istp ? long_tp : na, alert_message='Close L') if goShort if position_size > 0 strategy.close('Long', comment='Exit L', qty=math.abs(position_size)) nb := 2 // 记录空单信号的基准价和方向 stored_startprice := close stored_dir := -1 label.new(bar_index, low, 'C', xloc=xloc.bar_index, yloc=yloc.price, color=color.rgb(209, 255, 3), style=label.style_label_up, size=size.small) if nb[1] == 2 nb := 0 alert(syminfo.tickerid + ' Short Signal', alert.freq_once_per_bar_close) label.new(bar_index, high, 'S', xloc=xloc.bar_index, yloc=yloc.price, color=color.rgb(255, 0, 0), style=label.style_label_down, size=size.small) strategy.entry('Short', strategy.short) // 用存储的值计算空单止损止盈 short_tp = stored_startprice * (1 + stored_dir * tppercent * 0.01) short_sl = stored_startprice * (1 - stored_dir * slpercent * 0.01) strategy.exit(id='s/t S', from_entry='Short', stop=issl ? short_sl : na, limit=istp ? short_tp : na, alert_message='Stop Loss S')
关键修改说明
- 新增
stored_startprice和stored_dir变量,在触发goLong/goShort信号时,记录当时的收盘价和交易方向。 - 延迟入场时,调用存储的基准价和方向计算止损止盈,避免依赖当前K线的信号状态。
- 将
strategy.exit移至延迟入场的代码块中,确保每次入场都使用对应信号的止损止盈参数。
内容的提问来源于stack exchange,提问作者redbluefan
相关产品推荐
相关产品推荐

