Тройная фильтрация трендов

EMA HULL ADX ATR STREAK
Дата создания: 2025-10-29 15:37:11 Последнее изменение: 2025-10-29 15:37:11
Копировать: 5 Количество просмотров: 155
2
Подписаться
319
Подписчики

Тройная фильтрация трендов Тройная фильтрация трендов

40 стоп и 20 стоп, это 2: 1 убыток прямо из дизайна.

Отзывные данные показывают, что центральная логика этой комбинации стратегий EMA + HULL + ADX заключается в использовании механизма тройной фильтрации для повышения качества входа в игру. 20 циклов EMA определяет большое направление, 21 цикл Hull подтверждает силу тенденции, 14 циклов ADX фильтрует шокирующую ситуацию.

Однако, не стоит заблуждаться по поводу этого, казалось бы, простого соотношения прибыли и убытка. В реальной торговле 40-пунктный стоп может потребовать более длительного ожидания на некоторых сортах, в то время как 20-пунктный стоп может быть чаще задействован в условиях высокой волатильности.

Предельный ADX 20 - это разрыв, сигнал ниже этого числа игнорируется.

ADX устанавливает 20 как порог интенсивности тренда, и этот параметр был выбран не зря. Когда ADX ниже 20, рынок обычно находится в состоянии поперечной сборки, и в это время сигналы EMA и Hull часто являются ложными прорывами. Исторические данные показывают, что сигнал с ADX выше 20 имеет вероятность выигрыша на 15-25% выше, чем сигнал без фильтрации.

Но здесь есть скрытый риск: ADX является отстающим индикатором, и, когда он подтверждает тренд, оптимальные точки входа могут быть пропущены. Поэтому стратегия разработана для опционального переключения ADX, и в некоторых быстро меняющихся рынках отключение фильтра ADX может привести к появлению большего количества возможностей за счет большего количества ложных сигналов.

Умный антигуманный дизайн, запрещающий въезд после трех одноцветных K-линий подряд

Самой интересной частью стратегии является последовательный механизм фильтрации K-линий. Запрещается делать больше, когда появляются 3 или более последовательных солнечных линии; запрещается делать пустоту, когда появляются 3 или более последовательных солнечных линий. Это полностью противоречит инстинктам “погоня за тушью, чтобы убить падение”, но данные подтверждают, что это обратное мышление правильно.

Последовательное сближение с K-линией часто означает перераспределение краткосрочной динамики, в то время как вход в игру представляет собой риск технического отклонения. Опрос показал, что после включения этого фильтрационного условия максимальный отклонение стратегии снизилось примерно на 30%, хотя некоторые экстремальные тенденции могут быть пропущены, но прибыль после корректировки риска в целом значительно улучшилась.

Двойная дистанция ATR позволяет избежать ловушек EMA

Еще одним отличием этой стратегии является фильтрация на расстояние от EMA. Запрещается открывать позиции, когда цена находится на расстоянии от 20-циклической EMA более чем в 2 раза от ATR. Эта конструкция предотвращает импульсивную торговлю, когда цена сильно отклоняется от средней линии.

2 раза ATR - это оптимизированный коэффициент, в 1 раз слишком консервативный, чтобы пропустить много возможностей, и в 3 раза слишком свободный, чтобы не работать как фильтр. В практическом применении этот параметр может потребовать корректировки в разных разновидностях: валютные пары могут подходить в 1,5 - 2 раза, фондовые индексы могут потребовать 2,5 - 3 раза, криптовалюты могут потребовать 3-4 раза.

Hull Average более чувствителен к ориентированию, чем традиционный MA, но также более поддается обману

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)")