Estrategia de ruptura impulsada por el sentimiento que integra múltiples indicadores


Fecha de creación: 2024-01-17 17:53:55 Última modificación: 2024-01-17 17:53:55
Copiar: 0 Número de Visitas: 745
1
Seguir
1617
Seguidores

Estrategia de ruptura impulsada por el sentimiento que integra múltiples indicadores

Descripción general

Esta estrategia combina los tres indicadores emocionales de QQE, el indicador híbrido SSL y el indicador de explosión de Waddah Attar, para formar una señal de negociación, que pertenece a la estrategia de ruptura emocional impulsada por múltiples indicadores. Puede juzgar la emoción del mercado antes de la ruptura, evitar falsas rupturas y pertenecer a la estrategia de ruptura de calidad.

Principio de estrategia

La lógica central de esta estrategia se basa en tres indicadores para tomar decisiones comerciales:

Indicadores mejorados de QQEEste indicador es una mejora en el RSI para que sea más sensible y permita determinar si el sentimiento del mercado es alto o bajo. Esta estrategia utiliza este indicador para determinar las señales de reversión inferior y superior.

Indicadores de hibridación de SSLEste indicador tiene en cuenta las rupturas de varias líneas de media móvil para determinar las señales del mercado. Esta estrategia utiliza este indicador para determinar la forma de ruptura de canal.

El índice de explosión de Waddah AttarEste indicador determina la intensidad de la ruptura del precio dentro del canal. Esta estrategia utiliza este indicador para determinar el impulso suficiente para la ruptura.

La estrategia genera una decisión de compra cuando el indicador QQE emite una señal de reversión inferior, el indicador SSL muestra una ruptura en el canal y el indicador Waddah Attar determina una explosión de impulso. Cuando los tres indicadores emiten simultáneamente una señal contraria, toma una decisión de venta.

Esta estrategia, que establece un punto de salida preciso para detener y detener los pérdidas al mismo tiempo y maximizar el bloqueo de ganancias, es una estrategia de ruptura impulsada por la emoción de alta calidad.

Análisis de las ventajas

La estrategia tiene las siguientes ventajas:

  1. La integración de múltiples indicadores para evaluar el estado de ánimo del mercado y evitar el riesgo de falsas rupturas
  2. Al mismo tiempo, considera los indicadores de reversión, los indicadores de canal y los indicadores de dinámica para garantizar una alta confirmación del mercado en el momento de la ruptura
  3. El uso de alto nivel de precisión para limitar el riesgo de pérdidas móviles, rastrear y bloquear ganancias
  4. Los parámetros han sido sometidos a una gran cantidad de pruebas de optimización, con una buena estabilidad, adecuados para la posesión de líneas medias a largas
  5. Parámetros de indicadores configurables para ajustar el estilo de la estrategia de forma autónoma para adaptarse a una situación de mercado más amplia

Análisis de riesgos

Los principales riesgos de esta estrategia son los siguientes:

  1. La tendencia a las pequeñas pérdidas se manifiesta cuando las grandes bolsas siguen bajas.
  2. Necesidad de confiar en varios indicadores al mismo tiempo, lo que puede ser ineficaz en algunos mercados
  3. El riesgo de optimización excesiva de parámetros en múltiples indicadores, como los indicadores de QQE, debe establecerse con precaución
  4. El deterioro móvil puede ser más difícil de manejar en situaciones especiales

En respuesta a estos riesgos, se recomienda ajustar los parámetros del indicador para que sean más estables y aumentar adecuadamente el ciclo de tenencia para obtener una mayor tasa de ganancias.

Dirección de optimización

Esta estrategia puede ser mejorada en los siguientes aspectos:

  1. Ajuste los parámetros de los indicadores para que sean más estables o más sensibles
  2. Aumentar el módulo de optimización de la escala de las posiciones basado en la volatilidad
  3. Aumentar el módulo de aprendizaje automático para el control de viento y evaluar la situación del mercado en tiempo real
  4. Modelos de aprendizaje profundo para mejorar la precisión de la toma de decisiones
  5. Introducción de análisis de ciclo a través del tiempo para reducir la probabilidad de falsas brechas

Resumir

Esta estrategia combina las ventajas de múltiples indicadores de sentimiento dominantes para construir una estrategia de ruptura impulsada por la emoción de alta eficiencia. Ha evitado con éxito los riesgos de muchas rupturas de baja calidad, pero tiene una estrategia de alto nivel de precisión para detener los pérdidas y bloquear los beneficios. Es una combinación de estrategias de ruptura sólidas y probadas que vale la pena aprender y aplicar.

Código Fuente de la Estrategia
/*backtest
start: 2023-12-17 00:00:00
end: 2024-01-16 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// Strategy based on the 3 indicators:
//  - QQE MOD
//  - SSL Hybrid
//  - Waddah Attar Explosion
//
// Strategy was designed for the purpose of back testing. 
// See strategy documentation for info on trade entry logic.
// 
// Credits:
//  - QQE MOD: Mihkel00 (https://www.tradingview.com/u/Mihkel00/)
//  - SSL Hybrid: Mihkel00 (https://www.tradingview.com/u/Mihkel00/)
//  - Waddah Attar Explosion: shayankm (https://www.tradingview.com/u/shayankm/)

//@version=5
strategy("QQE MOD + SSL Hybrid + Waddah Attar Explosion", overlay=false)

// =============================================================================
// STRATEGY INPUT SETTINGS
// =============================================================================

// ---------------
// Risk Management
// ---------------
swingLength = input.int(10, "Swing High/Low Lookback Length", group='Strategy: Risk Management', tooltip='Stop Loss is calculated by the swing high or low over the previous X candles')
accountRiskPercent = input.float(2, "Account percent loss per trade", step=0.1, group='Strategy: Risk Management', tooltip='Each trade will risk X% of the account balance')

// ----------
// Date Range
// ----------
start_year = input.int(title='Start Date', defval=2022, minval=2010, maxval=3000, group='Strategy: Date Range', inline='1')
start_month = input.int(title='', defval=1, group='Strategy: Date Range', inline='1', options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
start_date = input.int(title='', defval=1, group='Strategy: Date Range', inline='1', options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
end_year = input.int(title='End Date', defval=2023, minval=1800, maxval=3000, group='Strategy: Date Range', inline='2')
end_month = input.int(title='', defval=1, group='Strategy: Date Range', inline='2', options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
end_date = input.int(title='', defval=1, group='Strategy: Date Range', inline='2', options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
in_date_range = true
// =============================================================================
// INDICATORS
// =============================================================================

// -------
// QQE MOD
// -------
RSI_Period = input.int(6, title='RSI Length', group='Indicators: QQE Mod Settings')
SF = input.int(6, title='RSI Smoothing', group='Indicators: QQE Mod Settings')
QQE = input.int(3, title='Fast QQE Factor', group='Indicators: QQE Mod Settings')
ThreshHold = input.int(3, title='Thresh-hold', group='Indicators: QQE Mod Settings')
qqeSrc = input(close, title='RSI Source', group='Indicators: QQE Mod Settings')
Wilders_Period = RSI_Period * 2 - 1

Rsi = ta.rsi(qqeSrc, RSI_Period)
RsiMa = ta.ema(Rsi, SF)
AtrRsi = math.abs(RsiMa[1] - RsiMa)
MaAtrRsi = ta.ema(AtrRsi, Wilders_Period)
dar = ta.ema(MaAtrRsi, Wilders_Period) * QQE

longband = 0.0
shortband = 0.0
trend = 0

DeltaFastAtrRsi = dar
RSIndex = RsiMa
newshortband = RSIndex + DeltaFastAtrRsi
newlongband = RSIndex - DeltaFastAtrRsi
longband := RSIndex[1] > longband[1] and RSIndex > longband[1] ? math.max(longband[1], newlongband) : newlongband
shortband := RSIndex[1] < shortband[1] and RSIndex < shortband[1] ? math.min(shortband[1], newshortband) : newshortband
cross_1 = ta.cross(longband[1], RSIndex)
trend := ta.cross(RSIndex, shortband[1]) ? 1 : cross_1 ? -1 : nz(trend[1], 1)
FastAtrRsiTL = trend == 1 ? longband : shortband

length = input.int(50, minval=1, title='Bollinger Length', group='Indicators: QQE Mod Settings')
qqeMult = input.float(0.35, minval=0.001, maxval=5, step=0.1, title='BB Multiplier', group='Indicators: QQE Mod Settings')
basis = ta.sma(FastAtrRsiTL - 50, length)
dev = qqeMult * ta.stdev(FastAtrRsiTL - 50, length)
upper = basis + dev
lower = basis - dev
//qqe_color_bar = RsiMa - 50 > upper ? #00c3ff : RsiMa - 50 < lower ? #ff0062 : color.gray

// Zero cross
QQEzlong = 0
QQEzlong := nz(QQEzlong[1])
QQEzshort = 0
QQEzshort := nz(QQEzshort[1])
QQEzlong := RSIndex >= 50 ? QQEzlong + 1 : 0
QQEzshort := RSIndex < 50 ? QQEzshort + 1 : 0

Zero = hline(0, color=color.white, linestyle=hline.style_dotted, linewidth=1, display=display.none)

RSI_Period2 = input.int(6, title='RSI Length', group='Indicators: QQE Mod Settings')
SF2 = input.int(5, title='RSI Smoothing', group='Indicators: QQE Mod Settings')
QQE2 = input.float(1.61, title='Fast QQE2 Factor', group='Indicators: QQE Mod Settings')
ThreshHold2 = input.int(3, title='Thresh-hold', group='Indicators: QQE Mod Settings')
src2 = input(close, title='RSI Source', group='Indicators: QQE Mod Settings')
Wilders_Period2 = RSI_Period2 * 2 - 1

Rsi2 = ta.rsi(src2, RSI_Period2)
RsiMa2 = ta.ema(Rsi2, SF2)
AtrRsi2 = math.abs(RsiMa2[1] - RsiMa2)
MaAtrRsi2 = ta.ema(AtrRsi2, Wilders_Period2)
dar2 = ta.ema(MaAtrRsi2, Wilders_Period2) * QQE2
longband2 = 0.0
shortband2 = 0.0
trend2 = 0

DeltaFastAtrRsi2 = dar2
RSIndex2 = RsiMa2
newshortband2 = RSIndex2 + DeltaFastAtrRsi2
newlongband2 = RSIndex2 - DeltaFastAtrRsi2
longband2 := RSIndex2[1] > longband2[1] and RSIndex2 > longband2[1] ? math.max(longband2[1], newlongband2) : newlongband2
shortband2 := RSIndex2[1] < shortband2[1] and RSIndex2 < shortband2[1] ? math.min(shortband2[1], newshortband2) : newshortband2
cross_2 = ta.cross(longband2[1], RSIndex2)
trend2 := ta.cross(RSIndex2, shortband2[1]) ? 1 : cross_2 ? -1 : nz(trend2[1], 1)
FastAtrRsi2TL = trend2 == 1 ? longband2 : shortband2

// Zero cross
QQE2zlong = 0
QQE2zlong := nz(QQE2zlong[1])
QQE2zshort = 0
QQE2zshort := nz(QQE2zshort[1])
QQE2zlong := RSIndex2 >= 50 ? QQE2zlong + 1 : 0
QQE2zshort := RSIndex2 < 50 ? QQE2zshort + 1 : 0

hcolor2 = RsiMa2 - 50 > ThreshHold2 ? color.silver : RsiMa2 - 50 < 0 - ThreshHold2 ? color.silver : na
plot(RsiMa2 - 50, color=hcolor2, title='Histo2', style=plot.style_columns, transp=50)

Greenbar1 = RsiMa2 - 50 > ThreshHold2
Greenbar2 = RsiMa - 50 > upper
Redbar1 = RsiMa2 - 50 < 0 - ThreshHold2
Redbar2 = RsiMa - 50 < lower

plot(Greenbar1 and Greenbar2 == 1 ? RsiMa2 - 50 : na, title='QQE Up', style=plot.style_columns, color=color.new(#00c3ff, 0))
plot(Redbar1 and Redbar2 == 1 ? RsiMa2 - 50 : na, title='QQE Down', style=plot.style_columns, color=color.new(#ff0062, 0))

// ----------
// SSL HYBRID
// ----------
show_Baseline = input(title='Show Baseline', defval=true)
show_SSL1 = input(title='Show SSL1', defval=false)
show_atr = input(title='Show ATR bands', defval=true)
//ATR
atrlen = input(14, 'ATR Period')
mult = input.float(1, 'ATR Multi', step=0.1)
smoothing = input.string(title='ATR Smoothing', defval='WMA', options=['RMA', 'SMA', 'EMA', 'WMA'])

ma_function(source, atrlen) =>
    if smoothing == 'RMA'
        ta.rma(source, atrlen)
    else
        if smoothing == 'SMA'
            ta.sma(source, atrlen)
        else
            if smoothing == 'EMA'
                ta.ema(source, atrlen)
            else
                ta.wma(source, atrlen)
atr_slen = ma_function(ta.tr(true), atrlen)
////ATR Up/Low Bands
upper_band = atr_slen * mult + close
lower_band = close - atr_slen * mult

////BASELINE / SSL1 / SSL2 / EXIT MOVING AVERAGE VALUES
maType = input.string(title='SSL1 / Baseline Type', defval='HMA', options=['SMA', 'EMA', 'DEMA', 'TEMA', 'LSMA', 'WMA', 'MF', 'VAMA', 'TMA', 'HMA', 'JMA', 'Kijun v2', 'EDSMA', 'McGinley'])
len = input(title='SSL1 / Baseline Length', defval=60)

SSL2Type = input.string(title='SSL2 / Continuation Type', defval='JMA', options=['SMA', 'EMA', 'DEMA', 'TEMA', 'WMA', 'MF', 'VAMA', 'TMA', 'HMA', 'JMA', 'McGinley'])
len2 = input(title='SSL 2 Length', defval=5)
SSL3Type = input.string(title='EXIT Type', defval='HMA', options=['DEMA', 'TEMA', 'LSMA', 'VAMA', 'TMA', 'HMA', 'JMA', 'Kijun v2', 'McGinley', 'MF'])
len3 = input(title='EXIT Length', defval=15)
src = input(title='Source', defval=close)

tema(src, len) =>
    ema1 = ta.ema(src, len)
    ema2 = ta.ema(ema1, len)
    ema3 = ta.ema(ema2, len)
    3 * ema1 - 3 * ema2 + ema3
kidiv = input.int(defval=1, maxval=4, title='Kijun MOD Divider')

jurik_phase = input(title='* Jurik (JMA) Only - Phase', defval=3)
jurik_power = input(title='* Jurik (JMA) Only - Power', defval=1)
volatility_lookback = input(10, title='* Volatility Adjusted (VAMA) Only - Volatility lookback length')
//MF
beta = input.float(0.8, minval=0, maxval=1, step=0.1, title='Modular Filter, General Filter Only - Beta')
feedback = input(false, title='Modular Filter Only - Feedback')
z = input.float(0.5, title='Modular Filter Only - Feedback Weighting', step=0.1, minval=0, maxval=1)
//EDSMA
ssfLength = input.int(title='EDSMA - Super Smoother Filter Length', minval=1, defval=20)
ssfPoles = input.int(title='EDSMA - Super Smoother Filter Poles', defval=2, options=[2, 3])

//EDSMA
get2PoleSSF(src, length) =>
    PI = 2 * math.asin(1)
    arg = math.sqrt(2) * PI / length
    a1 = math.exp(-arg)
    b1 = 2 * a1 * math.cos(arg)
    c2 = b1
    c3 = -math.pow(a1, 2)
    c1 = 1 - c2 - c3

    ssf = 0.0
    ssf := c1 * src + c2 * nz(ssf[1]) + c3 * nz(ssf[2])
    ssf

get3PoleSSF(src, length) =>
    PI = 2 * math.asin(1)

    arg = PI / length
    a1 = math.exp(-arg)
    b1 = 2 * a1 * math.cos(1.738 * arg)
    c1 = math.pow(a1, 2)

    coef2 = b1 + c1
    coef3 = -(c1 + b1 * c1)
    coef4 = math.pow(c1, 2)
    coef1 = 1 - coef2 - coef3 - coef4

    ssf = 0.0
    ssf := coef1 * src + coef2 * nz(ssf[1]) + coef3 * nz(ssf[2]) + coef4 * nz(ssf[3])
    ssf

ma(type, src, len) =>
    float result = 0
    if type == 'TMA'
        result := ta.sma(ta.sma(src, math.ceil(len / 2)), math.floor(len / 2) + 1)
        result
    if type == 'MF'
        ts = 0.
        b = 0.
        c = 0.
        os = 0.
        //----
        alpha = 2 / (len + 1)
        a = feedback ? z * src + (1 - z) * nz(ts[1], src) : src
        //----
        b := a > alpha * a + (1 - alpha) * nz(b[1], a) ? a : alpha * a + (1 - alpha) * nz(b[1], a)
        c := a < alpha * a + (1 - alpha) * nz(c[1], a) ? a : alpha * a + (1 - alpha) * nz(c[1], a)
        os := a == b ? 1 : a == c ? 0 : os[1]
        //----
        upper = beta * b + (1 - beta) * c
        lower = beta * c + (1 - beta) * b
        ts := os * upper + (1 - os) * lower
        result := ts
        result
    if type == 'LSMA'
        result := ta.linreg(src, len, 0)
        result
    if type == 'SMA'  // Simple
        result := ta.sma(src, len)
        result
    if type == 'EMA'  // Exponential
        result := ta.ema(src, len)
        result
    if type == 'DEMA'  // Double Exponential
        e = ta.ema(src, len)
        result := 2 * e - ta.ema(e, len)
        result
    if type == 'TEMA'  // Triple Exponential
        e = ta.ema(src, len)
        result := 3 * (e - ta.ema(e, len)) + ta.ema(ta.ema(e, len), len)
        result
    if type == 'WMA'  // Weighted
        result := ta.wma(src, len)
        result
    if type == 'VAMA'  // Volatility Adjusted
        /// Copyright © 2019 to present, Joris Duyck (JD)
        mid = ta.ema(src, len)
        dev = src - mid
        vol_up = ta.highest(dev, volatility_lookback)
        vol_down = ta.lowest(dev, volatility_lookback)
        result := mid + math.avg(vol_up, vol_down)
        result
    if type == 'HMA'  // Hull
        result := ta.wma(2 * ta.wma(src, len / 2) - ta.wma(src, len), math.round(math.sqrt(len)))
        result
    if type == 'JMA'  // Jurik
        /// Copyright © 2018 Alex Orekhov (everget)
        /// Copyright © 2017 Jurik Research and Consulting.
        phaseRatio = jurik_phase < -100 ? 0.5 : jurik_phase > 100 ? 2.5 : jurik_phase / 100 + 1.5
        beta = 0.45 * (len - 1) / (0.45 * (len - 1) + 2)
        alpha = math.pow(beta, jurik_power)
        jma = 0.0
        e0 = 0.0
        e0 := (1 - alpha) * src + alpha * nz(e0[1])
        e1 = 0.0
        e1 := (src - e0) * (1 - beta) + beta * nz(e1[1])
        e2 = 0.0
        e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * math.pow(1 - alpha, 2) + math.pow(alpha, 2) * nz(e2[1])
        jma := e2 + nz(jma[1])
        result := jma
        result
    if type == 'Kijun v2'
        kijun = math.avg(ta.lowest(len), ta.highest(len))  //, (open + close)/2)
        conversionLine = math.avg(ta.lowest(len / kidiv), ta.highest(len / kidiv))
        delta = (kijun + conversionLine) / 2
        result := delta
        result
    if type == 'McGinley'
        mg = 0.0
        mg := na(mg[1]) ? ta.ema(src, len) : mg[1] + (src - mg[1]) / (len * math.pow(src / mg[1], 4))
        result := mg
        result
    if type == 'EDSMA'

        zeros = src - nz(src[2])
        avgZeros = (zeros + zeros[1]) / 2

        // Ehlers Super Smoother Filter 
        ssf = ssfPoles == 2 ? get2PoleSSF(avgZeros, ssfLength) : get3PoleSSF(avgZeros, ssfLength)

        // Rescale filter in terms of Standard Deviations
        stdev = ta.stdev(ssf, len)
        scaledFilter = stdev != 0 ? ssf / stdev : 0

        alpha = 5 * math.abs(scaledFilter) / len

        edsma = 0.0
        edsma := alpha * src + (1 - alpha) * nz(edsma[1])
        result := edsma
        result
    result

///SSL 1 and SSL2
emaHigh = ma(maType, high, len)
emaLow = ma(maType, low, len)

maHigh = ma(SSL2Type, high, len2)
maLow = ma(SSL2Type, low, len2)

///EXIT
ExitHigh = ma(SSL3Type, high, len3)
ExitLow = ma(SSL3Type, low, len3)

///Keltner Baseline Channel
BBMC = ma(maType, close, len)
useTrueRange = input(true)
multy = input.float(0.2, step=0.05, title='Base Channel Multiplier')
Keltma = ma(maType, src, len)
range_1 = useTrueRange ? ta.tr : high - low
rangema = ta.ema(range_1, len)
upperk = Keltma + rangema * multy
lowerk = Keltma - rangema * multy

//Baseline Violation Candle
open_pos = open * 1
close_pos = close * 1
difference = math.abs(close_pos - open_pos)
atr_violation = difference > atr_slen
InRange = upper_band > BBMC and lower_band < BBMC

//SSL1 VALUES
Hlv = int(na)
Hlv := close > emaHigh ? 1 : close < emaLow ? -1 : Hlv[1]
sslDown = Hlv < 0 ? emaHigh : emaLow

//EXIT VALUES
Hlv3 = int(na)
Hlv3 := close > ExitHigh ? 1 : close < ExitLow ? -1 : Hlv3[1]
sslExit = Hlv3 < 0 ? ExitHigh : ExitLow
base_cross_Long = ta.crossover(close, sslExit)
base_cross_Short = ta.crossover(sslExit, close)
codiff = base_cross_Long ? 1 : base_cross_Short ? -1 : na

//COLORS
show_color_bar = input(title='Color Bars', defval=true)
color_bar = close > upperk ? #00c3ff : close < lowerk ? #ff0062 : color.gray
color_ssl1 = close > sslDown ? #00c3ff : close < sslDown ? #ff0062 : na

//PLOTS
plotarrow(codiff, colorup=color.new(#00c3ff, 20), colordown=color.new(#ff0062, 20), title='Exit Arrows', maxheight=20, offset=0, display=display.none)
p1 = plot(0, color=color_bar, linewidth=3, title='MA Baseline', transp=0)
barcolor(show_color_bar ? color_bar : na)

// ---------------------
// WADDAH ATTAR EXPLOSION
// ---------------------
sensitivity = input.int(180, title="Sensitivity", group='Indicators: Waddah Attar Explosion')
fastLength=input.int(20, title="FastEMA Length", group='Indicators: Waddah Attar Explosion')
slowLength=input.int(40, title="SlowEMA Length", group='Indicators: Waddah Attar Explosion')
channelLength=input.int(20, title="BB Channel Length", group='Indicators: Waddah Attar Explosion')
waeMult=input.float(2.0, title="BB Stdev Multiplier", group='Indicators: Waddah Attar Explosion')

calc_macd(source, fastLength, slowLength) =>
	fastMA = ta.ema(source, fastLength)
	slowMA = ta.ema(source, slowLength)
	fastMA - slowMA

calc_BBUpper(source, length, mult) => 
	basis = ta.sma(source, length)
	dev = mult * ta.stdev(source, length)
	basis + dev

calc_BBLower(source, length, mult) => 
	basis = ta.sma(source, length)
	dev = mult * ta.stdev(source, length)
	basis - dev

t1 = (calc_macd(close, fastLength, slowLength) - calc_macd(close[1], fastLength, slowLength))*sensitivity

e1 = (calc_BBUpper(close, channelLength, waeMult) - calc_BBLower(close, channelLength, waeMult))

trendUp = (t1 >= 0) ? t1 : 0
trendDown = (t1 < 0) ? (-1*t1) : 0

plot(trendUp, style=plot.style_columns, linewidth=1, color=(trendUp<trendUp[1]) ? color.lime : color.green, transp=45, title="UpTrend", display=display.none)
plot(trendDown, style=plot.style_columns, linewidth=1, color=(trendDown<trendDown[1]) ? color.orange : color.red, transp=45, title="DownTrend", display=display.none)
plot(e1, style=plot.style_line, linewidth=2, color=color.yellow, title="ExplosionLine", display=display.none)

// =============================================================================
// STRATEGY LOGIC
// =============================================================================

// QQE Mod
qqeGreenBar = Greenbar1 and Greenbar2
qqeRedBar = Redbar1 and Redbar2
qqeBuy = qqeGreenBar and not qqeGreenBar[1]
qqeSell = qqeRedBar and not qqeRedBar[1]

// SSL Hybrid
sslBuy = close > upperk and close > BBMC
sslSell = close < lowerk and close < BBMC

// Waddah Attar Explosion
waeBuy = trendUp > 0 and trendUp > e1
waeSell = trendDown > 0 and trendDown > e1

inLong = strategy.position_size > 0
inShort = strategy.position_size < 0

longCondition = qqeBuy and sslBuy and waeBuy and in_date_range
shortCondition = qqeSell and sslSell and waeSell and in_date_range

swingLow = ta.lowest(source=low, length=swingLength)
swingHigh = ta.highest(source=high, length=swingLength)

longStopPercent = math.abs((1 - (swingLow / close)) * 100)
shortStopPercent = math.abs((1 - (swingHigh / close)) * 100)

// Position sizing (default risk 2% per trade)
riskAmt = strategy.equity * accountRiskPercent / 100
longQty = math.abs(riskAmt / longStopPercent * 100) / close
shortQty = math.abs(riskAmt / shortStopPercent * 100) / close

if (longCondition and not inShort and not inLong)
    strategy.entry("Long", strategy.long, qty=longQty)
    strategy.exit("Long  SL/TP", from_entry="Long", stop=swingLow, alert_message='Long SL Hit')
    buyLabel = label.new(x=bar_index, y=high[1], color=color.green, style=label.style_label_up)
    label.set_y(id=buyLabel, y=0)
    label.set_tooltip(id=buyLabel, tooltip="Risk Amt: " + str.tostring(riskAmt) + " Qty: " + str.tostring(longQty) + " Swing low: " + str.tostring(swingLow) + " Stop Percent: " + str.tostring(longStopPercent))

if (shortCondition and not inLong and not inShort)
    strategy.entry("Short", strategy.short, qty=shortQty)
    strategy.exit("Short  SL/TP", from_entry="Short", stop=swingHigh, alert_message='Short SL Hit')
    sellLabel = label.new(x=bar_index, y=high[1], color=color.red, style=label.style_label_up)
    label.set_y(id=sellLabel, y=0)
    label.set_tooltip(id=sellLabel, tooltip="Risk Amt: " + str.tostring(riskAmt) + " Qty: " + str.tostring(shortQty) + " Swing high: " + str.tostring(swingHigh) + " Stop Percent: " + str.tostring(shortStopPercent))

openTradesInProfit() =>
    result = 0.
    for i = 0 to strategy.opentrades-1
        result += strategy.opentrades.profit(i)
    result > 0

exitLong = inLong and base_cross_Short and openTradesInProfit()
strategy.close(id = "Long", when = exitLong, comment = "Closing Long", alert_message="Long TP Hit")

exitShort = inShort and base_cross_Long and openTradesInProfit()
strategy.close(id = "Short", when = exitShort, comment = "Closing Short", alert_message="Short TP Hit")

// =============================================================================
// DATA WINDOW PLOTTING
// =============================================================================

plotchar(0, "===========", "", location = location.top, color=#141823)
plotchar(0, "BUY SIGNALS:", "", location = location.top, color=#141823)
plotchar(0, "===========", "", location = location.top, color=#141823)

plotchar(qqeBuy, "QQE Mod: Buy Signal", "", location = location.top, color=qqeBuy ? color.green : color.orange)
plotchar(sslBuy, "SSL Hybrid: Buy Signal", "", location = location.top, color=sslBuy ? color.green : color.orange)
plotchar(waeBuy, "Waddah Attar Explosion: Buy Signal", "", location = location.top, color=waeBuy ? color.green : color.orange)
plotchar(inLong, "inLong", "", location = location.top, color=inLong ? color.green : color.orange)
plotchar(exitLong, "Exit Long", "", location = location.top, color=exitLong ? color.green : color.orange)

plotchar(0, "============", "", location = location.top, color=#141823)
plotchar(0, "SELL SIGNALS:", "", location = location.top, color=#141823)
plotchar(0, "============", "", location = location.top, color=#141823)

plotchar(qqeSell, "QQE Mod: Sell Signal", "", location = location.top, color=qqeSell ? color.red : color.orange)
plotchar(sslSell, "SSL Hybrid: Sell Signal", "", location = location.top, color=sslSell ? color.red : color.orange)
plotchar(waeSell, "Waddah Attar Explosion: Sell Signal", "", location = location.top, color=waeSell ? color.red : color.orange)
plotchar(inShort, "inShort", "", location = location.top, color=inShort ? color.red : color.orange)
plotchar(exitShort, "Exit Short", "", location = location.top, color=exitShort ? color.red : color.orange)