Estrategia de negociación cruzada de media móvil doble

El autor:¿ Qué pasa?, fecha: 2023-10-13 15:40:49
Las etiquetas:

Resumen general

La doble estrategia de negociación de media móvil cruzada genera señales de negociación mediante el cálculo de dos medias móviles con diferentes configuraciones de parámetros y la negociación cuando las medias móviles se cruzan.

Estrategia lógica

La lógica central de esta estrategia es la siguiente:

  1. Parámetros de entrada: período MA más rápido maLen1, período MA más lento maLen2, tipo MA maTypeChoice

  2. Calcular el MA maValue1 más rápido y el MA maValue2 más lento basándose en los parámetros de entrada

  3. Definir las condiciones de compra y venta mediante la comparación de las dos AMP:

    • Comprar cuando maValue1 cruza por encima de maValue2

    • Vender cuando maValue1 se cruza por debajo de maValue2

  4. Ejecutar operaciones con señales de compra y venta

  5. Visualizar las MA en diferentes colores basados en su relación

  6. Enviar señales de alerta de compra y venta

Ventajas

  • Utiliza un sistema de cruce de dos MA, evita señales falsas de un solo MA

  • Los periodos de gestión de mercado personalizables se adaptan a los diferentes horizontes de negociación

  • Lógica sencilla y directa, fácil de entender e implementar

  • Alertas de señal personalizables para su ejecución oportuna

  • Las tendencias MA visualizadas forman un indicador de trading intuitivo

  • Parámetros optimizables para encontrar la mejor combinación

  • Aplicable para pruebas de retroceso y operaciones en vivo

Los riesgos

  • Los cruces MA pueden generar señales falsas, necesitan tendencia adicional y confirmación de patrones

  • Los problemas relacionados con el cruce de la MA implican costes comerciales innecesarios

  • Los parámetros inadecuados conducen a un exceso de operaciones o a un comercio escaso

  • Los eventos extremos causan grandes oscilaciones de precios, incapaces de limitar las pérdidas

  • Las rupturas de tendencia a largo plazo invalidan los indicadores a corto plazo

  • Requiere monitoreo frecuente, no totalmente automatizable

Gestión de riesgos:

  • Añadir filtro de tendencia para evitar el comercio contra tendencia

  • Añadir un filtro de patrón para confirmar la validez de la señal

  • Optimizar los parámetros para una frecuencia de negociación razonable

  • Establecer el stop loss/take profit para limitar las pérdidas

  • Prueba de robustez en largos plazos

  • Filtros de precios y de tiempo para evitar falsas rupturas

Direcciones de optimización

  • Prueba diferentes parámetros de MA para encontrar el óptimo

  • Prueba diferentes tipos de MA para obtener las señales más precisas

  • Añadir un filtro de tendencia para evitar operaciones contra tendencia

  • Añadir un filtro de volatilidad para identificar los puntos de salida adecuados

  • Añadir un filtro precio/tiempo para reducir las señales falsas

  • Implementar el control del deslizamiento para operaciones reales

  • Prueba de robustez en todos los instrumentos y plazos

  • Integrar pérdida de parada automática/beneficio de toma

  • Explorar el aprendizaje automático para mejorar la estrategia

Conclusión

El doble cruce de promedios móviles es una estrategia clásica de indicadores técnicos. Genera señales de cruces de MA y puede producir buenos resultados de backtest a través de la optimización. Sin embargo, los riesgos como señales falsas permanecen, requiriendo filtros adicionales. El comercio real también necesita detalles de ejecución como el control de deslizamiento. En general, la estrategia se adapta al comercio a mediano plazo como una opción simple e intuitiva. Con mejoras continuas y validación de robustez, esta estrategia puede lograr retornos estables en el comercio en vivo.


/*backtest
start: 2023-10-05 00:00:00
end: 2023-10-05 22:00:00
period: 15m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// © sehweijun
//study( title="Arch1tect's New Toy", shorttitle="Arch1tect's New Toy", overlay=true, resolution="")
// strategy( title="Arch1tect's New Toy (Strategy Tester Version)", shorttitle="Arch1tect's New Toy (Strategy Tester Version)", overlay=true, initial_capital = 100000, commission_value=0.07, commission_type=strategy.commission.cash_per_contract)

maTypeChoice = input( "EMA", title="MA Type", options=["EMA", "WMA", "SMA"] )
maSrc = input( close, title="MA Source" )
maLen1 = input( 15, minval=1, title="MA Length" )
maLen2 = input( 95, minval=1, title="MA Length" )

maValue1 = if ( maTypeChoice == "EMA" )
    ema( maSrc, maLen1 )
else if ( maTypeChoice == "WMA" )
    wma( maSrc, maLen1 )
else if ( maTypeChoice == "SMA" )
    sma( maSrc, maLen1 )
else
    0
    
maValue2 = if ( maTypeChoice == "EMA" )
    ema( maSrc, maLen2 )
else if ( maTypeChoice == "WMA" )
    wma( maSrc, maLen2 )
else if ( maTypeChoice == "SMA" )
    sma( maSrc, maLen2 )
else
    0

buySignal = crossover( maValue1, maValue2 )
sellSignal = crossunder( maValue1, maValue2 )

mainMAColour = ( maValue1 > maValue2 ) ? color.green : color.red 

plot( maValue1, title="Arch1tect's New Toy", color=mainMAColour, offset=0, linewidth=4 )
//plot( maValue2, title="Arch1tect's Filter", color=color.black, offset=0, linewidth=2 )

var color buyCandleColour = #00ff0a
var color sellCandleColour = #ff1100

barcolor( buySignal ? buyCandleColour : sellSignal ? sellCandleColour : na, title="Signal Bar Colour" )
bgcolor( color=buySignal ? buyCandleColour : sellSignal ? sellCandleColour : na, transp=85, title="Signal Background Colour")

alertcondition( buySignal or sellSignal, title="Signal change!", message="Signal change!")
alertcondition( buySignal, title="Buy signal!", message="Buy signal!")
alertcondition( sellSignal, title="Sell signal!", message="Sell signal!")

// Strategy Tester
stratTesterOn    = input( title="Strategy Tester [ON/OFF]", group="Strategy Tester", type=input.bool, defval=true)
entryTime        = input( "2200-1200", title = "Daily trading time session (in Exchange GMT)", group="Strategy Tester", type = input.session )
startTime        = input( "2200-2201", title = "Start Time", group="Strategy Tester", type = input.session )
maxDailyLoss     = input( 2500, title = "Max daily loss", group="Strategy Tester", type = input.integer )
maxTotalDrawdown = input( 12000, title = "Max daily loss", group="Strategy Tester", type = input.integer )
contractSize     = input( 1, title = "Contract size", group="Strategy Tester", type = input.integer )

tradeOnStartSess = input( title="First trade on session start [ON/OFF]", group="Strategy Tester", type=input.bool, defval=true)

fixedTPSL        = input( title="Fixed TP/SL PIPS [ON/OFF]", group="Strategy Tester", type=input.bool, defval=false)
fixedTPValue     = input ( 10.00, minval=0.01, type=input.float, title="TP", group="Strategy Tester" )
fixedSLValue     = input ( 10.00, minval=0.01, type=input.float, title="SL", group="Strategy Tester" )

fromDay          = input(defval = 1,    title = "From Day", group="Date Range", type = input.integer, minval = 1, maxval = 31)
fromMonth        = input(defval = 1,    title = "From Month", group="Date Range", type = input.integer, minval = 1, maxval = 12)
fromYear         = input(defval = 2020, title = "From Year", group="Date Range", type = input.integer, minval = 1970)
thruDay          = input(defval = 1,    title = "Thru Day", group="Date Range", type = input.integer, minval = 1, maxval = 31)
thruMonth        = input(defval = 1,    title = "Thru Month", group="Date Range", type = input.integer, minval = 1, maxval = 12)
thruYear         = input(defval = 2112, title = "Thru Year", group="Date Range", type = input.integer, minval = 1970)

start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(thruYear, thruMonth, thruDay, 23, 59)        // backtest finish window
window()  => time >= start and time <= finish ? true : false       // create function "within window of time"

// strategy.risk.max_intraday_loss( maxDailyLoss, strategy.cash )
// strategy.risk.max_drawdown( maxTotalDrawdown, strategy.cash )

isTime(_position) =>
    range = time( timeframe.period, _position + ':1234567' )
bgcolor( color=isTime( entryTime ) and stratTesterOn and window() ? color.yellow : na, title="Daily trading time session (in Exchange GMT)", transp=75 )

if ( stratTesterOn and window() )
    if ( buySignal and isTime( entryTime ) )
        if ( not fixedTPSL )
            strategy.close_all()
            strategy.entry( "Buy", strategy.long, contractSize )
        
        if ( fixedTPSL and strategy.position_size == 0 )
            strategy.entry( "Buy", strategy.long, contractSize )
            strategy.exit( "TP/SL", "Buy", stop=close[0]-fixedSLValue, limit=close[0]+fixedTPValue )
        
    if ( sellSignal and isTime( entryTime ))
        if ( not fixedTPSL )
            strategy.close_all()
            strategy.entry( "Sell", strategy.short, contractSize )
        
        if ( fixedTPSL and strategy.position_size == 0  )
            strategy.entry( "Sell", strategy.short, contractSize )
            strategy.exit( "TP/SL", "Sell", stop=close[0]+fixedSLValue, limit=close[0]-fixedTPValue )
    
    if ( isTime( startTime ) and tradeOnStartSess and strategy.position_size == 0 )
        if ( maValue1 > maValue2 )
            strategy.entry( "Buy", strategy.long, contractSize )
            
            if ( fixedTPSL )
                strategy.exit( "TP/SL", "Buy", stop=close[0]-fixedSLValue, limit=close[0]+fixedTPValue )
        else
            strategy.entry( "Sell", strategy.short, contractSize ) 
            
            if ( fixedTPSL )
                strategy.exit( "TP/SL", "Sell", stop=close[0]+fixedSLValue, limit=close[0]-fixedTPValue )
    
    strategy.close_all( when=not isTime( entryTime ) )

plot( strategy.equity )

Más.