Стратегия скальпинга с использованием тройной коррекции EMA

EMA ATR PULLBACK SCALPING
Дата создания: 2025-09-30 13:04:41 Последнее изменение: 2025-09-30 13:04:41
Копировать: 0 Количество просмотров: 443
2
Подписаться
319
Подписчики

Стратегия скальпинга с использованием тройной коррекции EMA Стратегия скальпинга с использованием тройной коррекции EMA

Тройная фильтрация 25/50/100 EMA - настоящая тенденция к отзыву

Перестаньте торговать с помощью единой равномерной линии. Эта стратегия использует три 25/50/100 EMA для построения полной системы идентификации тенденций, требуя, чтобы EMA были расположены в порядке и наклонены в одну сторону, а также требует минимального интервала в 0,10 раза ATR. Данные показывают, что этот трехкратный фильтрующий механизм эффективно избегает ложных прорывов в волатильных рынках и работает только в условиях реальной тенденции.

Ключ к “чистому расположению EMA”: 25>50>100 при многоголосном расположении и все сверху, 25<50<100 при пустом расположении и все сверху. Интервальные фильтры обеспечивают достаточно сильную тенденцию, чтобы избежать недействительного сигнала в состоянии равномерного сцепления.

Логика отклонения была разработана с точностью до 15 циклов, чтобы завершить обратное подтверждение

В основе стратегии лежит механизм обнаружения отступления. Многоголовное отступление требует, чтобы цена достигла 25 или 50 ЭМА, но оставалась выше 100 ЭМА, и пустое отступление требует, чтобы цена достигла 25 или 50 ЭМА, но оставалась ниже 100 ЭМА.

Установка 15-циклического окна отступления является разумной. Данные обратной связи показывают, что истинное отступление от тренда обычно завершается в течение 10-15 циклов, а отступление, превышающее это временное окно, часто означает, что тенденция может измениться.

Вход в систему строго контролируется, и вся линия K должна быть полностью отделена от 25EMA.

Условия ввода в игру очень строгие: после подтверждения закрытия линии K, вся линия K (открытая, высокая, низкая, закрытая) должна быть полностью расположена на правильной стороне 25EMA. Эта конструкция избегает ложных прорывов и шума в диске, гарантируя, что она будет включена только после подтверждения реального поворота.

Требования к многоголовному входу: открытие> 25EMA, минимум> 25EMA, закрытие> 25EMA. Требования к пустоголовому входу: открытие <25EMA, максимум <25EMA, закрытие <25EMA. Такой метод “целого подтверждения K-линии” значительно повышает качество входа и уменьшает количество недействительных сделок.

10% позиции + 0.05% комиссионных, для высокочастотных операций с отколовкой

Стратегия по умолчанию 10% позиции настройка умеренная, как получить достаточную прибыль и контролировать один риск … … … … … … … … … … … … … … … … … … … … … … … .

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

Применимые сценарии ясны, трендовые рынки отлично работают, но в условиях волатильности нужно быть осторожным

Стратегия отлично работает на рынках с ясным трендом, особенно подходит для одностороннего купли-продажи. Однако на рынках с горизонтальным колебанием сложно выполнить условия EMA, и у вас будет относительно мало возможностей для торговли. Это фактически является преимуществом стратегии, которая предотвращает чрезмерную торговлю в неблагоприятных условиях.

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

Исходный код стратегии
/*backtest
start: 2025-01-01 00:00:00
end: 2025-09-27 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Bybit","currency":"ETH_USDT","balance":500000}]
*/

//@version=6
strategy("Clean 25/50/100 EMA Pullback Scalper — Entries Only (Side Select)",
     overlay=true, calc_on_every_tick=true, calc_on_order_fills=true,
     initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.05,
     pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=10)

// === Side selector ===
side = input.string("Both", "Trade Side", options=["Both", "Long Only", "Short Only"])
longsEnabled  = side == "Both" or side == "Long Only"
shortsEnabled = side == "Both" or side == "Short Only"

// === Inputs ===
lenFast   = input.int(25,  "Fast EMA (pullback)", minval=1)
lenMid    = input.int(50,  "Mid EMA (filter)",    minval=1)
lenSlow   = input.int(100, "Slow EMA (safety)",   minval=1)

useSlope  = input.bool(true,  "Require EMAs sloping same way?")
useSpread = input.bool(true,  "Require clean spacing (min spread)?")
spreadPct = input.float(0.10, "Min spread vs ATR (0.10 = 0.10×ATR)", step=0.01, minval=0.0)

pullLookback = input.int(15, "Max bars after pullback", minval=1, maxval=100)
showSignals  = input.bool(true, "Show entry markers?")

// === Series ===
ema25  = ta.ema(close, lenFast)
ema50  = ta.ema(close, lenMid)
ema100 = ta.ema(close, lenSlow)
atr    = ta.atr(14)

// === Trend & spacing ===
isUpStack   = ema25 > ema50 and ema50 > ema100
isDownStack = ema25 < ema50 and ema50 < ema100
slopeUp     = ema25 > ema25[1] and ema50 > ema50[1] and ema100 > ema100[1]
slopeDown   = ema25 < ema25[1] and ema50 < ema50[1] and ema100 < ema100[1]

minGap = atr * spreadPct
spreadUpOK   = (ema25 - ema50) > minGap and (ema50 - ema100) > minGap
spreadDownOK = (ema100 - ema50) > minGap and (ema50 - ema25) > minGap

trendLongOK  = isUpStack   and (useSlope ? slopeUp   : true) and (useSpread ? spreadUpOK   : true)
trendShortOK = isDownStack and (useSlope ? slopeDown : true) and (useSpread ? spreadDownOK : true)

// === Pullback detection state ===
var bool  pullArmedLong   = false
var bool  pullArmedShort  = false
var int   pullBarIdxLong  = na
var int   pullBarIdxShort = na
var float pullMinLong     = na
var float pullMaxShort    = na

// Long pullback state
if trendLongOK
    touched25 = low <= ema25
    touched50 = low <= ema50
    stayedAbove100 = low > ema100
    if (touched25 or touched50) and stayedAbove100
        pullArmedLong  := true
        pullBarIdxLong := bar_index
        pullMinLong    := na(pullMinLong) ? low : math.min(pullMinLong, low)
    else if pullArmedLong
        pullMinLong := na(pullMinLong) ? low : math.min(pullMinLong, low)
        if low <= ema100 or (bar_index - pullBarIdxLong > pullLookback)
            pullArmedLong := false
            pullMinLong   := na
else
    pullArmedLong := false
    pullMinLong   := na

// Short pullback state
if trendShortOK
    touched25s = high >= ema25
    touched50s = high >= ema50
    stayedBelow100 = high < ema100
    if (touched25s or touched50s) and stayedBelow100
        pullArmedShort  := true
        pullBarIdxShort := bar_index
        pullMaxShort    := na(pullMaxShort) ? high : math.max(pullMaxShort, high)
    else if pullArmedShort
        pullMaxShort := na(pullMaxShort) ? high : math.max(pullMaxShort, high)
        if high >= ema100 or (bar_index - pullBarIdxShort > pullLookback)
            pullArmedShort := false
            pullMaxShort   := na
else
    pullArmedShort := false
    pullMaxShort   := na

// === Entry triggers (confirmed bar & whole candle outside 25 EMA) ===
longEntryRaw  = pullArmedLong  and barstate.isconfirmed and (open > ema25 and low > ema25 and close > ema25) and (na(pullMinLong)  or pullMinLong  > ema100)
shortEntryRaw = pullArmedShort and barstate.isconfirmed and (open < ema25 and high < ema25 and close < ema25) and (na(pullMaxShort) or pullMaxShort < ema100)

longEntry  = longsEnabled  and longEntryRaw
shortEntry = shortsEnabled and shortEntryRaw

// Disarm after trigger
if longEntry
    pullArmedLong := false
    pullMinLong   := na
if shortEntry
    pullArmedShort := false
    pullMaxShort   := na

// === Orders (entries only; no TP/SL) ===
if longEntry and strategy.position_size <= 0
    strategy.entry("Long", strategy.long)

if shortEntry and strategy.position_size >= 0
    strategy.entry("Short", strategy.short)

// === Plots & visuals ===
plot(ema25,  "EMA 25",  color=color.new(color.teal, 0))
plot(ema50,  "EMA 50",  color=color.new(color.orange, 0))
plot(ema100, "EMA 100", color=color.new(color.purple, 0))

bgcolor(trendLongOK  ? color.new(color.green, 92) : na)
bgcolor(trendShortOK ? color.new(color.red, 92)   : na)

if showSignals and longEntry
    label.new(bar_index, low, "▲ BUY\nFull candle above 25 EMA", style=label.style_label_up, textcolor=color.white, color=color.new(color.green, 0))
if showSignals and shortEntry
    label.new(bar_index, high, "▼ SELL\nFull candle below 25 EMA", style=label.style_label_down, textcolor=color.white, color=color.new(color.red, 0))