
Отзывные данные показывают, что центральная логика этой комбинации стратегий EMA + HULL + ADX заключается в использовании механизма тройной фильтрации для повышения качества входа в игру. 20 циклов EMA определяет большое направление, 21 цикл Hull подтверждает силу тенденции, 14 циклов ADX фильтрует шокирующую ситуацию.
Однако, не стоит заблуждаться по поводу этого, казалось бы, простого соотношения прибыли и убытка. В реальной торговле 40-пунктный стоп может потребовать более длительного ожидания на некоторых сортах, в то время как 20-пунктный стоп может быть чаще задействован в условиях высокой волатильности.
ADX устанавливает 20 как порог интенсивности тренда, и этот параметр был выбран не зря. Когда ADX ниже 20, рынок обычно находится в состоянии поперечной сборки, и в это время сигналы EMA и Hull часто являются ложными прорывами. Исторические данные показывают, что сигнал с ADX выше 20 имеет вероятность выигрыша на 15-25% выше, чем сигнал без фильтрации.
Но здесь есть скрытый риск: ADX является отстающим индикатором, и, когда он подтверждает тренд, оптимальные точки входа могут быть пропущены. Поэтому стратегия разработана для опционального переключения ADX, и в некоторых быстро меняющихся рынках отключение фильтра ADX может привести к появлению большего количества возможностей за счет большего количества ложных сигналов.
Самой интересной частью стратегии является последовательный механизм фильтрации K-линий. Запрещается делать больше, когда появляются 3 или более последовательных солнечных линии; запрещается делать пустоту, когда появляются 3 или более последовательных солнечных линий. Это полностью противоречит инстинктам “погоня за тушью, чтобы убить падение”, но данные подтверждают, что это обратное мышление правильно.
Последовательное сближение с K-линией часто означает перераспределение краткосрочной динамики, в то время как вход в игру представляет собой риск технического отклонения. Опрос показал, что после включения этого фильтрационного условия максимальный отклонение стратегии снизилось примерно на 30%, хотя некоторые экстремальные тенденции могут быть пропущены, но прибыль после корректировки риска в целом значительно улучшилась.
Еще одним отличием этой стратегии является фильтрация на расстояние от EMA. Запрещается открывать позиции, когда цена находится на расстоянии от 20-циклической EMA более чем в 2 раза от ATR. Эта конструкция предотвращает импульсивную торговлю, когда цена сильно отклоняется от средней линии.
2 раза ATR - это оптимизированный коэффициент, в 1 раз слишком консервативный, чтобы пропустить много возможностей, и в 3 раза слишком свободный, чтобы не работать как фильтр. В практическом применении этот параметр может потребовать корректировки в разных разновидностях: валютные пары могут подходить в 1,5 - 2 раза, фондовые индексы могут потребовать 2,5 - 3 раза, криптовалюты могут потребовать 3-4 раза.
Hull Moving Average является ключевым техническим показателем этой стратегии, он реагирует быстрее, чем традиционная EMA, и может быстрее улавливать перемены в тренде. 21-циклическая настройка находит баланс между чувствительностью и стабильностью.
Но быстрая реакция Hull также является обоюдоострым мечом. В волатильных рынках Hull может производить больше изменений направления, что приводит к большему количеству фальшивых сигналов. Вот почему стратегия должна работать с ADX-фильтрацией и другими условиями.
С точки зрения применимых сценариев, портфель отлично работает в условиях четкой тенденции, особенно в течение суток и в коротких волнах. Фильтрация ADX гарантирует торговлю только в направленных рынках, а многократные условия фильтрации повышают качество сигнала.
Но слабость стратегии также очевидна: в поперечных колебательных рынках даже при наличии фильтрации ADX все равно может быть произведено некоторое количество ложных сигналов прорыва. 20-точный стоп может быть часто задействован в высокочастотных колебаниях, а 40-точный стоп трудно достичь в рынках, где отсутствует тенденция.
Существует очевидный риск потери этой стратегии, особенно при изменении рыночной обстановки. Последующие потери могут достигать 5-8 раз, а максимальное изъятие может превышать 15-20% от счета.
Рекомендуется контролировать риски в пределах 1-2% от счета за один раз и устанавливать максимальные лимиты вывода на уровне стратегии. При более чем трех последовательных убытках следует приостановить торговлю и переоценить рыночную обстановку.
/*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)")