
La lógica central de esta combinación de estrategias EMA+HULL+ADX es la de utilizar un mecanismo de triple filtración para mejorar la calidad de entrada. El EMA de 20 períodos determina la dirección general, el Hull de 21 períodos confirma la intensidad de la tendencia, y el ADX de 14 períodos filtra las situaciones de choque. Lo más importante es que el TP de 40 puntos se corresponde con el SL de 20 puntos, con una relación de riesgo-rentabilidad de 2: 1, que en la estrategia cuantitativa es una configuración relativamente radical pero razonable.
Sin embargo, no te dejes engañar por esta aparentemente simple comparación de ganancias y pérdidas. En el comercio real, un stop de 40 puntos puede requerir una espera más larga en ciertas variedades, mientras que un stop de 20 puntos puede ser activado con frecuencia en un entorno de alta volatilidad. El verdadero rendimiento de la estrategia depende en gran medida de la variedad específica y el marco de tiempo en el que usted negocia.
El ADX establece el 20 como umbral de la intensidad de la tendencia, por lo que la elección de este parámetro es justificada. Cuando el ADX es inferior a 20, el mercado suele estar en un estado de ordenamiento horizontal, y las señales de EMA y Hull a menudo son falsas rupturas. Los datos históricos muestran que las señales con un ADX superior a 20 tienen una probabilidad de victoria del 15-25% más alta que las señales sin filtro.
Pero aquí hay un riesgo oculto: el ADX es un indicador atrasado, y cuando confirma una tendencia, el punto de entrada óptimo puede haberse perdido. Por lo tanto, la estrategia diseñó un interruptor ADX opcional, y en algunos mercados que cambian rápidamente, el cierre del filtro ADX podría capturar más oportunidades a costa de más señales falsas.
La parte más interesante de la estrategia es el mecanismo de filtración de K-lineas consecutivas. Se prohíbe hacer más cuando hay 3 o más líneas positivas consecutivas; se prohíbe hacer vacío cuando hay 3 o más líneas negativas consecutivas. Esto es totalmente contrario a la instinto de “perseguir y matar a la caída”, pero los datos demuestran que este pensamiento inverso es correcto.
La continuidad con la línea K suele significar una liberación excesiva de la dinámica a corto plazo, en la que la entrada se enfrenta a un riesgo de reajuste técnico. La retrospectiva muestra que después de agregar esta condición de filtro, la reversión máxima de la estrategia se reduce en aproximadamente un 30%, aunque puede perderse algunas situaciones de tendencia extrema, pero el rendimiento se mejora significativamente después de ajustar el riesgo general.
El filtro de la distancia entre EMAs es otro de los puntos fuertes de esta estrategia. Se prohíbe abrir una posición cuando el precio está a más de 2 veces ATR de la distancia entre la EMA de 20 ciclos. Este diseño evita el impulso de negociación cuando el precio se desvía gravemente de la línea media.
2 veces el ATR es un factor optimizado, 1 vez demasiado conservador pierde muchas oportunidades, 3 veces demasiado flexible no sirve de filtro. En la práctica, este parámetro puede necesitar ajustes en diferentes variedades: los pares de divisas pueden ser de 1.5 a 2 veces, los futuros de índices de acciones pueden necesitar 2.5 a 3 veces, y las criptomonedas pueden necesitar 3-4 veces.
El promedio móvil de Hull, el indicador técnico central de esta estrategia, es más rápido que los EMA tradicionales para reaccionar y captar el cambio de tendencia antes. La configuración de 21 ciclos encuentra el punto de equilibrio entre sensibilidad y estabilidad.
Pero la rápida reacción de Hull también es un arma de doble filo. En un mercado convulso, Hull produce más cambios de dirección, lo que provoca más falsas señales. Por eso la estrategia debe estar acompañada de filtros ADX y otras condiciones, y la probabilidad de ganar con la señal de Hull solo puede ser del 45-50%
Desde el punto de vista de los escenarios de aplicación, esta combinación se destaca en situaciones de tendencias claras, especialmente en el segmento de intradiario y de ondas cortas. El filtro ADX asegura que se negocie solo en mercados direccionales, y las condiciones de filtración múltiple mejoran la calidad de la señal.
Pero la debilidad de la estrategia también es evidente: en mercados de oscilación horizontal, incluso con filtros ADX, se producen algunas falsas señales de ruptura. Los paros de 20 puntos pueden ser activados con frecuencia en oscilaciones de alta frecuencia, mientras que los paros de 40 puntos son difíciles de alcanzar en mercados sin tendencia.
Esta estrategia presenta un riesgo evidente de pérdidas, especialmente cuando se produce un cambio en el entorno del mercado. Las pérdidas consecutivas pueden llegar a 5-8 veces, y el retiro máximo puede superar el 15-20% de la cuenta. El rendimiento en diferentes entornos del mercado varía mucho y es necesario ajustar los parámetros o suspender el uso según las circunstancias reales.
Se recomienda que el riesgo individual se controle dentro del 1-2% de la cuenta y se establezca un límite máximo de retiro a nivel de estrategia. Si hay más de 3 pérdidas consecutivas, se debe suspender la negociación y volver a evaluar el entorno del mercado.
/*backtest
start: 2025-10-18 00:00:00
end: 2025-10-27 08:00:00
period: 5m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDT"}]
*/
//@version=6
strategy("Iriza4 - DAX EMA+HULL+ADX TP40 SL20 (Streak & EMA/ATR Distance Filter)", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=1)
// === INPUTS ===
emaLen = input.int(20, "EMA Length")
hullLen = input.int(21, "HULL Length")
adxLen = input.int(14, "ADX Length")
adxThreshold = input.float(20, "ADX Threshold")
useADX = input.bool(true, "Use ADX filter (entry only)")
tpPoints = input.int(40, "TP (points)")
slPoints = input.int(20, "SL (points)")
// Filters
atrLen = input.int(14, "ATR Length")
atrMult = input.float(2.0, "Max distance from EMA (ATR multiples)")
maxBullStreak= input.int(3, "Block LONG if ≥ this many prior bull bars")
maxBearStreak= input.int(3, "Block SHORT if ≥ this many prior bear bars")
// === FUNCTIONS ===
// Hull Moving Average (HMA)
hma(src, length) =>
half = math.round(length / 2)
sqrt_l = math.round(math.sqrt(length))
w1 = ta.wma(src, half)
w2 = ta.wma(src, length)
ta.wma(2 * w1 - w2, sqrt_l)
// ADX (Wilder) manual calc
calc_adx(len) =>
upMove = ta.change(high)
downMove = -ta.change(low)
plusDM = na(upMove) ? na : (upMove > downMove and upMove > 0 ? upMove : 0)
minusDM = na(downMove) ? na : (downMove > upMove and downMove > 0 ? downMove : 0)
tr = ta.tr(true)
trRma = ta.rma(tr, len)
plusDI = 100 * ta.rma(plusDM, len) / trRma
minusDI = 100 * ta.rma(minusDM, len) / trRma
dx = 100 * math.abs(plusDI - minusDI) / (plusDI + minusDI)
ta.rma(dx, len)
// === INDICATORS ===
ema = ta.ema(close, emaLen)
hull = hma(close, hullLen)
adx = calc_adx(adxLen)
atr = ta.atr(atrLen)
// HULL slope state
var float hull_dir = 0.0
hull_dir := hull > hull[1] ? 1 : hull < hull[1] ? -1 : hull_dir
// === STREAKS (consecutive bull/bear bars BEFORE current bar) ===
var int bullStreak = 0
var int bearStreak = 0
bullStreak := close[1] > open[1] ? bullStreak[1] + 1 : 0
bearStreak := close[1] < open[1] ? bearStreak[1] + 1 : 0
blockLong = bullStreak >= maxBullStreak
blockShort = bearStreak >= maxBearStreak
// === EMA DISTANCE FILTER ===
distFromEMA = math.abs(close - ema)
farFromEMA = distFromEMA > atrMult * atr
// === ENTRY CONDITIONS ===
baseLong = close > ema and hull_dir == 1 and (not useADX or adx > adxThreshold)
baseShort = close < ema and hull_dir == -1 and (not useADX or adx > adxThreshold)
longSignal = barstate.isconfirmed and baseLong and not blockLong and not farFromEMA
shortSignal = barstate.isconfirmed and baseShort and not blockShort and not farFromEMA
// === ENTRIES ===
if (longSignal and strategy.position_size == 0)
strategy.entry("Long", strategy.long)
if (shortSignal and strategy.position_size == 0)
strategy.entry("Short", strategy.short)
// === EXITS === (no partials, no breakeven)
if (strategy.position_size > 0)
entryPrice = strategy.position_avg_price
strategy.exit("Exit Long", from_entry="Long", stop=entryPrice - slPoints, limit=entryPrice + tpPoints)
if (strategy.position_size < 0)
entryPrice = strategy.position_avg_price
strategy.exit("Exit Short", from_entry="Short", stop=entryPrice + slPoints, limit=entryPrice - tpPoints)
// === VISUALS ===
plot(ema, color=color.orange, title="EMA 20")
plot(hull, color=hull_dir == 1 ? color.green : color.red, title="HULL 21")
plot(adx, title="ADX 14", color=color.new(color.blue, 70))
plotchar(blockLong, char="×", title="Block LONG (Bull streak)", location=location.top, color=color.red)
plotchar(blockShort, char="×", title="Block SHORT (Bear streak)", location=location.bottom,color=color.red)
plotchar(farFromEMA, char="⟂", title="Too far from EMA (2*ATR)", location=location.top, color=color.orange)
plotshape(longSignal and strategy.position_size == 0, title="Iriza4 Long", style=shape.triangleup, location=location.belowbar, size=size.tiny, color=color.green)
plotshape(shortSignal and strategy.position_size == 0, title="Iriza4 Short", style=shape.triangledown, location=location.abovebar, size=size.tiny, color=color.red)
bgcolor(strategy.position_size > 0 ? color.new(color.green, 92) : strategy.position_size < 0 ? color.new(color.red, 92) : na)
// === ALERTS ===
alertcondition(longSignal, title="Iriza4 Long", message="Iriza4 LONG (streak & EMA/ATR filter)")
alertcondition(shortSignal, title="Iriza4 Short", message="Iriza4 SHORT (streak & EMA/ATR filter)")