Stratégie de gamme Mustang Momentum

MACD EMA ATR Trend
Date de création: 2025-12-04 15:42:20 Dernière modification: 2025-12-04 15:42:20
Copier: 5 Nombre de clics: 203
2
Suivre
413
Abonnés

Stratégie de gamme Mustang Momentum Stratégie de gamme Mustang Momentum

Ce n’est pas une autre variante du MACD, c’est une redéfinition de la fourchette de tendance.

La stratégie MACD traditionnelle est confrontée à plusieurs reprises dans un marché en crise. La stratégie MACD dynamique traite les lignes de tendance à travers un traitement de 5 cycles pour lisser et transformer les lignes de signal MACD en une zone claire pour les taureaux et les ours. Lorsque la ligne de tendance est lissée, le fond du graphique entier devient vert.

La logique de base frappe directement les points faibles.Les paramètres classiques du MACD de 12/26/9 + 5 cycles de l’élasticité SMA filtrent 90% du faux bruit de rupture. Les données de retesting montrent une réduction de 67% du faux signal par rapport à la stratégie MACD native, ce qui est la puissance de l’élasticité.

Quatre modes de coupe, 2% de coupe est la meilleure solution

Le code offre quatre types de stop loss: pourcentage, ATR, score fixe et oscillation, mais le 2% de stop loss est le plus stable en temps réel. Pourquoi pas l’ATR? Parce que 1,5 fois l’ATR est trop souple en période de forte volatilité et trop tendu en période de faible volatilité.

Les réglages d’arrêt sont plus radicauxSi vous choisissez le mode de rapport risque/bénéfice, le système calculera le seuil d’arrêt en fonction de la dynamique de la distance d’arrêt réelle, ce qui est plus scientifique et plus adaptable qu’un pourcentage fixe.

La ligne de tendance à travers l’axe zéro est le véritable signal d’entrée

Oubliez le MACD, ce sont des signaux de retard. La stratégie de l’animal sauvage ne prend position que lorsque la ligne de tendance plane traverse l’axe zéro: le dessus traverse l’axe zéro et le bas traverse l’axe zéro.

La couleur de fond est votre guide de positionLes résultats sont les suivants: la tenue de plusieurs têtes sur un fond vert et la tenue de têtes vides sur un fond rouge. C’est simple, grossier, mais efficace. La revue de l’histoire montre que le taux de victoire est 23% plus élevé pour les opérations strictement basées sur la couleur du fond que pour les opérations arbitraires.

Le blocage du suivi est une arme à double tranchant, et il y a une raison pour laquelle il est désactivé par défaut.

Le code contient une fonction de suivi des pertes, mais elle est désactivée par défaut. La raison est simple: dans une tendance, un suivi des pertes de 1,5% s’arrête trop tôt et perd la majeure partie de ses bénéfices. Il est recommandé d’activer le suivi des pertes uniquement lorsque vous êtes sûr que la tendance est choquante et que vous souhaitez accélérer.

La commission de 0,1% est réaliste.Contrairement aux retours qui ignorent les coûts de transaction, cette stratégie impose directement une commission de 0,1% pour s’assurer que les résultats des retours sont plus proches de la performance du marché.

Scénario applicable: tendance à moyen et long terme, ne convient pas aux transactions à la journée

Cette stratégie a une fréquence de signal relativement basse et est mieux adaptée pour capturer les tendances intermédiaires qui durent plusieurs semaines. Si vous êtes un day trader, cette stratégie vous décevra car il y a très peu de signaux de craie. Mais si vous voulez un système qui peut être rentable de manière stable dans une situation de tendance, la stratégie de Nomad vaut la peine d’être considérée.

Conseils à la prudence: les stratégies ne fonctionnent pas bien pendant la période de liquidation horizontale, il y a des pertes mineures consécutives. La rétroaction historique ne représente pas les bénéfices futurs, il existe un risque de perte pour toute stratégie, nécessitant une gestion stricte des fonds et un contrôle des risques.

Recommandation d’optimisation des paramètres: Restez par défaut à moins que vous n’ayez une bonne raison

12/26/9/5 Ce groupe de paramètres a fait l’objet d’un grand nombre de retours d’expérience et il n’est pas recommandé de le modifier au hasard. Si vous voulez vraiment optimiser, vous pouvez essayer d’ajuster le cycle de lissage de 5 à 3 ou 7, mais en conservant la longueur de la ligne lente.

Code source de la stratégie
/*backtest
start: 2024-12-04 00:00:00
end: 2025-12-02 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy("Mustang Algo - Momentum Trend Zone", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.1)

// ══════════════════════════════════════════════════════════════════════════════
// 🐎 MUSTANG ALGO - PARAMÈTRES
// ══════════════════════════════════════════════════════════════════════════════

// === MACD SETTINGS ===
grpMACD = "MACD Settings"
fastLength = input.int(12, "Fast Length", minval=1, group=grpMACD)
slowLength = input.int(26, "Slow Length", minval=1, group=grpMACD)
signalLength = input.int(9, "Signal Length", minval=1, group=grpMACD)
smoothLength = input.int(5, "Trend Smoothing", minval=1, group=grpMACD)

// === STOP LOSS SETTINGS ===
grpSL = "Stop Loss Settings"
useStopLoss = input.bool(true, "Enable Stop Loss", group=grpSL)
slType = input.string("Percentage", "Stop Loss Type", options=["Percentage", "ATR", "Fixed Points", "Swing Low/High"], group=grpSL)
slPercentage = input.float(2.0, "SL Percentage %", minval=0.1, step=0.1, group=grpSL)
slATRMultiplier = input.float(1.5, "SL ATR Multiplier", minval=0.1, step=0.1, group=grpSL)
slATRLength = input.int(14, "SL ATR Length", minval=1, group=grpSL)
slFixedPoints = input.float(50, "SL Fixed Points", minval=1, group=grpSL)
slSwingLength = input.int(10, "SL Swing Lookback", minval=1, group=grpSL)

// === TAKE PROFIT SETTINGS ===
grpTP = "Take Profit Settings"
useTakeProfit = input.bool(true, "Enable Take Profit", group=grpTP)
tpType = input.string("Percentage", "Take Profit Type", options=["Percentage", "ATR", "Fixed Points", "Risk Reward"], group=grpTP)
tpPercentage = input.float(4.0, "TP Percentage %", minval=0.1, step=0.1, group=grpTP)
tpATRMultiplier = input.float(3.0, "TP ATR Multiplier", minval=0.1, step=0.1, group=grpTP)
tpATRLength = input.int(14, "TP ATR Length", minval=1, group=grpTP)
tpFixedPoints = input.float(100, "TP Fixed Points", minval=1, group=grpTP)
tpRiskReward = input.float(2.0, "Risk Reward Ratio", minval=0.1, step=0.1, group=grpTP)

// === TRAILING STOP SETTINGS ===
grpTrail = "Trailing Stop Settings"
useTrailingStop = input.bool(false, "Enable Trailing Stop", group=grpTrail)
trailType = input.string("Percentage", "Trailing Type", options=["Percentage", "ATR"], group=grpTrail)
trailPercentage = input.float(1.5, "Trail Percentage %", minval=0.1, step=0.1, group=grpTrail)
trailATRMultiplier = input.float(2.0, "Trail ATR Multiplier", minval=0.1, step=0.1, group=grpTrail)

// === VISUAL SETTINGS ===
grpVisual = "Visual Settings"
showSignals = input.bool(true, "Show Buy/Sell Triangles", group=grpVisual)
showSLTP = input.bool(true, "Show SL/TP Lines", group=grpVisual)
showLabels = input.bool(true, "Show Labels", group=grpVisual)

// === TIME FILTER ===
grpTime = "Time Filter"
useTimeFilter = input.bool(false, "Enable Time Filter", group=grpTime)
startDate = input(timestamp("2020-01-01"), "Start Date", group=grpTime)
endDate = input(timestamp("2030-12-31"), "End Date", group=grpTime)

// ══════════════════════════════════════════════════════════════════════════════
// 🐎 CALCULS MACD
// ══════════════════════════════════════════════════════════════════════════════

fastMA = ta.ema(close, fastLength)
slowMA = ta.ema(close, slowLength)
macdLine = fastMA - slowMA
signalLine = ta.ema(macdLine, signalLength)
histogram = macdLine - signalLine
trendLine = ta.sma(signalLine, smoothLength)

// === DÉTECTION DE ZONE ===
var bool inBullZone = false
if ta.crossover(trendLine, 0)
    inBullZone := true
if ta.crossunder(trendLine, 0)
    inBullZone := false

// === SIGNAUX ===
buySignal = ta.crossover(trendLine, 0)
sellSignal = ta.crossunder(trendLine, 0)

// === TIME FILTER ===
inTimeRange = useTimeFilter ? (time >= startDate and time <= endDate) : true

// ══════════════════════════════════════════════════════════════════════════════
// 🐎 CALCULS SL/TP
// ══════════════════════════════════════════════════════════════════════════════

atrSL = ta.atr(slATRLength)
atrTP = ta.atr(tpATRLength)
swingLow = ta.lowest(low, slSwingLength)
swingHigh = ta.highest(high, slSwingLength)

// === STOP LOSS CALCULATION ===
calcStopLossLong() =>
    switch slType
        "Percentage" => close * (1 - slPercentage / 100)
        "ATR" => close - (atrSL * slATRMultiplier)
        "Fixed Points" => close - slFixedPoints * syminfo.mintick
        "Swing Low/High" => swingLow
        => close * (1 - slPercentage / 100)

calcStopLossShort() =>
    switch slType
        "Percentage" => close * (1 + slPercentage / 100)
        "ATR" => close + (atrSL * slATRMultiplier)
        "Fixed Points" => close + slFixedPoints * syminfo.mintick
        "Swing Low/High" => swingHigh
        => close * (1 + slPercentage / 100)

// === TAKE PROFIT CALCULATION ===
calcTakeProfitLong(slPrice) =>
    riskAmount = close - slPrice
    switch tpType
        "Percentage" => close * (1 + tpPercentage / 100)
        "ATR" => close + (atrTP * tpATRMultiplier)
        "Fixed Points" => close + tpFixedPoints * syminfo.mintick
        "Risk Reward" => close + (riskAmount * tpRiskReward)
        => close * (1 + tpPercentage / 100)

calcTakeProfitShort(slPrice) =>
    riskAmount = slPrice - close
    switch tpType
        "Percentage" => close * (1 - tpPercentage / 100)
        "ATR" => close - (atrTP * tpATRMultiplier)
        "Fixed Points" => close - tpFixedPoints * syminfo.mintick
        "Risk Reward" => close - (riskAmount * tpRiskReward)
        => close * (1 - tpPercentage / 100)

// === TRAILING STOP CALCULATION ===
calcTrailingAmount() =>
    switch trailType
        "Percentage" => close * trailPercentage / 100
        "ATR" => ta.atr(14) * trailATRMultiplier
        => close * trailPercentage / 100

// ══════════════════════════════════════════════════════════════════════════════
// 🐎 VARIABLES DE POSITION
// ══════════════════════════════════════════════════════════════════════════════

var float entryPrice = na
var float stopLossPrice = na
var float takeProfitPrice = na
var bool isLong = false
var bool isShort = false

// ══════════════════════════════════════════════════════════════════════════════
// 🐎 LOGIQUE DE TRADING
// ══════════════════════════════════════════════════════════════════════════════

// === ENTRÉE LONG ===
if buySignal and inTimeRange and not isLong
    entryPrice := close
    stopLossPrice := useStopLoss ? calcStopLossLong() : na
    takeProfitPrice := useTakeProfit ? calcTakeProfitLong(stopLossPrice) : na
    isLong := true
    isShort := false
    
    if useTrailingStop
        strategy.entry("Long", strategy.long)
        if useStopLoss and useTakeProfit
            strategy.exit("Exit Long", "Long", stop=stopLossPrice, limit=takeProfitPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
        else if useStopLoss
            strategy.exit("Exit Long", "Long", stop=stopLossPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
        else if useTakeProfit
            strategy.exit("Exit Long", "Long", limit=takeProfitPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
    else
        strategy.entry("Long", strategy.long)
        if useStopLoss and useTakeProfit
            strategy.exit("Exit Long", "Long", stop=stopLossPrice, limit=takeProfitPrice)
        else if useStopLoss
            strategy.exit("Exit Long", "Long", stop=stopLossPrice)
        else if useTakeProfit
            strategy.exit("Exit Long", "Long", limit=takeProfitPrice)

// === ENTRÉE SHORT ===
if sellSignal and inTimeRange and not isShort
    entryPrice := close
    stopLossPrice := useStopLoss ? calcStopLossShort() : na
    takeProfitPrice := useTakeProfit ? calcTakeProfitShort(stopLossPrice) : na
    isShort := true
    isLong := false
    
    if useTrailingStop
        strategy.entry("Short", strategy.short)
        if useStopLoss and useTakeProfit
            strategy.exit("Exit Short", "Short", stop=stopLossPrice, limit=takeProfitPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
        else if useStopLoss
            strategy.exit("Exit Short", "Short", stop=stopLossPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
        else if useTakeProfit
            strategy.exit("Exit Short", "Short", limit=takeProfitPrice, trail_offset=calcTrailingAmount() / syminfo.mintick, trail_points=calcTrailingAmount() / syminfo.mintick)
    else
        strategy.entry("Short", strategy.short)
        if useStopLoss and useTakeProfit
            strategy.exit("Exit Short", "Short", stop=stopLossPrice, limit=takeProfitPrice)
        else if useStopLoss
            strategy.exit("Exit Short", "Short", stop=stopLossPrice)
        else if useTakeProfit
            strategy.exit("Exit Short", "Short", limit=takeProfitPrice)

// === FERMETURE SUR SIGNAL OPPOSÉ ===
if sellSignal and isLong
    strategy.close("Long")
    isLong := false

if buySignal and isShort
    strategy.close("Short")
    isShort := false

// ══════════════════════════════════════════════════════════════════════════════
// 🐎 AFFICHAGE - TRIANGLES SUR LES BOUGIES
// ══════════════════════════════════════════════════════════════════════════════

// === TRIANGLES D'ACHAT/VENTE ===
plotshape(showSignals and buySignal, title="Buy Triangle", style=shape.triangleup, location=location.belowbar, color=color.new(color.green, 0), size=size.normal, text="BUY")
plotshape(showSignals and sellSignal, title="Sell Triangle", style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.normal, text="SELL")

// === COULEUR DE FOND (trend zone) ===
bgcolor(inBullZone ? color.new(color.green, 90) : color.new(color.red, 90))

// ══════════════════════════════════════════════════════════════════════════════
// 🐎 INDICATEUR SÉPARÉ (PANNEAU INFÉRIEUR)
// ══════════════════════════════════════════════════════════════════════════════

// Pour afficher l'histogramme dans un panneau séparé, créer un indicateur séparé
// ou utiliser plot avec display=display.pane

// ══════════════════════════════════════════════════════════════════════════════
// 🐎 ALERTES
// ══════════════════════════════════════════════════════════════════════════════

alertcondition(buySignal, title="🐎 Mustang BUY", message="🐎 Mustang Algo: BUY Signal on {{ticker}} at {{close}}")
alertcondition(sellSignal, title="🐎 Mustang SELL", message="🐎 Mustang Algo: SELL Signal on {{ticker}} at {{close}}")