La estrategia de seguimiento de tendencia de la media móvil exponencial doble es una estrategia de seguimiento de tendencia basada en los cruces de la media móvil exponencial (EMA). Juzga la dirección de la tendencia actual calculando la línea EMA rápida y la línea EMA lenta y actúa sobre sus cruces. Cuando la línea EMA rápida cruza por encima de la línea EMA lenta, se determina como una señal alcista. Cuando la línea EMA rápida cruza por debajo de la línea EMA lenta, se determina como una señal bajista.
La lógica central de esta estrategia radica en el cálculo de dos líneas EMA de períodos diferentes - una actúa como la línea bajista y otra actúa como la línea alcista. Específicamente, la estrategia calcula una línea EMA rápida de 8 períodos utilizando el indicador talib como la línea alcista. Y calcula una línea EMA lenta de 21 períodos como la línea bajista. Luego juzga las relaciones de cruce entre la línea EMA rápida y la línea EMA lenta. Cuando la línea rápida cruza por encima de la línea lenta, determina una señal alcista para ir largo. Cuando la línea rápida cruza por debajo de la línea lenta, determina una señal bajista para ir corto.
En términos de ejecución comercial real, esta estrategia puede ir larga sólo, ir corta sólo, o ir en ambos sentidos cuando el cruce ocurre entre líneas rápidas y lentas. Además, los precios de stop loss y take profit se configuran en la estrategia. Después de abrir posiciones, si el precio va en una dirección desfavorable, stop loss se desencadenará a posiciones de salida. Si el precio alcanza el nivel objetivo esperado, take profit se dará cuenta y cerrará posiciones.
La mayor ventaja de la estrategia de seguimiento de tendencias de la doble EMA radica en la poderosa capacidad de identificación de tendencias de los cruces de promedios móviles.
Además, los ajustes flexibles en las direcciones comerciales hacen que la estrategia sea adaptable tanto a tendencias unidireccionales como a oscilaciones bidireccionales, lo que mejora la aplicabilidad de la estrategia.
El mayor riesgo de esta estrategia son las señales falsas desencadenadas por los cruces pequeños frecuentes en mercados de rango. Esto conduciría a una apertura y pérdidas excesivas de posiciones. Para hacer frente a esto, podemos aumentar los períodos de EMA para reducir los tiempos de cruce y las probabilidades de señales falsas.
Por otro lado, una configuración de stop loss demasiado apretada también aumenta la posibilidad de ser detenido.
Esta estrategia puede optimizarse aún más en los siguientes aspectos:
Ajuste adaptativo de los períodos de EMA basado en la volatilidad del mercado y los resultados de las pruebas de retroceso, evitando el sobreajuste en períodos fijos.
Añadir condiciones de filtro para filtrar señales falsas, por ejemplo, combinar con volúmenes de negociación para filtrar cruces insignificantes; o combinar otros indicadores como MACD y KDJ para evitar señales de incertidumbre.
Optimizar las estrategias de stop loss y take profit, por ejemplo, combinando ATR para lograr un seguimiento dinámico en SL/TP, evitando SL demasiado ajustado y TP prematuro.
Prueba de diferentes períodos de retención. Los períodos de retención demasiado largos pueden verse afectados por incidentes, mientras que los períodos demasiado cortos conducen a altos costos de negociación y costos de deslizamiento. Encontrar los días de retención óptimos puede mejorar la rentabilidad de la estrategia.
En general, la estrategia de seguimiento de tendencias es un sistema de trading de tendencias robusto y práctico. Captura las direcciones de tendencia de manera efectiva a través del sistema de cruce de EMA. Mientras tanto, las configuraciones flexibles en las direcciones de comercio lo hacen adaptable; los riesgos de control de stop loss y take profit configurados. Con nuevas optimizaciones y mejoras, esta estrategia puede convertirse en una poderosa herramienta para el trading cuantitativo.
/*backtest start: 2024-01-02 00:00:00 end: 2024-02-01 00:00:00 period: 2h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © TradersPostInc //@version=5 strategy('TradersPost Example MOMO Strategy', overlay=true, default_qty_value=100, initial_capital=100000, default_qty_type=strategy.percent_of_equity, pyramiding=0) startTime = input(defval = timestamp('01 Jan 2021 00:00 +0000'), title = 'Start Time', group = 'Date Range') endTime = input(defval = timestamp('31 Dec 2023 23:59 +0000'), title = 'End Time', group = 'Date Range') timeCondition = true timeConditionEnd = timeCondition[1] and not timeCondition fastEmaLength = input.int(defval = 8, title = 'Fast EMA Length') slowEmaLength = input.int(defval = 21, title = 'Slow EMA Length') sides = input.string(defval = 'Both', title = 'Sides', options = ['Long', 'Short', 'Both', 'None']) fastEma = ta.ema(close, fastEmaLength) slowEma = ta.ema(close, slowEmaLength) isUptrend = fastEma >= slowEma isDowntrend = fastEma <= slowEma trendChanging = ta.cross(fastEma, slowEma) ema105 = request.security(syminfo.tickerid, '30', ta.ema(close, 105)[1], barmerge.gaps_off, barmerge.lookahead_on) ema205 = request.security(syminfo.tickerid, '30', ta.ema(close, 20)[1], barmerge.gaps_off, barmerge.lookahead_on) plot(ema105, linewidth=4, color=color.new(color.purple, 0), editable=true) plot(ema205, linewidth=2, color=color.new(color.purple, 0), editable=true) aa = plot(fastEma, linewidth=3, color=color.new(color.green, 0), editable=true) bb = plot(slowEma, linewidth=3, color=color.new(color.red, 0), editable=true) fill(aa, bb, color=isUptrend ? color.green : color.red, transp=90) tradersPostBuy = trendChanging and isUptrend and timeCondition tradersPostSell = trendChanging and isDowntrend and timeCondition pips = syminfo.pointvalue / syminfo.mintick percentOrPipsInput = input.string('Percent', title='Percent or Pips', options=['Percent', 'Pips']) stopLossLongInput = input.float(defval=0, step=0.01, title='Stop Loss Long', minval=0) stopLossShortInput = input.float(defval=0, step=0.01, title='Stop Loss Short', minval=0) takeProfitLongInput = input.float(defval=0, step=0.01, title='Target Profit Long', minval=0) takeProfitShortInput = input.float(defval=0, step=0.01, title='Target Profit Short', minval=0) stopLossPriceLong = ta.valuewhen(tradersPostBuy, close, 0) * (stopLossLongInput / 100) * pips stopLossPriceShort = ta.valuewhen(tradersPostSell, close, 0) * (stopLossShortInput / 100) * pips takeProfitPriceLong = ta.valuewhen(tradersPostBuy, close, 0) * (takeProfitLongInput / 100) * pips takeProfitPriceShort = ta.valuewhen(tradersPostSell, close, 0) * (takeProfitShortInput / 100) * pips takeProfitALong = takeProfitLongInput > 0 ? takeProfitLongInput : na takeProfitBLong = takeProfitPriceLong > 0 ? takeProfitPriceLong : na takeProfitAShort = takeProfitShortInput > 0 ? takeProfitShortInput : na takeProfitBShort = takeProfitPriceShort > 0 ? takeProfitPriceShort : na stopLossALong = stopLossLongInput > 0 ? stopLossLongInput : na stopLossBLong = stopLossPriceLong > 0 ? stopLossPriceLong : na stopLossAShort = stopLossShortInput > 0 ? stopLossShortInput : na stopLossBShort = stopLossPriceShort > 0 ? stopLossPriceShort : na takeProfitLong = percentOrPipsInput == 'Pips' ? takeProfitALong : takeProfitBLong stopLossLong = percentOrPipsInput == 'Pips' ? stopLossALong : stopLossBLong takeProfitShort = percentOrPipsInput == 'Pips' ? takeProfitAShort : takeProfitBShort stopLossShort = percentOrPipsInput == 'Pips' ? stopLossAShort : stopLossBShort buyAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "buy", "price": ' + str.tostring(close) + '}' sellAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "sell", "price": ' + str.tostring(close) + '}' exitLongAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit", "price": ' + str.tostring(close) + '}' exitShortAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit", "price": ' + str.tostring(close) + '}' if (sides != "None") if tradersPostBuy strategy.entry('Long', strategy.long, when = sides != 'Short', alert_message = buyAlertMessage) strategy.close('Short', when = sides == "Short" and timeCondition, alert_message = exitShortAlertMessage) if tradersPostSell strategy.entry('Short', strategy.short, when = sides != 'Long', alert_message = sellAlertMessage) strategy.close('Long', when = sides == 'Long', alert_message = exitLongAlertMessage) exitAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit"}' strategy.exit('Exit Long', from_entry = "Long", profit = takeProfitLong, loss = stopLossLong, alert_message = exitAlertMessage) strategy.exit('Exit Short', from_entry = "Short", profit = takeProfitShort, loss = stopLossShort, alert_message = exitAlertMessage) strategy.close_all(when = timeConditionEnd)