Inside Candle策略SL退出异常求助(15分钟日内交易)
开发的基于Inside Candle的15分钟日内交易策略出现SL(止损)退出异常:有时退出精准,有时未能及时退出,有时退出错误,甚至刚进场就立刻退出。已在代码中绘制SL水平线,但问题仍未解决,恳请协助排查。
策略代码如下:
//@version=5 strategy("Inside Candle ", overlay=true,slippage = 3,commission_type=strategy.commission.percent,commission_value = 0.05,initial_capital = 10000,calc_on_order_fills = true,calc_on_every_tick = true,pyramiding = 1000,backtest_fill_limits_assumption = 2,close_entries_rule = "FIFO") //=============================================Entry and exit Timings (9:30 a.m. to 2:30 p.m.)=========================================================== string sessionInput = input.session("0915-1415", "Session") string daysInput = input.string("1234567", tooltip = "1 = Sunday, 7 = Saturday") sessionString = sessionInput + ":" + daysInput inSession = not na(time(timeframe.period, sessionString)) bgcolor(inSession ? color.rgb(178, 181, 190, 96) : na) //================================================Detecting Inside Candle and ema=========================================================== //Defining Inside Candle and 50ema ema = ta.ema(close,150) plot(ema,"ema",color.orange,linewidth = 2) IC = (high <= high[1] and low >= low[1]) //==================================================Defining Entry Conditions===================================================================================================== //LONG above 50ema and SHORT below 50ema ICwithemaLONG = IC and (close > ema) ICwithemaSHORT = IC and (close < ema) //Previous Candle is an Inside Candle = IC[1] and // High of current candle is greater than previous (Inside) candle = high > high[1] //and close of previous(Inside) candle > ema = close[1] > ema then ====> LONG EntryCandleLONG = IC[1] and (high[0] > high[1]) and (close[1] > ema) EntryCandleSHORT = IC[1] and (low[0] < low[1]) and (close[1] < ema) //================================================Detecting Inside Candle high and low==================================================================== //Detecting Inside Candle High and Low h = high + (1 * syminfo.mintick) l = low - (1 * syminfo.mintick) var float IC_high = na var float IC_low = na var float IC_high1 = na var float IC_low1 = na //Getting high and low to the Inside Candle previous to Entry Candle if (EntryCandleLONG == true) IC_high := high[1] IC_low := low[1] if (EntryCandleSHORT == true) IC_high1 := high[1] IC_low1 := low[1] LONG_SL = IC_low - (1 * syminfo.mintick) SHORT_SL = IC_high1 + (1 * syminfo.mintick) plot(LONG_SL,color = color.red,linewidth = 2) plot(SHORT_SL,color = color.green,linewidth = 2) //======================================================================Coloring Bars=========================================== barcolor(ICwithemaLONG ? color.white : na) barcolor(ICwithemaSHORT ? color.white : na) barcolor(EntryCandleLONG ? color.yellow : na) barcolor(EntryCandleSHORT ? color.yellow : na) //=====================================================================Money Management========================================================================================== initial_capital = input(defval = 10000 , title = "initial capital") percentRisk = input(defval = 0.01,title = "Risk per trade") LONG_Position_Size = ((initial_capital * percentRisk) / (h - l)) SHORT_Position_Size = ((initial_capital * percentRisk) / (h - l)) //=============================================================Entry restricted to only next 1 bar================================================================================================================ is_long = strategy.position_size > 0 cancel_long_order = barstate.isconfirmed and ICwithemaLONG[1] and not is_long is_short = strategy.position_size > 0 cancel_short_order = barstate.isconfirmed and ICwithemaSHORT[1] and not is_short //==============================================LONG Entry and Exit Conditions========================================================================== if (ICwithemaLONG and inSession) strategy.entry("LONG",strategy.long,stop = h,qty = LONG_Position_Size) stoploss = LONG_SL target = h + ((h-l)*3) strategy.exit("LONG Exit",from_entry = "LONG",stop = stoploss,limit = target) if (cancel_long_order) strategy.cancel("LONG") //Exiting trade at 3:15 p.m. if (hour==15 and minute==00) strategy.close_all("Day Close" ) //==============================================SHORT Entry and Exit Conditions========================================================================== if (ICwithemaSHORT and inSession) strategy.entry("SHORT",strategy.short,stop = l,qty = SHORT_Position_Size) STOPLOSS = SHORT_SL TARGET = l - ((h-l) * 3) strategy.exit("SHORT SL",from_entry="SHORT",stop = STOPLOSS,limit = TARGET) //Only taking entry on next candle of inside candle and avoid entries in later candles if (cancel_short_order) strategy.cancel("SHORT") //Exiting trade at 3:15 p.m. if (hour==15 and minute==00) strategy.close_all("Day Close")
核心问题排查与修复建议
1. 止损值赋值时机错误
当前LONG_SL/SHORT_SL依赖EntryCandleLONG/EntryCandleSHORT触发时更新的IC_low/IC_high1,但ICwithemaLONG触发下单时,EntryCandleLONG还未成立(后者是下一根K线的条件),此时IC_low仍为初始na或历史旧值,导致止损参数完全错误,进而引发异常退出。
修复方案:在ICwithemaLONG/ICwithemaSHORT触发时,直接保存当前Inside Candle的高低点,作为后续止损和目标价的计算依据:
// 新增变量保存Inside Candle的高低点 var float ic_long_h = na var float ic_long_l = na var float ic_short_h = na var float ic_short_l = na if (ICwithemaLONG) ic_long_h := high ic_long_l := low if (ICwithemaSHORT) ic_short_h := high ic_short_l := low // 重新计算止损和目标价 LONG_SL = ic_long_l - syminfo.mintick SHORT_SL = ic_short_h + syminfo.mintick // 仓位计算也使用保存的Inside Candle高低点 LONG_Position_Size = ((initial_capital * percentRisk) / (ic_long_h - ic_long_l)) SHORT_Position_Size = ((initial_capital * percentRisk) / (ic_short_h - ic_short_l))
2. 空头仓位判断逻辑错误
代码中is_short = strategy.position_size > 0完全错误,空头仓位应判断为strategy.position_size < 0,导致cancel_short_order条件失效,无法正确取消未成交的空头订单,进而引发重复下单或异常持仓。
修复方案:
is_short = strategy.position_size < 0 cancel_short_order = barstate.isconfirmed and ICwithemaSHORT[1] and not is_short
3. 止损单绑定时机问题
当前在ICwithemaLONG触发时直接调用strategy.exit,但此时strategy.entry的止损单尚未成交,且止损值可能未完成初始化,导致止损单参数错误。建议将strategy.exit移到订单成交后,或使用条件判断确保止损值有效时再挂单。
修复方案:
// 多单逻辑修改 if (ICwithemaLONG and inSession) strategy.entry("LONG", strategy.long, stop = h, qty = LONG_Position_Size) // 单独处理止损和止盈,确保止损值有效 if (strategy.position_size > 0 and not na(LONG_SL)) stoploss = LONG_SL target = ic_long_h + ((ic_long_h - ic_long_l)*3) strategy.exit("LONG Exit", from_entry = "LONG", stop = stoploss, limit = target)
4. 时间退出条件不准确
hour==15 and minute==00在15分钟周期下,只有当K线刚好在15:00闭合时才会触发,可能错过提前收盘的时机。建议使用session时间函数精准判断:
exitSession = time(timeframe.period, "1500-1500") if (not na(exitSession)) strategy.close_all("Day Close")
5. 变量初始化问题
使用var定义的IC_high/IC_low等变量只会初始化一次,若未及时更新会保留历史旧值,导致后续止损计算错误。建议去掉var关键字,或在每次交易完成后重置变量。
内容的提问来源于stack exchange,提问作者Trading Records

