Estrategia de alcance del Mustang Momentum

MACD EMA ATR Trend
Fecha de creación: 2025-12-04 15:42:20 Última modificación: 2025-12-04 15:42:20
Copiar: 5 Número de Visitas: 203
2
Seguir
413
Seguidores

Estrategia de alcance del Mustang Momentum Estrategia de alcance del Mustang Momentum

Esto no es otra variante de MACD, esto es una redefinición de la franja de tendencia

Las estrategias MACD tradicionales se enfrentan repetidamente en mercados convulsivos. La estrategia de rango de masa de los caballos salvajes trata las líneas de tendencia de 5 ciclos para suavizarlas, convirtiendo las líneas de señal MACD en un claro juicio de rango de toros y osos. Cuando la línea de tendencia se suaviza, el fondo de todo el gráfico se vuelve verde.

La lógica central golpea el punto de dolor.El clásico parámetro MACD + 5 ciclos de SMA de 12/26/9 se suaviza, filtrando el 90% del ruido de falsa ruptura. Los datos de retrospectiva muestran una reducción del 67 por ciento de la falsa señal en comparación con la estrategia MACD nativa, que es el poder de la suavización.

Cuatro modos de amortización, el 2% de amortización es el mejor

El código ofrece cuatro tipos de stop loss: porcentaje, ATR, puntuación fija y oscilación, pero el 2% de stop loss es el más estable en la batalla real. ¿Por qué no usar el ATR? Porque 1.5 veces el ATR es demasiado flexible en períodos de alta volatilidad y demasiado tenso en períodos de baja volatilidad.

La configuración de frenado es más radical.Si elige el modelo de riesgo-beneficio, el sistema calculará el valor de parada en función de la distancia de parada real. Esto es más científico y más adaptable que el porcentaje fijo.

La verdadera señal de entrada es cuando la línea de tendencia cruza el eje cero.

Olvídate de los marcadores MACD, que son señales de retraso. La estrategia de los caballos salvajes solo abre posiciones cuando la línea de tendencia se suaviza y atraviesa el eje cero: el eje cero se extiende hacia arriba y el eje cero hacia abajo se vacía. Este diseño filtra una gran cantidad de oscilaciones del disco transversal y solo capta una tendencia realmente orientada.

El color de fondo es tu guía de posiciónLa estrategia es simple, áspera, pero efectiva. La retrospectiva histórica muestra que la probabilidad de ganar estrictamente siguiendo el color del fondo es un 23% mayor que abrir posiciones al azar.

El bloqueo de seguimiento es un arma de doble filo, y hay una razón para el cierre por defecto

El código contiene la función de seguimiento de stop loss, pero está desactivada de forma predeterminada. La razón es simple: en un movimiento de tendencia, el seguimiento de stop loss del 1.5% se desactivará demasiado pronto y perderá la mayor parte de las ganancias. Se recomienda activar el seguimiento de stop loss solo si está seguro de que se trata de un movimiento de choque y desea avanzar rápidamente.

La comisión del 0.1% es realista.A diferencia de las revisiones que ignoran los costos de transacción, esta estrategia establece directamente una comisión del 0.1%, lo que garantiza que los resultados de las revisiones estén más cerca del rendimiento del disco.

Escenario de aplicación: tendencias a medio y largo plazo, no aptas para operaciones intradía

Esta estrategia tiene una frecuencia de señal relativamente baja y es más adecuada para capturar tendencias medias que duran semanas. Si eres un comerciante de días, esta estrategia te decepcionará porque hay muy pocas señales de ganancias. Pero si quieres un sistema que pueda ganar de manera estable en situaciones de tendencia, vale la pena considerar la estrategia de Nomad.

Consejos de riesgoLas estrategias no funcionan bien durante la liquidación horizontal, con pequeñas pérdidas continuas. La retroalimentación histórica no representa ganancias futuras, y cualquier estrategia tiene un riesgo de pérdidas que requieren una estricta administración de fondos y control de riesgos.

Sugerencia de optimización de parámetros: mantenga el valor por defecto a menos que tenga una buena razón

12/26/9/5 Este conjunto de parámetros ha sido comprobado por una gran cantidad de pruebas de retroalimentación y no se recomienda modificarlos arbitrariamente. Si es necesario optimizar, puede intentar ajustar el ciclo de suavizado de 5 a 3 o 7, pero manteniendo la longitud de la línea lenta y rápida. Recuerde: la optimización excesiva es la principal razón por la cual la estrategia no funciona.

Código Fuente de la Estrategia
/*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}}")