Estrategia de trading cuantitativo de cruce de medias móviles de apertura y cierre combinada con el indicador dinámico ADX

MA ADX SMMA EMA DEMA TEMA WMA VWMA HullMA LSMA ALMA SSMA TMA ATR
Fecha de creación: 2025-02-18 13:35:54 Última modificación: 2025-02-18 13:35:54
Copiar: 1 Número de Visitas: 445
1
Seguir
1617
Seguidores

Estrategia de trading cuantitativo de cruce de medias móviles de apertura y cierre combinada con el indicador dinámico ADX

Descripción general

Se trata de una estrategia de comercio cuantitativa basada en cruces de medias móviles entre el precio de apertura y el precio de cierre, y que utiliza como filtro el indicador de tendencia promedio ((ADX)). La estrategia utiliza varios tipos de medias móviles, incluidos SMMA, EMA, DEMA, etc., para capturar cambios en la tendencia del mercado mediante la identificación de puntos de cruce de medias, mientras que el indicador ADX se utiliza para confirmar la fuerza de la tendencia, lo que mejora la fiabilidad de las operaciones.

Principio de estrategia

La lógica central de la estrategia es la de calcular las medias móviles de los precios de apertura y cierre, generando una señal múltiple cuando la media de cierre cruza hacia arriba la media de apertura y el valor de ADX es mayor que el umbral establecido; y una señal de cero cuando la media de cierre cruza hacia abajo la media de apertura y el valor de ADX es mayor que el umbral establecido. La estrategia admite varios métodos de cálculo de medias móviles, incluidas las medias móviles simples (SMA), las medias móviles de índices (EMA) y las medias móviles de índices dobles (EMAD), y puede elegir el tipo de media más adecuado según las diferentes características del mercado.

Ventajas estratégicas

  1. Flexible: soporta varios tipos de medias móviles y puede elegir el método de medias óptimo en función de las diferentes circunstancias del mercado
  2. Confirmación de tendencias: filtración de indicadores ADX para reducir las señales falsas en mercados convulsionados
  3. Control de riesgo completo: incluye funciones de stop loss y stop-loss para controlar eficazmente el riesgo de cada transacción
  4. Alta personalización: ofrece múltiples interfaces de parámetros, incluidos el ciclo de la línea media, el límite de ADX, la dirección de la operación, etc., para facilitar la optimización de la estrategia
  5. Soporte de múltiples períodos de tiempo: puede funcionar en diferentes períodos de tiempo para adaptarse a diferentes estilos de negociación

Riesgo estratégico

  1. Lagresión de la media: la media móvil es esencialmente un indicador de retraso, y puede generar señales de retraso en mercados que fluctúan rápidamente
  2. Riesgo de brechas falsas: puede haber brechas falsas en la línea media durante una oscilación del mercado, aunque hay filtración de ADX que debe tenerse en cuenta
  3. Sensibilidad de parámetros: los efectos de la estrategia son sensibles a la configuración de parámetros y necesitan un ajuste adecuado en diferentes entornos de mercado
  4. Adaptabilidad del mercado: mejor desempeño en mercados con una tendencia evidente, pero puede operar con frecuencia en mercados convulsionados
  5. Complejidad del cálculo: el cálculo de varios tipos de línea media puede aumentar la carga del sistema y se debe tener en cuenta la eficiencia operativa

Dirección de optimización de la estrategia

  1. Introducción de indicadores de volumen: la efectividad de la tendencia se puede confirmar combinando cambios en el volumen
  2. Optimización de los parámetros de ADX: ajustar los umbrales de ADX en función de las diferentes dinámicas del ciclo del mercado
  3. Aumento de indicadores de confirmación de tendencias: se puede considerar la adición de otros indicadores de tendencias para mejorar la fiabilidad de la señal
  4. Mecanismo de detención de pérdidas mejorado: introducción de detención de pérdidas de seguimiento o detención de pérdidas de adaptación a la tasa de fluctuación
  5. Optimizar el momento de negociación: considerar la volatilidad y la liquidez del mercado para elegir el mejor momento de negociación

Resumir

Se trata de un sistema de trading cuantitativo que combina la clásica estrategia de equilátero cruzado con el indicador ADX. Con el apoyo de varios tipos de equilátero y la confirmación de tendencias en ADX, se puede tener una mejor comprensión de las tendencias del mercado, al tiempo que se cuenta con un mecanismo de control de riesgos completo. La estrategia es altamente personalizable y se puede ajustar de manera óptima según las diferentes circunstancias del mercado.

Código Fuente de la Estrategia
/*backtest
start: 2024-02-18 00:00:00
end: 2025-02-16 08:00:00
period: 3d
basePeriod: 3d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © algostudio

//@version=6
strategy("Open Close Cross Strategy R5.1", shorttitle="OCC Strategy R5.1", overlay=true,
     pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=10, calc_on_every_tick=false)

// === INPUTS ===
useRes      = input.bool(true, title="Use Alternate Resolution?")
intRes      = input.int(3, title="Multiplier for Alternate Resolution", minval=1)
stratRes    = timeframe.ismonthly ? str.tostring(timeframe.multiplier * intRes) + "M" :
              timeframe.isweekly ? str.tostring(timeframe.multiplier * intRes) + "W" :
              timeframe.isdaily ? str.tostring(timeframe.multiplier * intRes) + "D" :
              timeframe.isintraday ? str.tostring(timeframe.multiplier * intRes) : "60"

basisType   = input.string("SMMA", title="MA Type:", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "HullMA", "LSMA", "ALMA", "SSMA", "TMA"])
basisLen    = input.int(8, title="MA Period", minval=1)
offsetSigma = input.int(6, title="Offset for LSMA / Sigma for ALMA", minval=0)
offsetALMA  = input.float(0.85, title="Offset for ALMA", minval=0, step=0.01)
scolor      = input.bool(false, title="Show Colored Bars to Indicate Trend?")
delayOffset = input.int(0, title="Delay Open/Close MA (Forces Non-Repainting)", minval=0, step=1)
tradeType   = input.string("BOTH", title="What trades should be taken:", options=["LONG", "SHORT", "BOTH", "NONE"])

// === BASE FUNCTIONS ===
variant(type, src, len, offSig, offALMA) =>
    if type == "EMA"
        ta.ema(src, len)
    else if type == "DEMA"
        ta.ema(ta.ema(src, len), len) * 2 - ta.ema(ta.ema(ta.ema(src, len), len), len)
    else if type == "TEMA"
        3 * (ta.ema(src, len) - ta.ema(ta.ema(src, len), len)) + ta.ema(ta.ema(ta.ema(src, len), len), len)
    else if type == "WMA"
        ta.wma(src, len)
    else if type == "VWMA"
        ta.vwma(src, len)
    else if type == "SMMA"
        ta.sma(src, len)
    else if type == "HullMA"
        ta.wma(2 * ta.wma(src, len / 2) - ta.wma(src, len), math.round(math.sqrt(len)))
    else if type == "LSMA"
        ta.linreg(src, len, offSig)
    else if type == "ALMA"
        ta.alma(src, len, offALMA, offSig)
    else if type == "TMA"
        ta.sma(ta.sma(src, len), len)
    else
        ta.sma(src, len)

// Security wrapper
reso(exp, use, res) => use ? request.security(syminfo.tickerid, res, exp, lookahead=barmerge.lookahead_on) : exp

// === SERIES SETUP ===
closeSeries = variant(basisType, close[delayOffset], basisLen, offsetSigma, offsetALMA)
openSeries  = variant(basisType, open[delayOffset], basisLen, offsetSigma, offsetALMA)

// Alternate resolution series
closeSeriesAlt = reso(closeSeries, useRes, stratRes)
openSeriesAlt  = reso(openSeries, useRes, stratRes)

// Trend Colors
trendColour = closeSeriesAlt > openSeriesAlt ? color.green : color.red
bcolour     = closeSeries > openSeriesAlt ? color.lime : color.red
barcolor(scolor ? bcolour : na, title="Bar Colours")

closeP = plot(closeSeriesAlt, title="Close Series", color=trendColour, linewidth=2, style=plot.style_line)
openP  = plot(openSeriesAlt, title="Open Series", color=trendColour, linewidth=2, style=plot.style_line)
fill(closeP, openP, color=trendColour)
// === ADX FILTER ===
// ADX Calculation
// Input parameters
adxLength = input.int(14, title="ADX Length", minval=1)
adxfilter = input.int(13, title="ADX filter", minval=1)
// Calculate +DM and -DM (Directional Movement)
plusDM = math.max(high - high[1], 0)
minusDM = math.max(low[1] - low, 0)

// Remove cases where both are positive
plusDM := plusDM > minusDM ? plusDM : 0
minusDM := minusDM > plusDM ? minusDM : 0

// Smooth the directional movement using RMA
smoothedPlusDM = ta.rma(plusDM, adxLength)
smoothedMinusDM = ta.rma(minusDM, adxLength)

// Calculate True Range and smooth it
tr = ta.atr(adxLength)
smoothedTR = ta.rma(tr, adxLength)

// Compute +DI and -DI
plusDI = (smoothedPlusDM / smoothedTR) * 100
minusDI = (smoothedMinusDM / smoothedTR) * 100

// Compute DX (Directional Index)
dx = math.abs(plusDI - minusDI) / (plusDI + minusDI) * 100

// Compute ADX by smoothing DX
adx = ta.rma(dx, adxLength)




// === UPDATED TRADE CONDITIONS ===
xlong     = ta.crossover(closeSeriesAlt, openSeriesAlt) and adx > adxfilter
xshort    = ta.crossunder(closeSeriesAlt, openSeriesAlt) and adx > adxfilter
longCond  = xlong
shortCond = xshort


// === STRATEGY ===
slPoints  = input.float(0, title="Initial Stop Loss Points", minval=0)
tpPoints  = input.float(0, title="Initial Target Profit Points", minval=0)
ebar      = input.int(10000, title="Number of Bars for Back Testing", minval=0)

tdays     = (timenow - time) / 60000.0

tdays     := timeframe.ismonthly ? tdays / 1440.0 / 5.0 / 4.3 / timeframe.multiplier :
             timeframe.isweekly ? tdays / 1440.0 / 5.0 / timeframe.multiplier :
             timeframe.isdaily ? tdays / 1440.0 / timeframe.multiplier :
             tdays / timeframe.multiplier

TP = tpPoints > 0 ? tpPoints : na
SL = slPoints > 0 ? slPoints : na

if (ebar == 0 or tdays <= ebar)
    if longCond and tradeType != "SHORT"
        strategy.entry("long", strategy.long)
    if shortCond and tradeType != "LONG"
        strategy.entry("short", strategy.short)
    if shortCond and tradeType == "LONG"
        strategy.close("long")
    if longCond and tradeType == "SHORT"
        strategy.close("short")
    strategy.exit("XL", from_entry="long", profit=TP, loss=SL)
    strategy.exit("XS", from_entry="short", profit=TP, loss=SL)

// === END ===