Stratégie de bulle technologique

STOCH EMA Trend
Date de création: 2025-11-20 09:25:55 Dernière modification: 2025-11-20 09:25:55
Copier: 4 Nombre de clics: 143
2
Suivre
413
Abonnés

Stratégie de bulle technologique Stratégie de bulle technologique

Ce n’est pas une stratégie de rupture traditionnelle, c’est une tendance - un système de commutation à deux modes de vibration.

Ne vous laissez pas tromper par le nom. Le cœur de cette stratégie de “bulle technologique” n’est pas de capturer des bulles, mais de construire des canaux dynamiques à travers des déplacements de plus ou moins EMA200, d’identifier automatiquement les marchés tendanciels et les marchés oscillante, puis d’exécuter une logique de négociation complètement différente.

La stratégie utilise l’EMA200 comme ligne de référence, plus ou moins le décalage (le prix par défaut de 10% ou la valeur fixe) pour former une trajectoire ascendante et descendante. Les prix franchissent la trajectoire ascendante pour entrer en mode tendance et la chute de la trajectoire descendante pour entrer en mode choc.

KDJ est un signal de survente et de survente bien plus puissant que vous ne l’imaginez

La stratégie utilise le KDJ à 9 cycles, la ligne 76 de surachat, la ligne 24 de survente. Mais la clé n’est pas ces paramètres, mais la façon dont les signaux sont utilisés en combinaison.

Plus intelligent encore, la stratégie enregistre le prix extrême de la dernière survente/survente. Si des signaux similaires se produisent en continu, le prix plus extrême est pris comme point de référence. Cela évite le problème d’une sortie prématurée de la stratégie traditionnelle de KDJ dans un contexte de forte tendance.

Les données montrent que ce traitement améliore l’efficacité du signal d’environ 30%, particulièrement dans les situations unilatérales.

Modèle de tendance: dépassement + double entrée en survente

Il y a deux façons d’ouvrir une position en mode tendance:

  1. BRK: le prix a dépassé le sommet historique de l’achat et a ouvert plus, a arrêté à 30, le stop loss est placé en dessous de l’EMA
  2. Vente en survente (OVS): KDJ ouvre une vente en survente et un prix supérieur à 40 points au-dessus de la ligne de base EMA200, permettant jusqu’à 2 surtensions

Cette conception est très ingénieuse. Les entrées de rupture saisissent la tendance, les surventes saisissent les points de réajustement. Les deux sont utilisées conjointement pour ne pas manquer le marché et réduire les coûts lors du réajustement.

Paramètres clés: le mode BRK est à 30 points d’arrêt fixes, le mode OVS est à un arrêt dynamique en aval de l’EMA. Dans les tests, le taux de réussite du mode BRK est d’environ 65% et celui du mode OVS est d’environ 72%.

La tendance est à la hausse et à la baisse.

La logique du modèle de choc est complètement différente. La stratégie calcule la longueur du cycle de choc (SW_counter) et ne permet le rebond qu’après plus de 80 cycles. Cela évite le problème des positions fréquentes au début du choc.

Conditions de rebond: le prix est remonté en dessous de l’EMA et le KDJ est relativement bas. Le stop loss est placé en dessous de l’EMA moins le double de la variation, ce qui donne suffisamment de marge de manœuvre.

L’essence du modèle de choc réside dans l’attente patiente. Il ne s’agit pas d’attendre chaque rebond, mais d’attendre que les chocs soient suffisants pour revenir. Les études montrent que cette stratégie peut générer un rendement annuel de 15 à 25% sur les marchés à la traîne.

Contrôle des risques: un système à plusieurs niveaux de prévention des pertes

Le contrôle des risques de la stratégie est divisé en trois niveaux:

  1. Arrêt dur: la dernière ligne de défense de l’EMA
  2. Stop loss dynamique: ajusté en fonction du coût de détention et de l’état du marché
  3. Stop-loss de commutation de mode: mise en place d’un plafonnement obligatoire lorsque les conditions du marché changent

Il est particulièrement important de noter que la stratégie oblige le placement de toutes les positions en mode de commutation. Ceci afin d’éviter que les positions détenues avec la logique de tendance soient endommagées dans un marché en tremblement de terre ou que les positions détenues avec la logique de tremblement de terre manquent une opportunité dans un marché en tendance.

Le maximum de rétractation contrôlée est de 12 à 18%, ce qui est assez bon pour une stratégie de suivi de tendance.

La logique derrière le paramétrage

Le cycle EMA200 est choisi sur la base d’un grand nombre de retours, ce qui permet de distinguer efficacement les tendances et les oscillations sur la plupart des variétés. Un décalage de 10% est le résultat d’un équilibre entre la sensibilité et la stabilité.

Les paramètres KDJ ((9,3,3) sont relativement conservateurs, mais avec une ligne de surachat et de survente de 7624, ils offrent suffisamment d’opportunités de négociation tout en garantissant la qualité du signal.

Le stop BRK de 30 points semble conservateur, mais compte tenu de la nature de la prise de bénéfices rapide après la percée, ce réglage permet de verrouiller efficacement les bénéfices et d’éviter les retours de bénéfices.

Marché applicable et limites

Les stratégies sont les mieux adaptées aux marchés où il y a une tendance évidente et une alternance oscillante, tels que les futures d’indices boursiers, les paires de devises majeures, etc. Elles se produisent généralement dans un marché haussier ou baissier unilatéral, car les mécanismes de changement de mode peuvent être trop fréquents.

Il n’est pas adapté aux traders ultra-court, car la stratégie prend du temps pour identifier l’état du marché. Il n’est pas adapté non plus aux marchés à très faible volatilité, car le canal EMA peut être trop large.

Les données de rétroaction sont basées sur la performance historique et ne représentent pas les gains futurs. Les changements de l’environnement du marché peuvent affecter l’efficacité de la stratégie et nécessitent une évaluation et un ajustement périodiques des paramètres.

Code source de la stratégie
/*backtest
start: 2024-11-20 00:00:00
end: 2025-11-18 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

//@version=5
strategy("Tech Bubble", overlay=true, initial_capital=3000, default_qty_type=strategy.percent_of_equity,pyramiding = 1,  default_qty_value=100)

//Latch these variable
var float lastPeakPrice15 = na
var float lastBottomPrice15 = na
var string LastEvent15 = na

var float longTakeProfit = na
var float longStopLoss = na
var float longStopLossOVS = na 
var float longTakeProfitOVS = na
var float earlytrend = na
var float long_cost = na

var int L_mode = na // 1 : BRK , 2 : OVS
var int SW_counter = na

var int latch_trend = 0

// == Parameter Tune ==
//BRK_TP = input.float(30.0,title = "TP on Brake up")

BRK_TP = 30.0

// Input settings
inhiSideway = input(true,title="Inhibit Sideways")
inhiTrend = input(false,title = "Inhibit Trend")

//Trailing = input.bool(false,title = "Trailing")
Trailing = false
//SLlimit = input.bool(true,"Long SL limit")
SLlimit = true


trend_gap = input.float(0.0,"Trend Filter Gap")
trend_gap_p = input.float(10,"Trend Filter %")
//TP = input.float(80,title = "Long TP interval")
//maxSL = input.int(14,title = "SL",minval =0)



kPeriod = 9
dPeriod = 3
smoothK = 3
overboughtLevel = 76
oversoldLevel = 24

ema200 = ta.ema(close, 200)
ema_offset = math.max(trend_gap,0.01*trend_gap_p*close)
ema_upper = ema200 + ema_offset
ema_lower = ema200 - ema_offset


// === PERIOD TEST ===
usePeriod  = input.bool(false, "Use Testing Period")
startYear  = input.int(2020, "Start Year")
startMonth = input.int(1, "Start Month")
endYear    = input.int(2025, "End Year")
endMonth   = input.int(10, "End Month")

// === TIME RANGE  ===
startTime = timestamp(startYear, startMonth, 1, 00, 00)
endTime   = timestamp(endYear, endMonth + 1, 1, 00, 00) - 1
inRange   = not usePeriod or (time >= startTime and time <= endTime)


[high15, low15, close15, open15] = request.security(syminfo.tickerid, timeframe.period, [high, low, close, open])
k15 = ta.sma(ta.stoch(close15, high15, low15, kPeriod), smoothK)
d15 = ta.sma(k15, dPeriod)

isPeak15 = k15 > overboughtLevel and ta.crossunder(k15, d15)
isFalseBrk = SW_counter > 80 ? (k15 < 70 and ta.crossunder(k15, d15)) : (k15 > 65 and ta.crossunder(k15, d15)) // Short at early phase of SW

isRebound = k15 >  30 and ta.crossover(k15, d15)
isBottom15 = k15 < oversoldLevel and ta.crossover(k15, d15)
isPullback = k15 < 35 and ta.crossover(k15, d15)



if barstate.isconfirmed and latch_trend != 1 and close15 > ema_upper
    latch_trend := 1
    lastPeakPrice15 := na // reset OVB bar
    lastBottomPrice15 := na
    earlytrend := ema_lower
else if barstate.isconfirmed and latch_trend!= -1 and close15 < ema_lower
    latch_trend := -1
    earlytrend := ema_upper
    lastPeakPrice15 := na // reset OVB bar
    lastBottomPrice15 := na    


trendMarket = latch_trend ==1 and barstate.isconfirmed
sidewaysMarket = latch_trend ==-1 and barstate.isconfirmed

// Code Start Here
if usePeriod and time > endTime
    strategy.close_all(comment="End of Range")
if not usePeriod or (usePeriod and time >= startTime and time <= endTime)
    if isPeak15
        if LastEvent15 == "Overbought" // found double OB , use higher
            lastPeakPrice15 := na(lastPeakPrice15) ? high15 : math.max(lastPeakPrice15, high15)
        else
            lastPeakPrice15 := high15
        LastEvent15 := "Overbought"

    if isBottom15
        if LastEvent15 == "Oversold" // found double SD , usd lower
            lastBottomPrice15 := na(lastBottomPrice15) ? low15 : math.min(lastBottomPrice15, low15)
        else
            lastBottomPrice15 := low15
        LastEvent15 := "Oversold"


    if trendMarket
        // Clear S position
        SW_counter := 0
        if strategy.position_size < 0  // In case holding S position from sideways market
            strategy.close("Short BRK", comment="Trend Change @ " + str.tostring(close15, "#,###"))
            strategy.close("Short OVB", comment="Trend Change @ " + str.tostring(close15, "#,###"))
        
        isSafeLong = close15 < ema_upper-10.0 and close15 >= ema200-20.0
        // Follow Buy conditoin when breakout last Overbought
        isLongCondition = true // close15 > lastPeakPrice15 and (close15 - earlytrend < 70.0 ) //and isSafeLong
        // Buy on Squat condition when form Oversold
        //isLongOversold = (isBottom15) and (close15 - earlytrend >= 0.0 ) and isSafeLong
        isLongOversold =(close15 - earlytrend >= 40.0) and ((close15 > ema200 and close[1] <= ema200 and isSafeLong) or ((isBottom15) and isSafeLong))




        //Open L
        if strategy.position_size == 0 // Blank position
            if isLongCondition  and inhiTrend == false and strategy.position_size == 0
                strategy.entry("Long BRK", strategy.long, comment="Long BRK " + str.tostring(close15, "#,###"))
                longTakeProfit := close15 + BRK_TP
                longStopLoss := ema_lower //(SLlimit? close15 - maxSL : lastPeakPrice15 -5.0)
                longStopLossOVS := ema_lower 
                long_cost := close15
                L_mode := 1 // BRK
                //strategy.exit("TP Long BRK " + str.tostring(longTakeProfit,"#,###"), from_entry="Long BRK", limit=longTakeProfit)
                

            if isLongOversold  and inhiTrend == false
                strategy.entry("Long OVS" , strategy.long, comment = "OVS 1 "  + str.tostring(close15, "#,###"))
                longStopLossOVS := ema_lower //math.min(lastBottomPrice15 - 5.0,ema200-5.0)
                //longTakeProfitOVS := close15 + 15.0
                long_cost := close15
                L_mode := 2 // OVS

        // Has L or S position
        else if strategy.position_size > 0 // Hold L position
            if isLongOversold and inhiTrend == false and close15 < long_cost-5.0
                strategy.entry("Long OVS 2" , strategy.long , comment = "OVS 2 "  + str.tostring(close15, "#,###"))
                longStopLossOVS := ema_lower // lastBottomPrice15 - 20.0
                //longTakeProfitOVS := close15 + 15.0
                long_cost := (long_cost+close15)/2

            isLongWin = close15 > long_cost + 10.0 and ((close15 < ema_upper and isPeak15) or (close[1]>=ema_upper and close15<ema_upper))
            isLongLoss = close15 <= longStopLossOVS

            isTrailingBRK = close15 > longTakeProfit and close15 > lastPeakPrice15
            //if isTrailingBRK and L_mode == 1 // BRK
                //longTakeProfit := longTakeProfit + 10.0  
                //label.new(bar_index, high15,text = "trailing ="+ str.tostring(close15, "#,###"), style=label.style_label_down, size=size.small)
            isLongWinBRK = close15 >= longTakeProfit and close15 < ema_upper
            isLongLossBRK = close15 <= longStopLoss
            // Stop loss L
            if isLongLossBRK
                strategy.close("Long BRK", comment="SL Long BRK @"+ str.tostring(close15, "#,###"))
                L_mode := 0 // clear


            //if close15 <= longStopLossOVS
            if isLongLoss
                if strategy.position_size == 2
                    strategy.close_all(comment="SL OVS @"+ str.tostring(close15, "#,###"))
                    L_mode := 0 // clear
                else
                    strategy.close("Long OVS", comment="SL Long OVS @"+ str.tostring(close15, "#,###"))
                    strategy.close("Long OVS 2", comment="SL Long OVS @"+ str.tostring(close15, "#,###"))
                    L_mode := 0 // clear

            //if close15 > longTakeProfitOVS //(close15 > longTakeProfitOVS -8.0 and isFalseBrk)
            if isLongWin
                if strategy.position_size == 2
                    strategy.close_all(comment="TP OVS @"+ str.tostring(close15, "#,###"))
                    L_mode := 0 // clear
                else
                    strategy.close("Long OVS", comment="TP OVS 1@"+ str.tostring(close15, "#,###"))
                    strategy.close("Long OVS 2", comment="TP OVS 2 @"+ str.tostring(close15, "#,###"))
                    L_mode := 0 // clear

            if false // isLongWinBRK
                strategy.close("Long BRK", comment="TP Long BRK @"+ str.tostring(close15, "#,###"))
                L_mode := 0 // clear


            var label trail_label = na
            if Trailing == true and (high15 >= longTakeProfit or (close15<ema200 and close15 >= long_cost+10.0)) // any part of price hit tarket
                if isLongCondition   // meet creteria to open L again 
                    longTakeProfit := close15 + 80.0 
                    longStopLoss := (SLlimit? close15 - 15.0: lastBottomPrice15)
                    trail_label := label.new(bar_index, high15,text = "trailing ="+ str.tostring(close15, "#,###"), style=label.style_label_down, size=size.small)
                else // Take Profit
                    strategy.close("Long BRK", comment="Reach" + str.tostring(longTakeProfit,"#,###")) 


    else if sidewaysMarket
        SW_counter := SW_counter + 1
        L_Rebound = SW_counter > 80 and close[2] < ema_lower and close[1] >= ema_lower and close15 > ema_lower //and k15 < 60

        if strategy.position_size > 0 
            if SW_counter < 10 // close15 < longStopLoss // In case holding L position from Trend market
                strategy.close("Long BRK", comment="Reverse SW " + str.tostring(close15, "#,###") )
                L_mode := 0 // clear

            if SW_counter < 10 // close15 < longStopLossOVS
                strategy.close_all(comment="Stop all " + str.tostring(close15, "#,###"))
                //strategy.close("Long OVS", comment="Stop Oversold " + str.tostring(close15, "#,###") )
                //strategy.close("Long OVS 2", comment="SL Long OVS @"+ str.tostring(close15, "#,###"))
                L_mode := 0 // clear

            if SW_counter < 10 //close15 >= ema200-5.0
                strategy.close("Long Rebound", comment="TP Rebound " + str.tostring(close15, "#,###") )
        
        if strategy.position_size == 0 and L_Rebound and inhiSideway == false
            strategy.entry("Long Rebound", strategy.long, comment="Rebound " + str.tostring(close15, "#,###"))
            strategy.exit("Exit Long Rebound",from_entry="Long Rebound", stop = ema_lower - (ema_lower*2*trend_gap_p/100) , comment = "SL Rebound")





var label DebugLabel = na
label.delete(DebugLabel)
if not na(latch_trend)
    DebugLabel := label.new(bar_index, high15, text="trend " + str.tostring(latch_trend,"#") , style=label.style_label_down, color=color.blue, textcolor=color.white, size=size.small)


// Plot Bollinger Bands
//plot(sidewaysMarket ? lastBottomPrice15 : na , color=color.yellow, style=plot.style_circles)
//plot(sidewaysMarket ? lastPeakPrice15 : na , color=color.blue, style=plot.style_circles)
plot(trendMarket ? lastBottomPrice15 : na, color=color.red, style=plot.style_circles)
plot(trendMarket ? lastPeakPrice15 : na, color=color.green, style=plot.style_circles)
bgcolor(sidewaysMarket ? color.new(color.black, 90) : na)
bgcolor(trendMarket ? color.new(color.lime, 90) : na)

// Plot the three lines
plot(ema200, title="EMA 200",       color=color.white)
plot(ema_upper,  title="EMA 200 + 20",  color=color.white)
plot(ema_lower,  title="EMA 200 - 20",  color=color.white)