マルチタイムフレームストキャスティクスRSIクロスオーバー戦略

RSI STOCH RSI MTF TRENDING MARKETS STOP LOSS MULTI-STAGE TP
作成日: 2025-06-05 13:13:32 最終変更日: 2025-06-05 13:13:32
コピー: 0 クリック数: 336
2
フォロー
319
フォロワー

マルチタイムフレームストキャスティクスRSIクロスオーバー戦略 マルチタイムフレームストキャスティクスRSIクロスオーバー戦略

戦略概要

マルチタイムフレームのランダムな比較的強い指標の交差戦略は,ストキャスティックRSI (ランダムな比較的強い指標) に基づく複合取引システムで,5分と15分の2つの時間周期のデータを用いて取引シグナルを生成および確認する.これは,明確な入場条件,ストップ・ロス・コントロール,そして段階的な利益のプログラムを含む完全な取引システムである.この戦略は,市場の超買/超売状態に特に注目し,価格動力の転換を捕捉して利益を上げる.

この戦略は5分チャートで動作するが,15分チャートのデータを参照して取引シグナルを確認し,マルチタイムフレーム分析の深さを表している.多頭と空頭取引に対して異なるパラメータ設定を採用し,全体的に看板の市場環境に適応するように設計されていることを示唆している.

戦略原則

この戦略の核心原理は,多時枠確認メカニズムと組み合わせたストキャスティックRSI指標の交差信号に基づいて,低品質の信号をフィルタリングします.具体的な作業プロセスは次のとおりです.

  1. 初期トリガシグナル ((5分間の時間枠)

    • 多頭シグナル:5分図のストックRSIのK線がD線を上向きに横切って,横切った時のK値は指定されたトリガーレベル以下であるとき ((stoch_5min_k_long_trigger))
    • 空頭シグナル: 5分図のストック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. 2段階の利益の仕組み

    • 第1段階 (TP1):50%のポジションをクリアし,以下の2つの方法の1つでトリガーします.
      • 優先方法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は空頭)
    • 第2段階 ((TP2)):残りの50%のポジションを平らにして,TP1が誘発された後にのみ活性化し,5分または15分Stoch K値が再び同じ極限レベルに達したときに実行する。

戦略的優位性

  1. 複数の時間枠の確認機構

    • この戦略は,5分と15分間の時間枠のシグナルを組み合わせることで,偽信号を減少させ,取引の質を高めます.短い時間枠は入場機会を提供し,長い時間枠はトレンド確認を提供し,この方法は短期市場のノイズを効果的にフィルターすることができます.
  2. オーバーバイ/オーバーセール条件の正確な位置

    • ストキャスティックRSIは,従来のRSIよりも敏感で,価格動力の変化を早期に捉えることができる.この特性を利用して,価格が逆転しようとしているときに取引し,入場タイミングの正確性を向上させる.
  3. 段階的な停止戦略

    • 2段階のストップ・ストップメカニズムにより,トレーダーは利益の一部をロックし,余剰ポジションを保持してより大きな市場を捉えることができます.この方法はリスクと利益のバランスを保ち,特に波動性の高い市場には適しています.
  4. 設定を調整する

    • 戦略のパラメータは,市場の好みを反映するために調整され,異なる市場環境と取引好みに適応できるようにすることができる.
  5. リスクの管理

    • 明確なストップ・メカニズムは,入場K線の極限値に基づいて,各取引に可量化されるリスクコントロールを提供します.ストップ・チェックは,利益チェックよりも優先され,リスクコントロールが常に第一の考慮事項であることを保証します.
  6. 繰り返し信号をフィルタリング

    • 信号の冷却期を実装することで,短時間で同じ方向で過度に取引を避け,取引コストを削減し,信号の質を向上させる.

戦略リスク

  1. パラメータ感度

    • この戦略は,様々なトリガーレベルや確認の値などの複数の値パラメータに依存している.不適切なパラメータ設定は,過剰な偽信号や重要な取引機会を逃す可能性があります.これらのパラメータは,異なる市場条件でリテックによって最適化されるべきです.
  2. ストップポイントは幅が広い

    • 入場K線極値に基づくストップは,特定の状況において,特に波動性の高い市場において,より緩やかである可能性があります.これは,単一の取引の潜在的な損失が予想以上に増加する可能性があります.過度のリスク露出を避けるために最大ストップ制限を設定することを考慮してください.
  3. 市場条件に依存する

    • ストキャスティックRSIは,区間振動市場では良好なパフォーマンスを発揮しますが,強いトレンド市場では早すぎる反転信号を生じることがあります.この戦略は,価格が反転せずに継続的に超買いまたは超売り状態を続けるため,急速な単方向の動きでは不良なパフォーマンスを発揮することがあります.
  4. 多頭性への偏見

    • 現在の戦略配置は多頭取引に好意を示しており,これは熊市環境で過度取引や不適切な多頭シグナルを引き起こす可能性がある.市場環境に応じてパラメータを調整してバランスをとるべきである.
  5. 15分遅延確認

    • 15分間の時間枠の確認を待つことは,入場の遅延を引き起こし,急速な市場では理想的な入場点を逃す可能性があります.極端に変動する市場では,この遅延は戦略のパフォーマンスに著しく影響を与える可能性があります.

戦略最適化の方向性

  1. ダイナミック・ストップ・メカニズム

    • 現在の固定パーセントのストップはATR ((Average True Range) に基づくダイナミックストップにアップグレードするか,トレンドの状況でより多くの利益をキャッチするために尾行ストップの仕組みを適用することができます.特に第2段階のストップの場合,波動率またはトレンドの強度に調整されたストップレベルを使用することを考慮してください.
  2. 市場が適応する

    • 市場状態検知機構の導入 ((ADX指標のようなトレンドの強さを評価する) は,戦略が異なる市場環境に応じてパラメータを自動的に調整できるようにする.例えば,強いトレンド市場では反転条件を緩和し,震動市場ではこれらの条件を厳しくする.
  3. 複数の指標の同定

    • MACD,ブリン帯,または移動平均などの追加の技術指標を補助的な確認ツールとして統合する.多指標共振は信号の信頼性を高め,偽突破を減らすことができます.
  4. リスクエッジの最適化

    • 動的なポジション規模管理を実施し,現在の変動率または最近の取引のパフォーマンスをベースに各取引のリスクフローリングを調整します. さらに,極度の損失を防ぐために最大停止幅の制限を追加できます.
  5. 複数の時間枠層の拡張

    • 3つ目の時間枠 (例えば1時間または4時間) を追加することを検討し,特にトレンド確認と主要なサポート/レジスタンス位置の識別のために,より高いレベルの市場背景分析を提供してください.
  6. 取引時間フィルター

    • 取引時間フィルターを追加し,流動性が不足しているまたは変動が不規則な市場時間に取引を避ける.例えば,市場開盤前と閉盤後の高波動期間に取引を制限することができます.

要約する

複数の時間枠でランダムに相対的に強い指標を交差する戦略は,複数の時間枠分析と厳格な信号確認プロセスを通して取引の質を向上させるための構造化された取引システムである.この戦略の核心的な優位性は,その全面的な入場条件とリスク管理システム,特に2段階のストップ・ストップ・メカニズムによって,一部のポジションをトレンドを追跡しながら利益をロックすることができます.

しかし,この戦略の効果は,パラメータ設定と市場条件に大きく依存しています. 揺れ動いている市場では良好なパフォーマンスを発揮しますが,強いトレンドまたは高い波動性のある環境では調整が必要になります. 交易者は,歴史を振り返ってパラメータを最適化し,市場状態検出やダイナミックストップメカニズムなどの機能を追加することを考慮して,その適応性を強化することをお勧めします.

この戦略は,プログラミングの知識を持つ中級から高級のトレーダーに最適で,これらの複雑な取引規則を理解し,カスタマイズすることができます.適切なパラメータ調整とリスク管理により,このシステムは,日中および短期トレーダーのツールキットの貴重な構成要素になり得る.

ストラテジーソースコード
/*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