Esta estrategia utiliza principalmente el cruce del doble impulso de la EMA y el impulso de la DEMA para identificar tendencias e incorpora el índice de volatilidad ATR para filtrar las falsas rupturas, implementando una estrategia comercial cuantitativa con indicadores de doble impulso y filtrado de volatilidad.
Los principales componentes de esta estrategia incluyen:
Calcular EMA y DEMA del precio como indicadores de impulso dual. El EMA de período más largo refleja las tendencias a largo plazo, mientras que DEMA sirve como un indicador de impulso a corto plazo más sensible. Se genera una señal de compra cuando DEMA cruza por encima de EMA.
Calcular el índice de volatilidad ATR. Utilice el valor ATR para determinar la volatilidad del mercado y las condiciones de liquidez. Filtrar las señales del indicador de impulso cuando la volatilidad es demasiado alta para evitar fallas falsas.
La volatilidad del ATR se juzga como alta o baja por una línea de media móvil parametrizada.
Los parámetros controlan el marco de tiempo del ATR, la longitud del ATR, el tipo y la longitud de la media móvil del ATR, etc.
Establecer las reglas de stop loss, take profit y trailing stop para las posiciones largas.
El doble filtro de EMA puede reducir significativamente las señales falsas y el exceso de negociación en comparación con las estrategias cruzadas de EMA básicas.
En comparación con los indicadores de momento únicos, el diseño dual puede mejorar la efectividad del juicio.
Al ajustar los parámetros ATR, se pueden establecer umbrales de volatilidad adecuados para diferentes indicadores, mejorando la adaptabilidad de la estrategia.
El mayor riesgo es que la configuración incorrecta de parámetros pueda resultar en muy pocas señales comerciales. Las longitudes DEMA y EMA demasiado largas, o los umbrales de volatilidad ATR establecidos demasiado altos, pueden socavar el rendimiento real de la estrategia. Se necesitan pruebas de retroceso repetidas para encontrar la combinación óptima de parámetros.
Otro riesgo potencial es que en condiciones extremas de mercado, las oscilaciones de precios puedan violar las restricciones del parámetro ATR que conducen a pérdidas.
Prueba diferentes combinaciones de parámetros del indicador de momento para encontrar los ajustes óptimos.
Intente sustituir los indicadores de impulso de la EMA dual por el MACD u otros indicadores.
Prueba de diferentes configuraciones de índices de volatilidad, como el ATR histórico general, el índice de volatilidad del mercado, etc.
Añadir filtrado de volumen para evitar el riesgo de falsas rupturas de precios.
Optimizar los mecanismos de stop loss y take profit para mejorar la relación riesgo-recompensa.
Esta estrategia integra el análisis de impulso y la investigación de volatilidad con una base teórica sólida. A través del ajuste de parámetros y la optimización lógica, puede convertirse en un sistema de negociación algorítmica estable y confiable. Con señales comerciales claras y riesgos controlables, vale la pena verificarlo e implementarlo en el comercio en vivo.
/*backtest start: 2023-11-21 00:00:00 end: 2023-12-21 00:00:00 period: 1h 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/ // © Qorbanjf //@version=4 strategy("ORIGIN DEMA/EMA & VOL LONG ONLY", shorttitle="ORIGIN DEMA/EMA & VOL LONG", overlay=true) // DEMA length = input(10, minval=1, title="DEMA LENGTH") src = input(close, title="Source") e1 = ema(src, length) e2 = ema(e1, length) dema1 = 2 * e1 - e2 plot(dema1, "DEMA", color=color.yellow) //EMA len = input(25, minval=1, title="EMA Length") srb = input(close, title="Source") offset = input(title="Offset", type=input.integer, defval=0, minval=-500, maxval=500) ema1 = ema(srb, len) plot(ema1, title="EMA", color=color.blue, offset=offset) // Inputs atrTimeFrame = input("D", title="ATR Timeframe", type=input.resolution) atrLookback = input(defval=14,title="ATR Lookback Period",type=input.integer) useMA = input(title = "Show Moving Average?", type = input.bool, defval = true) maType = input(defval="EMA", options=["EMA", "SMA"], title = "Moving Average Type") maLength = input(defval = 20, title = "Moving Average Period", minval = 1) //longLossPerc = input(title="Long Stop Loss (%)", // type=input.float, minval=0.0, step=0.1, defval=1) * 0.01 longTrailPerc = input(title="Trail stop loss (%)", type=input.float, minval=0.0, step=0.1, defval=50) * 0.01 longProfitPerc = input(title="Long Take Profit (%)", type=input.float, minval=0.0, step=0.1, defval=3000) / 100 // === INPUT BACKTEST RANGE === FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12) FromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31) FromYear = input(defval = 2017, title = "From Year", minval = 2000) ToMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12) ToDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31) ToYear = input(defval = 9999, title = "To Year", minval = 2017) // ATR Logic // atrValue = atr(atrLookback) // atrp = (atrValue/close)*100 // plot(atrp, color=color.white, linewidth=2, transp = 30) atrValue = security(syminfo.tickerid, atrTimeFrame, atr(atrLookback)) atrp = (atrValue/close)*100 // Moving Average Logic ma(maType, src, length) => maType == "EMA" ? ema(src, length) : sma(src, length) //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc) maFilter = security(syminfo.tickerid, atrTimeFrame, ma(maType, atrp, maLength)) // variables for enter position enterLong = crossover(dema1, ema1) and atrp < maFilter // variables for exit position sale = crossunder(dema1, ema1) // stop loss //longStopPrice = strategy.position_avg_price * (1 - longLossPerc) // trail stop // Determine trail stop loss prices longStopTrail = 0.0 longStopTrail := if (strategy.position_size > 0) stopValue = close * (1 - longTrailPerc) max(stopValue, longStopTrail[1]) else 0 //Take profit Percentage longExitPrice = strategy.position_avg_price * (1 + longProfitPerc) //Enter trades when conditions are met strategy.entry(id="long", long=strategy.long, when=enterLong, comment="long") // strategy.close("long", when = sale, comment = "Sell") //place exit orders (only executed after trades are active) strategy.exit(id="sell", limit = longExitPrice, stop = longStopTrail, comment = "SL/TP")