多时间框架随机相对强弱指标交叉策略

RSI STOCH RSI MTF TRENDING MARKETS STOP LOSS MULTI-STAGE TP
创建日期: 2025-06-05 13:13:32 最后修改: 2025-06-05 13:13:32
复制: 0 点击次数: 84
avatar of ianzeng123 ianzeng123
2
关注
62
关注者

多时间框架随机相对强弱指标交叉策略 多时间框架随机相对强弱指标交叉策略

策略概述

多时间框架随机相对强弱指标交叉策略是一个基于Stochastic RSI(随机相对强弱指标)的复合交易系统,该策略采用5分钟和15分钟两个时间周期的数据进行交易信号生成和确认。这是一个完整的交易系统,包含明确的入场条件、止损控制以及分阶段获利方案。该策略特别关注市场的超买/超卖状态,通过捕捉价格动量的转变时机实现盈利。

该策略在5分钟图表上操作,但会参考15分钟图表的数据来确认交易信号,体现了多时间框架分析的深度。它对多头和空头交易采用了不同的参数设置,暗示其在设计上偏向适应整体看涨的市场环境。

策略原理

该策略的核心原理基于Stochastic RSI指标的交叉信号,结合了多时间框架确认机制来过滤低质量信号。具体工作流程如下:

  1. 初始触发信号(5分钟时间框架)

    • 多头信号:当5分钟图表上Stoch RSI的K线向上穿越D线,且在穿越时的K值低于指定的触发水平(stoch_5min_k_long_trigger)。
    • 空头信号:当5分钟图表上Stoch RSI的K线向下穿越D线,且在穿越时的K值高于指定的触发水平(stoch_5min_k_short_trigger)。
  2. 高级确认(15分钟时间框架)

    • 在5分钟初始信号触发后,策略会在设定的等待窗口(wait_window_5min_bars)内寻求15分钟时间框架的确认。
    • 多头确认:15分钟Stoch RSI的K线必须严格大于其D线,且15分钟K值必须低于stoch_15min_long_entry_level设定值。
    • 空头确认:15分钟Stoch RSI的K线必须严格小于其D线,且15分钟K值必须高于stoch_15min_short_entry_level设定值。
  3. 重复信号过滤

    • 策略实施了冷却期机制(min_bars_between_signals),在同方向信号之间必须经过指定数量的K线才会考虑新信号。
  4. 仓位管理

    • 开仓位置锁定:当已持有未平仓位时,策略不会生成新的入场信号。
    • 止损设置:基于入场K线的低点(对多头)或高点(对空头)设置,如果后续K线的收盘价突破此水平,则触发止损。
    • 止损检查优先于获利检查。
  5. 两阶段获利机制

    • 第一阶段(TP1):平掉50%的仓位,通过以下两种方式之一触发:
      • 优先方式A(极端K值):如果5分钟或15分钟Stoch K值超过extreme_long_tp_level(多头)或低于extreme_short_tp_level(空头)。
      • 优先方式B(条件性5分钟交叉+15分钟K值反转):当5分钟Stoch RSI的K/D交叉发生(多头时K向下穿越D;空头时K向上穿越D),并且得到15分钟Stoch K值”反转”的确认(当前15分钟K < 前一15分钟K对于多头;当前15分钟K > 前一15分钟K对于空头)。
    • 第二阶段(TP2):平掉剩余50%的仓位,仅在TP1已触发后激活,当5分钟或15分钟Stoch K值再次达到相同的极端水平时执行。

策略优势

  1. 多时间框架确认机制

    • 通过结合5分钟和15分钟时间框架的信号,该策略减少了假信号,提高了交易质量。较短的时间框架提供入场机会,而较长的时间框架提供趋势确认,这种方法可以有效过滤短期市场噪音。
  2. 超买/超卖条件的精确定位

    • Stochastic RSI比传统RSI更敏感,能更早地捕捉到价格动量的变化。策略利用这一特性在价格即将反转时进行交易,提高了入场时机的准确性。
  3. 分阶段止盈策略

    • 两阶段止盈机制允许交易者锁定部分利润,同时保留剩余仓位以捕捉更大的行情。这种方法平衡了风险和收益,特别适合波动性较大的市场。
  4. 自适应偏好设置

    • 策略参数可以调整以反映市场偏好(如当前策略对多头更为宽松),使其能够适应不同的市场环境和交易偏好。
  5. 完整的风险管理

    • 明确的止损机制基于入场K线的极值,为每笔交易提供了可量化的风险控制。止损检查优先于获利检查,确保风险控制始终是首要考虑因素。
  6. 重复信号过滤

    • 通过实施信号冷却期,避免在短时间内过度交易相同方向,减少了交易成本并提高了信号质量。

策略风险

  1. 参数敏感性

    • 该策略依赖多个阈值参数,如各种触发水平和确认阈值。不适当的参数设置可能导致过多的假信号或错过关键交易机会。应通过回测在不同市场条件下优化这些参数。
  2. 止损点位可能较宽

    • 基于入场K线极值的止损可能在某些情况下较为宽松,尤其是在波动较大的市场中。这可能导致单笔交易的潜在损失超出预期。考虑设置最大止损限制以避免过度风险暴露。
  3. 市场条件依赖性

    • Stochastic RSI在区间震荡市场中表现良好,但在强趋势市场中可能产生过早的反转信号。该策略可能在快速单向行情中表现不佳,因为价格可能持续超买或超卖状态而不反转。
  4. 对多头偏向

    • 当前策略配置显示对多头交易的偏好,这在熊市环境下可能导致过度交易或不合适的多头信号。应根据市场环境调整参数以保持平衡。
  5. 15分钟确认延迟

    • 等待15分钟时间框架确认可能导致入场延迟,在快速市场中可能错过理想入场点。在极端波动的市场中,这种延迟可能会显著影响策略表现。

策略优化方向

  1. 动态止盈机制

    • 当前的固定百分比止盈可以升级为基于ATR(Average True Range)的动态止盈,或者实施尾随止损机制,以便在趋势行情中捕捉更多利润。特别是对于第二阶段的止盈,考虑使用波动率或趋势强度调整的止盈水平。
  2. 市场状态自适应

    • 引入市场状态检测机制(如ADX指标评估趋势强度),使策略能根据不同的市场环境自动调整参数。例如,在强趋势市场中放宽反转条件,在震荡市场中收紧这些条件。
  3. 多指标协同确认

    • 整合额外的技术指标如MACD、布林带或移动平均线作为辅助确认工具。多指标共振可以提高信号的可靠性,减少假突破。
  4. 风险敞口优化

    • 实施动态头寸规模管理,基于当前波动率或最近交易表现调整每笔交易的风险敞口。此外,可以添加最大止损幅度限制以防止极端损失。
  5. 多时间框架层级扩展

    • 考虑增加第三个时间框架(如1小时或4小时)来提供更高层次的市场背景分析,特别是对于趋势确认和主要支撑/阻力位识别。
  6. 交易时段过滤

    • 添加交易时段过滤器,避免在流动性不足或波动不规则的市场时段交易。例如,可以限制在市场开盘和收盘前后的高波动期间进行交易。

总结

多时间框架随机相对强弱指标交叉策略是一个结构完善的交易系统,通过多时间框架分析和严格的信号确认流程提高交易质量。该策略的核心优势在于其全面的入场条件和风险管理系统,特别是两阶段止盈机制允许在保持部分头寸追踪趋势的同时锁定利润。

然而,该策略的效果高度依赖于参数设置和市场条件。在震荡市场中可能表现良好,但在强趋势或高波动环境下可能需要调整。建议交易者通过历史回测优化参数,并考虑添加市场状态检测和动态止盈机制等功能来增强其适应性。

该策略最适合具有编程知识的中级到高级交易者,他们能够理解并定制这些复杂的交易规则。通过适当的参数调整和风险管理,这个系统可以成为日内和短期交易者工具箱中的有价值组成部分,特别是那些专注于捕捉市场动量变化的交易者。

策略源码
/*backtest
start: 2024-06-05 00:00:00
end: 2025-06-04 00:00:00
period: 2d
basePeriod: 2d
exchanges: [{"eid":"Futures_Binance","currency":"DOGE_USDT"}]
*/

// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Archertoria

//@version=6
strategy("System 0530 - Stoch RSI Strategy v13 SL-Priority TP-Reversal", 
         overlay=true, 
         default_qty_type=strategy.percent_of_equity, 
         default_qty_value=100, 
         calc_on_order_fills=false, 
         process_orders_on_close=true,
         margin_short=50) 

// --- Original Indicator Input Parameters ---
g_stoch = "Stochastic RSI Parameters"
rsi_len = input.int(14, "RSI Period", minval=1, group=g_stoch)
stoch_rsi_len = input.int(14, "Stochastic of RSI Period (K Period for Stoch)", minval=1, group=g_stoch)
stoch_k_smooth = input.int(3, "Stochastic %K Smoothing (D Period for Stoch)", minval=1, group=g_stoch)
stoch_d_smooth = input.int(3, "Stochastic %D Smoothing (Smoothing for final D)", minval=1, group=g_stoch)

g_signal = "Signal Trigger and Confirmation Parameters"
stoch_5min_k_long_trigger = input.float(40.0, "5-min Stoch K Long Trigger Level (K must be ≤ this value)", minval=0, maxval=100, step=0.1, group=g_signal, tooltip="On the 5-minute chart, when the K line crosses above the D line, the K value at that time must be less than or equal to this setting to initiate a long signal wait.")
stoch_5min_k_short_trigger = input.float(70.0, "5-min Stoch K Short Trigger Level (K must be ≥ this value)", minval=0, maxval=100, step=0.1, group=g_signal, tooltip="On the 5-minute chart, when the K line crosses below the D line, the K value at that time must be greater than or equal to this setting to initiate a short signal wait.")
stoch_15min_long_entry_level = input.int(50, "15-min Stoch K Long Confirmation Threshold (K must be below this value)", minval=0, maxval=100, group=g_signal, tooltip="On the 15-minute chart, for final long confirmation, the 15-minute K line value must be below this setting.")
stoch_15min_short_entry_level = input.int(70, "15-min Stoch K Short Confirmation Threshold (K must be above this value)", minval=0, maxval=100, group=g_signal, tooltip="On the 15-minute chart, for final short confirmation, the 15-minute K line value must be above this setting.")
wait_window_5min_bars = input.int(7, "Number of 5-min bars to wait for 15-min signal", minval=1, group=g_signal, tooltip="After a 5-minute signal is issued, wait for 15-minute signal confirmation within the next N 5-minute bars.")

g_repeat_filter = "Duplicate Signal Filtering Settings"
use_signal_cooldown_filter = input.bool(true, title="Enable Duplicate Signal Filter", group=g_repeat_filter, tooltip="Filters out duplicate signals in the same direction within a short period.")
min_bars_between_signals = input.int(12, title="Minimum Bars Between Same-Direction Signals", minval=1, group=g_repeat_filter, tooltip="After a signal is issued, at least this many bars must pass before another signal in the same direction can be issued.")

// --- Take Profit Parameters ---
g_tp_params = "Take Profit Parameters"
extreme_long_tp_level = input.float(95.0, "Extreme Long TP Level (Stoch K >)", minval=50, maxval=100, step=0.1, group=g_tp_params, tooltip="Direct TP for longs if 5-min OR 15-min Stoch K exceeds this.")
extreme_short_tp_level = input.float(5.0, "Extreme Short TP Level (Stoch K <)", minval=0, maxval=50, step=0.1, group=g_tp_params, tooltip="Direct TP for shorts if 5-min OR 15-min Stoch K is below this.")

// --- Strategy Specific Input Parameters ---
g_strategy = "Strategy Parameters"
leverage_multiplier = input.float(1.0, "Leverage Multiplier (Affects theoretical position size only)", minval=1.0, step=0.1, group=g_strategy, tooltip="Note: TradingView strategies do not directly simulate margin account liquidation. This leverage is used to calculate theoretical position size. Actual leverage effects must be realized with a broker that supports leverage.")

// --- Function: Calculate Stochastic RSI ---
getStochasticRSI(src, rsiLen, stochLen, kSmooth, dSmooth) =>
    rsi_val = ta.rsi(src, rsiLen)
    stoch_rsi_k_raw = ta.stoch(rsi_val, rsi_val, rsi_val, stochLen) // Stoch of RSI
    stoch_rsi_k = ta.sma(stoch_rsi_k_raw, kSmooth)
    stoch_rsi_d = ta.sma(stoch_rsi_k, dSmooth)
    [stoch_rsi_k, stoch_rsi_d]

// --- Helper Function to get only K-series for Stochastic RSI (RE-ADDED for 15-min prev K) ---
getStochKSeriesOnly(src, rsiLen, stochLen, kSmooth, dSmooth) =>
    rsi_val = ta.rsi(src, rsiLen)
    stoch_rsi_k_raw = ta.stoch(rsi_val, rsi_val, rsi_val, stochLen)
    stoch_rsi_k = ta.sma(stoch_rsi_k_raw, kSmooth)
    stoch_rsi_k // Return only the K series

// --- Time Series Data Fetching and Stochastic RSI Calculation ---
[stoch_k_15min_val, stoch_d_15min_val] = request.security(syminfo.tickerid, "15", getStochasticRSI(close, rsi_len, stoch_rsi_len, stoch_k_smooth, stoch_d_smooth), lookahead=barmerge.lookahead_off)
// RE-ADDED: K value of the PREVIOUS 15-minute bar's Stochastic RSI
stoch_k_15min_prev_tf_bar = request.security(syminfo.tickerid, "15", nz(getStochKSeriesOnly(close, rsi_len, stoch_rsi_len, stoch_k_smooth, stoch_d_smooth)[1]), lookahead=barmerge.lookahead_off)
[stoch_k_5min_val, stoch_d_5min_val] = getStochasticRSI(close, rsi_len, stoch_rsi_len, stoch_k_smooth, stoch_d_smooth)

// --- Signal Logic State Variables ---
var bool waiting_for_15m_long_confirm = false
var bool waiting_for_15m_short_confirm = false
var int bars_elapsed_in_wait_state = 0
var int last_long_signal_bar_idx = -min_bars_between_signals 
var int last_short_signal_bar_idx = -min_bars_between_signals

// --- Variables to store SL reference points from ENTRY bar ---
var float entry_bar_low_for_sl = na
var float entry_bar_high_for_sl = na

// --- Take Profit Logic State Variables ---
var bool first_tp_long_taken = false
var bool first_tp_short_taken = false
// RE-ADDED: State variables for pending TP confirmation on 15-min reversal
var bool pending_long_tp_on_15m_reversal = false
var bool pending_short_tp_on_15m_reversal = false

// --- Detect 5-minute Stochastic RSI crossover events for ENTRY ---
bool stoch_5min_crossed_up_prev_bar = ta.crossover(stoch_k_5min_val[1], stoch_d_5min_val[1])
bool stoch_5min_crossed_down_prev_bar = ta.crossunder(stoch_k_5min_val[1], stoch_d_5min_val[1])
bool condition_5min_k_level_for_long_trigger = stoch_k_5min_val[1] <= stoch_5min_k_long_trigger
bool condition_5min_k_level_for_short_trigger = stoch_k_5min_val[1] >= stoch_5min_k_short_trigger

// --- Specific 5-minute Stochastic RSI crossover for Take Profit (current bar) ---
bool stoch_5min_k_cross_under_d_tp = ta.crossunder(stoch_k_5min_val, stoch_d_5min_val) // For Long TP trigger
bool stoch_5min_k_cross_over_d_tp  = ta.crossover(stoch_k_5min_val, stoch_d_5min_val)  // For Short TP trigger

// --- RE-ADDED: 15-minute Reversal Confirmation for Take Profit ---
bool confirm_15m_reversal_for_long_tp = stoch_k_15min_val < stoch_k_15min_prev_tf_bar
bool confirm_15m_reversal_for_short_tp = stoch_k_15min_val > stoch_k_15min_prev_tf_bar

// --- Manage waiting state and tolerance period for ENTRY ---
if (strategy.position_size == 0)
    if (stoch_5min_crossed_up_prev_bar and condition_5min_k_level_for_long_trigger)
        can_trigger_new_long = not use_signal_cooldown_filter or (bar_index - last_long_signal_bar_idx >= min_bars_between_signals)
        if (can_trigger_new_long)
            waiting_for_15m_long_confirm := true
            waiting_for_15m_short_confirm := false 
            bars_elapsed_in_wait_state := 1
    else if (stoch_5min_crossed_down_prev_bar and condition_5min_k_level_for_short_trigger)
        can_trigger_new_short = not use_signal_cooldown_filter or (bar_index - last_short_signal_bar_idx >= min_bars_between_signals)
        if (can_trigger_new_short)
            waiting_for_15m_short_confirm := true
            waiting_for_15m_long_confirm := false 
            bars_elapsed_in_wait_state := 1
    else if (waiting_for_15m_long_confirm or waiting_for_15m_short_confirm)
        bars_elapsed_in_wait_state += 1
    
    if (bars_elapsed_in_wait_state > wait_window_5min_bars)
        waiting_for_15m_long_confirm := false
        waiting_for_15m_short_confirm := false
        bars_elapsed_in_wait_state := 0 
else 
    waiting_for_15m_long_confirm := false
    waiting_for_15m_short_confirm := false
    bars_elapsed_in_wait_state := 0

// --- 15-minute Stochastic RSI confirmation conditions for ENTRY (Strict Crossover) ---
bool confirm_15min_long_stoch_kd_cond = stoch_k_15min_val > stoch_d_15min_val // K must be strictly greater than D
bool confirm_15min_short_stoch_kd_cond = stoch_k_15min_val < stoch_d_15min_val // K must be strictly less than D
bool filter_15min_stoch_level_long = stoch_k_15min_val < stoch_15min_long_entry_level
bool filter_15min_stoch_level_short = stoch_k_15min_val > stoch_15min_short_entry_level

// --- Main Signal Determination (for strategy logic) ---
entry_long_signal = false
entry_short_signal = false

if (strategy.position_size == 0) 
    if (waiting_for_15m_long_confirm and bars_elapsed_in_wait_state <= wait_window_5min_bars)
        if (confirm_15min_long_stoch_kd_cond and filter_15min_stoch_level_long)
            can_confirm_new_long = not use_signal_cooldown_filter or (bar_index - last_long_signal_bar_idx >= min_bars_between_signals)
            if (can_confirm_new_long)
                entry_long_signal := true
    if (waiting_for_15m_short_confirm and bars_elapsed_in_wait_state <= wait_window_5min_bars)
        if (confirm_15min_short_stoch_kd_cond and filter_15min_stoch_level_short)
            can_confirm_new_short = not use_signal_cooldown_filter or (bar_index - last_short_signal_bar_idx >= min_bars_between_signals)
            if (can_confirm_new_short)
                entry_short_signal := true

// --- Strategy Execution Logic ---
// Reset SL ref and TP flags if position just closed
if (strategy.position_size == 0 and strategy.position_size[1] != 0) 
    first_tp_long_taken := false
    first_tp_short_taken := false
    entry_bar_low_for_sl := na 
    entry_bar_high_for_sl := na 
    pending_long_tp_on_15m_reversal := false // Reset pending TP flag
    pending_short_tp_on_15m_reversal := false // Reset pending TP flag

if (entry_long_signal) 
    strategy.entry("LE", strategy.long, comment="Long Entry")
    last_long_signal_bar_idx := bar_index 
    waiting_for_15m_long_confirm := false 
    bars_elapsed_in_wait_state := 0
    first_tp_long_taken := false 
    entry_bar_low_for_sl := low 
    entry_bar_high_for_sl := na 
    pending_long_tp_on_15m_reversal := false // Reset for new trade
    pending_short_tp_on_15m_reversal := false     

if (entry_short_signal) 
    strategy.entry("SE", strategy.short, comment="Short Entry")
    last_short_signal_bar_idx := bar_index 
    waiting_for_15m_short_confirm := false 
    bars_elapsed_in_wait_state := 0
    first_tp_short_taken := false  
    entry_bar_high_for_sl := high 
    entry_bar_low_for_sl := na    
    pending_short_tp_on_15m_reversal := false // Reset for new trade
    pending_long_tp_on_15m_reversal := false

// --- Stop Loss Logic (PRIORITY 1) ---
// Check and execute SL first. If SL triggers, position size becomes 0, preventing TP logic below from executing on the same bar.
bool sl_triggered_this_bar = false
if (strategy.position_size > 0) // If in a long trade
    if (not na(entry_bar_low_for_sl) and close < entry_bar_low_for_sl)
        strategy.close(id="LE", comment="SL Long")
        sl_triggered_this_bar := true
        pending_long_tp_on_15m_reversal := false // Ensure pending TP is cancelled if SL hits

if (strategy.position_size < 0) // If in a short trade
    if (not na(entry_bar_high_for_sl) and close > entry_bar_high_for_sl)
        strategy.close(id="SE", comment="SL Short")
        sl_triggered_this_bar := true
        pending_short_tp_on_15m_reversal := false // Ensure pending TP is cancelled if SL hits

// --- Take Profit Logic (PRIORITY 2 - only if SL did not trigger on this bar) ---
if (not sl_triggered_this_bar) // Only proceed with TP if SL hasn't already closed the position on this bar
    if (strategy.position_size > 0) // --- LONG TP LOGIC ---
        extreme_long_tp_condition = stoch_k_5min_val > extreme_long_tp_level or stoch_k_15min_val > extreme_long_tp_level
        if (extreme_long_tp_condition)
            if (not first_tp_long_taken)
                strategy.close(id="LE", comment="TP1 Long", qty_percent=50)
                first_tp_long_taken := true
            else 
                strategy.close(id="LE", comment="TP2 Long")
            pending_long_tp_on_15m_reversal := false // Reset pending state as this TP takes precedence
        else 
            // Conditional TP logic (5-min trigger + 15-min reversal)
            if (stoch_5min_k_cross_under_d_tp and not pending_long_tp_on_15m_reversal) // Set pending state
                pending_long_tp_on_15m_reversal := true
        
            if (pending_long_tp_on_15m_reversal and confirm_15m_reversal_for_long_tp) // Check for confirmation
                if (not first_tp_long_taken)
                    strategy.close(id="LE", comment="TP1 Long", qty_percent=50)
                    first_tp_long_taken := true
                else 
                    strategy.close(id="LE", comment="TP2 Long")
                pending_long_tp_on_15m_reversal := false // Reset after TP

    if (strategy.position_size < 0) // --- SHORT TP LOGIC ---
        extreme_short_tp_condition = stoch_k_5min_val < extreme_short_tp_level or stoch_k_15min_val < extreme_short_tp_level
        if (extreme_short_tp_condition)
            if (not first_tp_short_taken)
                strategy.close(id="SE", comment="TP1 Short", qty_percent=50)
                first_tp_short_taken := true
            else 
                strategy.close(id="SE", comment="TP2 Short")
            pending_short_tp_on_15m_reversal := false // Reset pending state
        else
            // Conditional TP logic (5-min trigger + 15-min reversal)
            if (stoch_5min_k_cross_over_d_tp and not pending_short_tp_on_15m_reversal) // Set pending state
                pending_short_tp_on_15m_reversal := true

            if (pending_short_tp_on_15m_reversal and confirm_15m_reversal_for_short_tp) // Check for confirmation
                if (not first_tp_short_taken)
                    strategy.close(id="SE", comment="TP1 Short", qty_percent=50)
                    first_tp_short_taken := true
                else 
                    strategy.close(id="SE", comment="TP2 Short")
                pending_short_tp_on_15m_reversal := false // Reset after TP
相关推荐