Pine Script三条件交易策略无执行问题求助
Pine Script策略协同条件问题解决
问题描述
我编写了如下Pine Script策略,预期实现以下逻辑:
- 条件1:处于指定交易时段内
- 条件2:MA(移动平均线)交叉
- 条件3:仅当条件2触发后的x根K线内,RSI穿越指定区间时才执行交易;若RSI在x根K线后穿越,或在条件2触发前穿越,信号均无效。
但目前无法让所有条件协同生效:要么未等待条件3就执行交易,要么完全无交易执行。已多日寻找解决方案,恳请帮助。
原代码:
//@version=5 strategy("MS + RSI cross", overlay=true) // User Inputs // Group SMA sma_group = "SMA" sma1_length = input.int(10, title="SMA 1 Length", group=sma_group) sma2_length = input.int(35, title="SMA 2 Length", group=sma_group) // Group RSI rsi_group = "RSI" rsi_length = input.int(8, title="RSI Length", group=rsi_group) rsi_source = input.source(close, title="RSI Source", group=rsi_group) rsi_upper_band = input.float(55, title="RSI Upper Band", group=rsi_group) rsi_lower_band = input.float(45, title="RSI Lower Band", group=rsi_group) rsi_confirmation_window = input.int(3, title="RSI Confirmation Window", group=rsi_group) // Group Trading Hours trading_hours_group = "TRADING TIME" start_trading_hour = input.int(9, title="Start Trading Hour", group=trading_hours_group) stop_trading_hour = input.int(21, title="Stop Trading Hour", group=trading_hours_group) // Group SL/TP sl_tp_group = "SL & TP" sl_points = input.int(300, title="SL (points)", group=sl_tp_group) tp_points = input.int(450, title="TP (points)", group=sl_tp_group) // Calculating moving averages sma1 = ta.sma(close, sma1_length) sma2 = ta.sma(close, sma2_length) // Calculating RSI rsi_value = ta.rsi(rsi_source, rsi_length) // Trading Conditions in_trading_hours = hour >= start_trading_hour and hour <= stop_trading_hour // Long conditions long_sma_cross = ta.crossover(sma1, sma2) and in_trading_hours long_rsi_cross = false bars_since_long_sma_cross = ta.barssince(long_sma_cross) if bars_since_long_sma_cross > 0 and bars_since_long_sma_cross <= rsi_confirmation_window long_rsi_cross := ta.crossover(rsi_value, rsi_upper_band) // Visualize the rsi cross for debugging bgcolor(ta.crossover(rsi_value, rsi_upper_band) ? color.new(#37b027, 81): na) // Short conditions short_sma_cross = ta.crossunder(sma1, sma2) and in_trading_hours short_rsi_cross = false bars_since_short_sma_cross = ta.barssince(short_sma_cross) if bars_since_short_sma_cross > 0 and bars_since_short_sma_cross <= rsi_confirmation_window short_rsi_cross := ta.crossunder(rsi_value, rsi_lower_band) // Visualize the rsi cross for debugging bgcolor(ta.crossunder(rsi_value, rsi_lower_band) ? color.new(#c74949, 76): na) // Entry and Exit Logic if (long_sma_cross and long_rsi_cross) strategy.entry("Long", strategy.long) strategy.exit("Exit Long", "Long", stop=close - sl_points * syminfo.mintick, limit=close + tp_points * syminfo.mintick) if (short_sma_cross and short_rsi_cross) strategy.entry("Short", strategy.short) strategy.exit("Exit Short", "Short", stop=close + sl_points * syminfo.mintick, limit=close - tp_points * syminfo.mintick) // Plotting plot(sma1, color=color.rgb(243, 135, 33), title="SMA 1") plot(sma2, color=color.rgb(235, 213, 213), title="SMA 2") plotshape(long_sma_cross and long_rsi_cross, style=shape.labelup, location=location.belowbar, color=color.green, size=size.small, title="Long Signal") plotshape(short_sma_cross and short_rsi_cross, style=shape.labeldown, location=location.abovebar, color=color.red, size=size.small, title="Short Signal")
问题根源
原代码核心错误在于入场条件逻辑冲突:要求long_sma_cross(MA交叉)和long_rsi_cross(RSI穿越)在同一根K线触发,但实际需求是MA交叉后,RSI在后续x根K线内穿越,两个条件不可能同时满足。此外,long_rsi_cross仅判断当前K线是否满足RSI穿越,没有持续记录窗口内是否出现过有效信号。
修改后的完整代码
//@version=5 strategy("MS + RSI cross", overlay=true) // User Inputs // Group SMA sma_group = "SMA" sma1_length = input.int(10, title="SMA 1 Length", group=sma_group) sma2_length = input.int(35, title="SMA 2 Length", group=sma_group) // Group RSI rsi_group = "RSI" rsi_length = input.int(8, title="RSI Length", group=rsi_group) rsi_source = input.source(close, title="RSI Source", group=rsi_group) rsi_upper_band = input.float(55, title="RSI Upper Band", group=rsi_group) rsi_lower_band = input.float(45, title="RSI Lower Band", group=rsi_group) rsi_confirmation_window = input.int(3, title="RSI Confirmation Window", group=rsi_group) // Group Trading Hours trading_hours_group = "TRADING TIME" start_trading_hour = input.int(9, title="Start Trading Hour", group=trading_hours_group) stop_trading_hour = input.int(21, title="Stop Trading Hour", group=trading_hours_group) // Group SL/TP sl_tp_group = "SL & TP" sl_points = input.int(300, title="SL (points)", group=sl_tp_group) tp_points = input.int(450, title="TP (points)", group=sl_tp_group) // Calculating moving averages sma1 = ta.sma(close, sma1_length) sma2 = ta.sma(close, sma2_length) // Calculating RSI rsi_value = ta.rsi(rsi_source, rsi_length) // Trading Conditions in_trading_hours = hour >= start_trading_hour and hour <= stop_trading_hour // Long conditions long_sma_cross = ta.crossover(sma1, sma2) and in_trading_hours // 持续记录MA交叉窗口内是否出现过RSI上穿信号 var bool long_rsi_confirm = false bars_since_long_sma_cross = ta.barssince(long_sma_cross) // 重置确认标记:新MA交叉触发或超出窗口时重置 if long_sma_cross or bars_since_long_sma_cross > rsi_confirmation_window long_rsi_confirm := false // 窗口内检测到RSI上穿,标记确认 if bars_since_long_sma_cross >= 0 and bars_since_long_sma_cross <= rsi_confirmation_window if ta.crossover(rsi_value, rsi_upper_band) long_rsi_confirm := true // Short conditions short_sma_cross = ta.crossunder(sma1, sma2) and in_trading_hours // 持续记录MA交叉窗口内是否出现过RSI下穿信号 var bool short_rsi_confirm = false bars_since_short_sma_cross = ta.barssince(short_sma_cross) // 重置确认标记:新MA交叉触发或超出窗口时重置 if short_sma_cross or bars_since_short_sma_cross > rsi_confirmation_window short_rsi_confirm := false // 窗口内检测到RSI下穿,标记确认 if bars_since_short_sma_cross >= 0 and bars_since_short_sma_cross <= rsi_confirmation_window if ta.crossunder(rsi_value, rsi_lower_band) short_rsi_confirm := true // Entry and Exit Logic // 确认标记为真且在交易时段内时入场 if long_rsi_confirm and in_trading_hours strategy.entry("Long", strategy.long) strategy.exit("Exit Long", "Long", stop=close - sl_points * syminfo.mintick, limit=close + tp_points * syminfo.mintick) if short_rsi_confirm and in_trading_hours strategy.entry("Short", strategy.short) strategy.exit("Exit Short", "Short", stop=close + sl_points * syminfo.mintick, limit=close - tp_points * syminfo.mintick) // Plotting plot(sma1, color=color.rgb(243, 135, 33), title="SMA 1") plot(sma2, color=color.rgb(235, 213, 213), title="SMA 2") plotshape(long_rsi_confirm, style=shape.labelup, location=location.belowbar, color=color.green, size=size.small, title="Long Signal") plotshape(short_rsi_confirm, style=shape.labeldown, location=location.abovebar, color=color.red, size=size.small, title="Short Signal") // Debug visualization bgcolor(ta.crossover(rsi_value, rsi_upper_band) ? color.new(#37b027, 81): na) bgcolor(ta.crossunder(rsi_value, rsi_lower_band) ? color.new(#c74949, 76): na)
关键修改点说明
- 新增状态标记变量:用
var bool定义long_rsi_confirm和short_rsi_confirm,持续记录MA交叉窗口内是否出现过有效RSI穿越信号。 - 重置逻辑:新MA交叉触发或超出确认窗口时,重置状态标记,避免旧信号干扰后续交易。
- 入场条件调整:将入场条件改为判断状态标记为真,而非要求MA交叉和RSI穿越在同一K线,符合“MA交叉后x根K线内RSI穿越”的需求。
- 交易时段校验:入场时再次校验
in_trading_hours,确保交易仅在指定时段内执行。
内容的提问来源于stack exchange,提问作者Giuliano Arrigo
相关产品推荐
相关产品推荐

