Estrategia de cruce de RSI estocástico de múltiples marcos temporales

RSI STOCH RSI MTF TRENDING MARKETS STOP LOSS MULTI-STAGE TP
Fecha de creación: 2025-06-05 13:13:32 Última modificación: 2025-06-05 13:13:32
Copiar: 0 Número de Visitas: 336
2
Seguir
319
Seguidores

Estrategia de cruce de RSI estocástico de múltiples marcos temporales Estrategia de cruce de RSI estocástico de múltiples marcos temporales

Descripción general de la estrategia

La estrategia de cruce de indicadores aleatorios de fuerza relativamente débil en el marco temporal múltiple es un sistema de negociación complejo basado en el RSI estocástico (indicador aleatorio de fuerza relativamente débil) que utiliza datos de dos períodos de tiempo de 5 y 15 minutos para generar y confirmar señales de negociación. Se trata de un sistema de negociación completo que contiene condiciones de entrada claras, control de stop loss y un programa de ganancias por etapas.

La estrategia opera en gráficos de 5 minutos, pero se refiere a los datos de los gráficos de 15 minutos para confirmar las señales de negociación, lo que refleja la profundidad del análisis de varios marcos de tiempo. Utiliza diferentes configuraciones de parámetros para operaciones de varios y de un solo, lo que sugiere que está diseñado para adaptarse a un entorno de mercado optimista en general.

Principio de estrategia

El principio central de la estrategia se basa en la señal cruzada del indicador RSI estocástico, combinado con un mecanismo de confirmación de múltiples marcos de tiempo para filtrar señales de baja calidad. El proceso de trabajo específico es el siguiente:

  1. La señal de disparo inicial (en el marco de tiempo de 5 minutos)

    • Multipunto: cuando la línea K del RSI de Stoch en el gráfico de 5 minutos cruza la línea D hacia arriba, y el valor de K en el cruce es inferior al nivel de activación indicado.
    • Señales de cabeza en blanco: cuando la línea K del RSI de Stoch en el gráfico de 5 minutos cruza la línea D hacia abajo y el valor de K en el cruce es superior al nivel de disparo indicado (estoch_5min_k_short_trigger) [2].
  2. Confirmación de alto nivel en el marco de tiempo de 15 minutos

    • Después de la activación de la señal inicial de 5 minutos, la estrategia busca la confirmación del marco de tiempo de 15 minutos dentro de la ventana de espera establecida.
    • Confirmación múltiple: la línea K del RSI de 15 minutos de Stoch debe ser estrictamente mayor que su línea D, y el valor de K de 15 minutos debe ser menor que el valor establecido de stoch_15min_long_entry_level.
    • Confirmación en blanco: la línea K del RSI de Stoch de 15 minutos debe ser estrictamente menor que su línea D, y el valor de K de 15 minutos debe ser superior al valor de configuración de stoch_15min_short_entry_level.
  3. Filtración de señales repetidas

    • La estrategia implementa un mecanismo de período de enfriamiento (min_bars_between_signals) en el que una nueva señal debe pasar por un número determinado de líneas K entre señales en la misma dirección para ser considerada.
  4. Administración de posiciones

    • Bloqueo de posiciones abiertas: la estrategia no genera nuevas señales de entrada cuando ya se tiene una posición abierta.
    • Establecimiento de stop loss: basado en el establecimiento de los puntos bajos (en el caso de los pares) o altos (en el caso de los pares) de la línea K de entrada, si el precio de cierre de la línea K posterior supera este nivel, se activa el stop loss.
    • La inspección de pérdidas tiene prioridad sobre la inspección de ganancias.
  5. Mecanismo de ganancias en dos etapas

    • La primera etapa (TP1): eliminación del 50% de las posiciones, que se activa de una de las dos maneras siguientes:
      • Modo de prioridad A ((valor de K extremo): Si el valor de Stoch K de 5 minutos o 15 minutos es superior a extreme_long_tp_level ((multicabeza) o inferior a extreme_short_tp_level ((cabeza en blanco))
      • Método de prioridad B ((cruce condicional de 5 minutos + reversión del valor de K de 15 minutos): cuando se produce un cruce K/D de Stoch RSI de 5 minutos ((K se cruza hacia abajo en D cuando el multicapa; K se cruza hacia arriba en D cuando el voladizo), y se confirma el “reversión” del valor de Stoch K de 15 minutos ((el K de 15 minutos actual < el K de 15 minutos anteriores para el multicapa; el K de 15 minutos actual > el K de 15 minutos anteriores para el voladizo))
    • Fase dos ((TP2)): elimina el 50% restante de las posiciones, activado solo después de que se haya activado el TP1, y ejecutado cuando el valor de Stoch K de 5 minutos o 15 minutos vuelva a alcanzar el mismo nivel extremo.

Ventajas estratégicas

  1. Mecanismo de confirmación de marcos de tiempo múltiple

    • La estrategia reduce las falsas señales y mejora la calidad de las operaciones mediante la combinación de señales en los marcos de tiempo de 5 y 15 minutos. Los marcos de tiempo más cortos ofrecen oportunidades de entrada, mientras que los marcos de tiempo más largos ofrecen confirmación de tendencias, un método que puede filtrar eficazmente el ruido del mercado a corto plazo.
  2. Determinación exacta de las condiciones de sobrecompra/sobreventa

    • El RSI estocástico es más sensible que el RSI tradicional y puede capturar cambios en la dinámica de los precios antes. La estrategia utiliza esta característica para operar cuando los precios están a punto de invertir, lo que mejora la precisión de la hora de entrada.
  3. Estrategias para detener el alcohol por etapas

    • El mecanismo de stop-loss en dos etapas permite a los operadores bloquear parte de las ganancias, mientras que se mantienen las posiciones restantes para capturar el mercado más grande. Este método equilibra el riesgo y los beneficios, especialmente adecuado para los mercados con mayor volatilidad.
  4. Ajustes de preferencias personalizados

    • Los parámetros de la estrategia se pueden ajustar para reflejar las preferencias del mercado (por ejemplo, la estrategia actual es más flexible para los inversores), lo que permite adaptarse a diferentes entornos de mercado y preferencias de negociación.
  5. Gestión de riesgos completa

    • El mecanismo de detención de pérdidas claro está basado en los límites de la línea K de entrada, lo que proporciona un control de riesgo cuantificable para cada transacción. La verificación de la detención de pérdidas prevalece sobre la verificación de ganancias, asegurando que el control de riesgos siempre sea la primera consideración.
  6. Filtración de señales repetidas

    • Implementando un período de enfriamiento de la señal, se evita el exceso de operaciones en la misma dirección en un corto período de tiempo, reduciendo los costos de transacción y mejorando la calidad de la señal.

Riesgo estratégico

  1. Sensibilidad de los parámetros

    • La estrategia depende de varios parámetros de valoración, como varios niveles de activación y valoración de valoración. La configuración inadecuada de los parámetros puede causar demasiadas falsas señales o perder oportunidades de negociación clave. Estos parámetros deben optimizarse mediante retroalimentación en diferentes condiciones de mercado.
  2. El punto de parada puede ser más amplio

    • El stop loss basado en el límite de entrada de la línea K puede ser más flexible en ciertos casos, especialmente en mercados con mucha volatilidad. Esto puede provocar que la pérdida potencial de una sola transacción supere las expectativas. Considere establecer un límite de máximo stop loss para evitar una exposición excesiva al riesgo.
  3. Dependencia de las condiciones del mercado

    • El RSI estocástico funciona bien en mercados de oscilación intermedia, pero puede generar una señal de reversión prematura en mercados de fuerte tendencia. La estrategia puede funcionar mal en un movimiento unidireccional rápido, ya que los precios pueden continuar sobrecomprados o sobrevendidos sin revertir.
  4. Prejuicio por el polvo

    • La configuración de la estrategia actual muestra una preferencia por el comercio de múltiples cabezas, lo que puede conducir a un exceso de comercio o una señal de múltiples cabezas inadecuada en un entorno de mercado bajista. Se deben ajustar los parámetros según el entorno del mercado para mantener el equilibrio.
  5. 15 minutos para confirmar el retraso

    • La espera de 15 minutos para la confirmación del marco de tiempo puede causar retrasos en la entrada y puede perder el punto de entrada ideal en mercados rápidos. En mercados con extrema volatilidad, este retraso puede afectar significativamente el rendimiento de la estrategia.

Dirección de optimización de la estrategia

  1. Mecanismo de frenado dinámico

    • Los paros de porcentaje fijo actuales pueden ser actualizados a paros dinámicos basados en el ATR (Average True Range) o implementar mecanismos de paros de seguimiento para capturar más ganancias en situaciones de tendencia. En particular, para los paros de segunda etapa, considere el uso de paros ajustados a la volatilidad o la intensidad de la tendencia.
  2. El estado del mercado se adapta

    • La introducción de mecanismos de detección de estado de mercado (como el indicador ADX que evalúa la fuerza de la tendencia) permite a la estrategia ajustar automáticamente los parámetros según los diferentes entornos del mercado. Por ejemplo, relajar las condiciones de reversión en mercados de fuerte tendencia y endurecerlas en mercados de crisis.
  3. Confirmación sincronizada de varios indicadores

    • La integración de indicadores técnicos adicionales como el MACD, la banda de Brin o la media móvil como herramientas de confirmación auxiliares. La resonancia multiindicador puede mejorar la fiabilidad de la señal y reducir las falsas brechas.
  4. Optimización de las salidas de riesgo

    • Implementar gestión dinámica de la escala de la posición, ajustando el umbral de riesgo de cada operación en función de la volatilidad actual o el rendimiento de las operaciones recientes. Además, se puede agregar un límite de máximo límite de pérdida para evitar pérdidas extremas.
  5. Extensión a nivel de marco temporal múltiple

    • Considere agregar un tercer marco de tiempo (como 1 hora o 4 horas) para proporcionar un nivel más alto de análisis del contexto del mercado, especialmente para la confirmación de tendencias y la identificación de los principales puntos de soporte / resistencia.
  6. Filtrado por período de transacción

    • Añadir filtros de tiempo de negociación para evitar la negociación en momentos de mercado con poca liquidez o fluctuaciones irregulares. Por ejemplo, se puede limitar la negociación durante los períodos de alta volatilidad antes y después de la apertura y el cierre del mercado.

Resumir

La estrategia de cruce de indicadores de índices aleatorios con fuertes y débiles índices de múltiples marcos de tiempo es un sistema de negociación bien estructurado que mejora la calidad de las transacciones a través del análisis de marcos de tiempo múltiples y un riguroso proceso de confirmación de señales. La ventaja central de la estrategia radica en sus condiciones de entrada completas y su sistema de gestión de riesgos, en particular el mecanismo de paradas de dos etapas que permite bloquear los beneficios mientras se mantiene la tendencia de seguimiento de algunas posiciones.

Sin embargo, la eficacia de esta estrategia depende en gran medida de la configuración de los parámetros y las condiciones del mercado. Puede funcionar bien en un mercado convulso, pero puede necesitar ajustes en un entorno de fuerte tendencia o alta volatilidad. Se recomienda a los comerciantes optimizar los parámetros a través de la retroalimentación histórica y considerar la adición de funciones como detección de estado del mercado y mecanismos de suspensión dinámica para aumentar su adaptabilidad.

La estrategia es más adecuada para los operadores intermedios a avanzados con conocimientos de programación, que pueden entender y personalizar estas complejas reglas de negociación. Con el ajuste adecuado de los parámetros y la gestión del riesgo, este sistema puede ser un componente valioso en la caja de herramientas de los comerciantes diarios y a corto plazo, especialmente aquellos que se centran en capturar los cambios en la dinámica del mercado.

Código Fuente de la Estrategia
/*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