Stratégie de scalping de retracement Triple EMA

EMA ATR PULLBACK SCALPING
Date de création: 2025-09-30 13:04:41 Dernière modification: 2025-09-30 13:04:41
Copier: 0 Nombre de clics: 443
2
Suivre
319
Abonnés

Stratégie de scalping de retracement Triple EMA Stratégie de scalping de retracement Triple EMA

25/50/100 EMA triple filtration, c’est vraiment une tendance à la retraite

Cette stratégie consiste à construire un système de détection de tendance complet avec trois EMA de 25/50/100, exigeant que les EMA soient alignées dans l’ordre et inclinées dans la même direction, ainsi qu’une exigence d’intervalle minimum de 0,10 fois l’ATR. Les données montrent que ce triple filtre est efficace pour éviter les fausses ruptures dans les marchés volatiles et ne fonctionne que lorsque la tendance est réelle.

La clé réside dans un “arrangement EMA propre”: 25>50>100 avec une inclinaison totale vers le haut en cas de multiples, 25<50<100 avec une inclinaison totale vers le bas en cas d’une inclinaison nulle. Le filtrage d’intervalle assure une tendance suffisamment forte pour éviter des signaux inefficaces dans un état de collision uniforme.

Logique de rétractation conçue avec précision, confirmation de rétractation à 15 cycles

Le cœur de la stratégie est le mécanisme de détection des retraits. Les retraits à plusieurs têtes exigent que les prix touchent 25 ou 50 EMA mais restent au-dessus de 100 EMA, et les retraits à tête vide exigent que les prix touchent 25 ou 50 EMA mais restent en dessous de 100 EMA. Cette conception est plus précise que le traditionnel “ retrait de support et achat “.

Le réglage de la fenêtre de rétractation de 15 cycles est raisonnable. Les données de retracement montrent que la véritable rétractation de tendance est généralement terminée dans un délai de 10 à 15 cycles, et une rétractation au-delà de cette fenêtre de temps signifie souvent qu’une modification de tendance est possible.

Le mécanisme de confirmation d’entrée est strict et la ligne K doit être complètement déconnectée de 25EMA.

Les conditions de déclenchement de l’entrée sont extrêmement strictes: après la confirmation de la fermeture de la ligne K, l’ensemble de la ligne K (ouverture, haut, bas, fermeture) doit être complètement situé du bon côté de la 25EMA. Cette conception évite les fausses percées et le bruit dans la disque, assurant l’entrée en jeu uniquement après la confirmation d’un véritable renversement.

Les conditions d’entrée à plusieurs têtes sont les suivantes: ouverture <25EMA, minimum >25EMA, clôture >25EMA. Conditions d’entrée à vide: ouverture <25EMA, maximum <25EMA, clôture <25EMA. Cette méthode de “confirmation de ligne K entière” améliore considérablement la qualité de l’entrée et réduit les transactions invalides.

10% de la position + 0,05% de frais de traitement, adapté aux opérations d’épluchage à haute fréquence

La stratégie de mise en position par défaut de 10% est modérée, permettant à la fois de générer des gains suffisants et de contrôler les risques individuels. La mise en place de frais de traitement de 0,05% est proche du coût réel de la transaction, les résultats de retracement sont plus utiles.

Remarque importante: la stratégie ne contient que la logique d’entrée et ne contient pas de stop loss. L’utilisation en ligne doit être accompagnée d’une gestion des risques stricte, il est recommandé de définir un stop loss de 2 à 3 fois l’ATR et un stop loss de 1,5 à 2 fois le rapport de risque / rendement.

Les scénarios sont clairs, le marché tendanciel est bon, mais les marchés volatiles doivent être prudents

Les stratégies fonctionnent bien dans les marchés clairement tendanciels et sont particulièrement adaptées aux achats et retours unilatéraux. Cependant, dans les marchés horizontalement volatiles, les conditions de classement des EMA sont difficiles à satisfaire et les opportunités de négociation sont relativement rares.

Remarque de risque: la rétroaction historique ne représente pas les gains futurs, la stratégie présente un risque de pertes continues. Les marchés en crise peuvent être en état de non-signal pendant une longue période, il faut attendre patiemment l’environnement de marché approprié.

Code source de la stratégie
/*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))