Estrategia de tendencia dinámica del ADX

El autor:¿ Qué pasa?, Fecha: 2024-01-15 15:32:45
Las etiquetas:

img

Resumen general

La estrategia de tendencia dinámica de ADX es una estrategia de trading cuantitativa que utiliza el indicador ADX para determinar la fuerza y dirección de las tendencias del mercado.

La lógica de la negociación

La estrategia utiliza primero el indicador ADX para determinar si existe una tendencia en el mercado. Cuando el ADX está por encima de un nivel clave definido por el usuario (por defecto 23), indica que la tendencia del mercado es relativamente fuerte. Cuando el valor actual del ADX es mayor que el valor del ADX hace n días (n es el período de retroceso definido por el usuario, por defecto 3 días), indica que el ADX está subiendo y se está formando una tendencia en el mercado.

La estrategia utiliza entonces DI+ y DI- para determinar la dirección de la tendencia del mercado. Cuando DI+ es superior a DI-, indica una tendencia alcista en el mercado. Cuando DI+ es inferior a DI-, indica una tendencia bajista en el mercado.

Por último, la estrategia combina el análisis ADX y DI para generar señales específicas de compra y venta:

  1. Cuando el ADX sube y está por encima del nivel clave y DI+ es superior a DI-, se genera una señal de compra
  2. Cuando el ADX sube y está por encima del nivel clave y DI+ es inferior a DI-, se genera una señal de venta
  3. Cuando el ADX se vuelve a disminuir, se genera una señal de posición plana

La estrategia también proporciona características como el filtrado de promedio móvil y el intervalo de tiempo de backtesting personalizable.

Análisis de ventajas

La estrategia de tendencia dinámica del ADX tiene las siguientes ventajas:

  1. Detecta automáticamente la existencia de tendencias del mercado, evitando operaciones ineficaces
  2. Determinar automáticamente la dirección de las tendencias del mercado para la tendencia siguiente
  3. Una lógica clara de compra en la existencia de tendencia y aplanamiento en la desaparición de tendencia
  4. El filtrado de la media móvil configurable evita las falsas rupturas
  5. Intervalo de tiempo de backtesting personalizable para las pruebas históricas
  6. Parámetros de indicadores ajustables para la optimización en diferentes productos

Análisis de riesgos

La estrategia también tiene algunos riesgos:

  1. El indicador ADX tiene un efecto retardante, posiblemente perdiendo oportunidades de tendencia tempranas
  2. La dependencia de la dirección de la tendencia en DI puede producir señales falsas ya que DI es sensible
  3. El filtro de media móvil puede perder oportunidades a corto plazo
  4. Un marco de tiempo de backtesting inadecuado puede causar sobreajuste
  5. Los parámetros incorrectos de los indicadores pueden afectar al rendimiento de la estrategia

Para mitigar los riesgos, se pueden considerar los siguientes aspectos:

  1. Acortar los parámetros ADX para reducir el retraso
  2. Eliminar o ajustar el filtro DI para evitar señales falsas
  3. Acortamiento del período de la media móvil
  4. Ampliar el marco de tiempo de backtesting para pruebas completas de muestras
  5. Optimiza los parámetros para encontrar las mejores configuraciones

Oportunidades de mejora

La estrategia puede mejorarse en los siguientes aspectos:

  1. Pruebas de cartera en múltiples acciones para diversificar el riesgo de una sola acción
  2. Añadir una lógica de stop loss al control por pérdida de operaciones
  3. Combinar con otros indicadores para la verificación de señales para mejorar la precisión
  4. Introducir algoritmos de aprendizaje automático para la generación de señales de compra/venta
  5. Añadir módulo de ajuste automático de parámetros para el ajuste dinámico

Conclusión

La estrategia de tendencia dinámica de ADX utiliza ADX para determinar la existencia de tendencias y DI para la dirección de tendencias. Genera señales comerciales cuando existe una tendencia y aplana posiciones cuando la tendencia desaparece. La lógica es clara. Al detectar y rastrear automáticamente las tendencias, se puede evitar la negociación ineficaz hasta cierto punto en los mercados no tendentes. Con la mejora adecuada, esta estrategia puede convertirse en una poderosa herramienta para la negociación cuantitativa a medio y largo plazo.


/*backtest
start: 2024-01-07 00:00:00
end: 2024-01-14 00:00:00
period: 10m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © millerrh with inspiration from @9e52f12edd034d28bdd5544e7ff92e 
//The intent behind this study is to look at ADX when it has an increasing slope and is above a user-defined key level (23 default). 
//This is to identify when it is trending.
//It then looks at the DMI levels.  If D+ is above D- and the ADX is sloping upwards and above the key level, it triggers a buy condition.  Opposite for short.
//Can use a user-defined moving average to filter long/short if desried.
// NOTE: THIS IS MEANT TO BE USED IN CONJUNCTION WITH MY "ATX TRIGGER" INDICATOR FOR VISUALIZATION. MAKE SURE SETTINGS ARE THE SAME FOR BOTH.

strategy("ADX | DMI Trend", overlay=true, initial_capital=10000, currency='USD', 
   default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.04)

// === BACKTEST RANGE ===
From_Year  = input(defval = 2019, title = "From Year")
From_Month = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
From_Day   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
To_Year    = input(defval = 9999, title = "To Year")
To_Month   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
To_Day     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
Start  = timestamp(From_Year, From_Month, From_Day, 00, 00)  // backtest start window
Finish = timestamp(To_Year, To_Month, To_Day, 23, 59)        // backtest finish window

// == INPUTS ==
// ADX Info
adxlen = input(14, title="ADX Smoothing")
dilen = input(14, title="DI Period")
keyLevel = input(23, title="Keylevel for ADX")
adxLookback = input(3, title="Lookback Period for Slope")

// == FILTERING ==
// Inputs
useMaFilter = input(title = "Use MA for Filtering?", type = input.bool, defval = true)
maType = input(defval="EMA", options=["EMA", "SMA"], title = "MA Type For Filtering")
maLength   = input(defval = 200, title = "MA Period for Filtering", minval = 1)

// Declare function to be able to swap out EMA/SMA
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 = ma(maType, close, maLength)
plot(maFilter, title = "Trend Filter MA", color = color.green, linewidth = 3, style = plot.style_line, transp = 50)

// Check to see if the useMaFilter check box is checked, this then inputs this conditional "maFilterCheck" variable into the strategy entry 
maFilterCheck = if useMaFilter == true
    maFilter
else
    close

// == USE BUILT-IN DMI FUNCTION TO DETERMINE ADX AND BULL/BEAR STRENGTH
[diplus, diminus, adx] = dmi(dilen, adxlen)

buySignal = (adx[0]-adx[adxLookback] > 0) and adx > keyLevel and diplus > diminus  and close >= maFilterCheck
// buySignalValue = valuewhen(buySignal, close, 0)
shortSignal = (adx[0]-adx[adxLookback] > 0) and adx > keyLevel and diplus < diminus  and close <= maFilterCheck
// shortSignalValue = valuewhen(shortSignal, close, 0)
sellCoverSignal = adx[0]-adx[adxLookback] < 0

// == ENTRY & EXIT CRITERIA
// Triggers to be TRUE for it to fire of the BUY Signal : (opposite for the SELL signal).
// (1): Price is over the 200 EMA line. (EMA level configurable by the user)
// (2): "D+" is OVER the "D-" line
// (3): RSI 7 is under 30 (for SELL, RSI 7 is over 70)
// 1* = The ultimate is to have a combination line of 3 EMA values, EMA 14, EMA 50 and EMA 200 - And if price is over this "combo" line, then it's a strong signal

// == STRATEGY ENTRIES/EXITS == 
strategy.entry("Long", strategy.long, when = buySignal)
strategy.close("Long", when = sellCoverSignal)
strategy.entry("Short", strategy.short, when = shortSignal)
strategy.close("Short", when = sellCoverSignal)
    
// == ALERTS == 
// alertcondition(buySignal, title='ADX Trigger Buy', message='ADX Trigger Buy')
// alertcondition(sellSignal, title='ADX Trigger Sell', message='ADX Trigger Sell')

Más.