
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é.
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.
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 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é.
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.
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.
/*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}}")