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.
La lógica central de esta estrategia es la siguiente:
Parámetros de entrada: período MA más rápido maLen1, período MA más lento maLen2, tipo MA maTypeChoice
Calcular el MA maValue1 más rápido y el MA maValue2 más lento basándose en los parámetros de entrada
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
Ejecutar operaciones con señales de compra y venta
Visualizar las MA en diferentes colores basados en su relación
Enviar señales de alerta de compra y venta
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 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
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
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 )