Estrategia de cruce de ciclos de volumen acumulado y media móvil exponencial de la teoría del trading dinámico

EMA CVP AVWP TOD
Fecha de creación: 2025-01-06 11:45:38 Última modificación: 2025-01-06 11:45:38
Copiar: 1 Número de Visitas: 346
1
Seguir
1617
Seguidores

Estrategia de cruce de ciclos de volumen acumulado y media móvil exponencial de la teoría del trading dinámico

Descripción general

Esta estrategia es un sistema de trading que combina la media móvil exponencial (EMA) y el período de volumen acumulado (CVP). Captura puntos de inflexión en las tendencias del mercado analizando el cruce del promedio móvil exponencial del precio y el precio ponderado por volumen acumulado. La estrategia tiene filtros de tiempo incorporados que pueden limitar las horas de negociación y admitir el cierre automático de posiciones al final del período de negociación. La estrategia ofrece dos métodos de salida diferentes: salida cruzada inversa y salida CVP personalizada, lo que la hace más flexible y adaptable.

Principio de estrategia

La lógica central de la estrategia se basa en los siguientes cálculos clave:

  1. Calcular el precio promedio (AVWP): multiplicar la media aritmética de los precios más alto, más bajo y de cierre por el volumen.
  2. Calcule el valor del período de volumen acumulado: agregue el precio ponderado por volumen durante el período establecido y divida por el volumen acumulado.
  3. Calcule la EMA del precio de cierre y la EMA del CVP por separado.
  4. Se genera una señal larga cuando el precio EMA cruza la EMA CVP hacia arriba; se genera una señal corta cuando el precio EMA cruza la EMA CVP hacia abajo.
  5. La señal de salida puede ser una señal de cruce inversa o una señal de cruce basada en un ciclo CVP personalizado.

Ventajas estratégicas

  1. El sistema de señales es sólido: combina las tendencias de precios y la información del volumen comercial para determinar con mayor precisión las tendencias del mercado.
  2. Fuerte adaptabilidad: el período EMA y el período CVP se pueden ajustar para adaptarse a diferentes entornos de mercado.
  3. Gestión de riesgos perfecta: los filtros de tiempo incorporados pueden evitar operaciones durante períodos que no son adecuados para el trading.
  4. Mecanismo de salida flexible: se proporcionan dos métodos de salida diferentes y puede elegir el método de salida apropiado según las características del mercado.
  5. Buena visualización: La estrategia proporciona una interfaz gráfica clara, que incluye marcadores de señales y relleno del área de tendencia.

Riesgo estratégico

  1. Riesgo de histéresis: la propia EMA tiene cierta histéresis, lo que puede provocar ligeros retrasos en los tiempos de entrada y salida.
  2. Riesgo de mercado volátil: Pueden generarse señales falsas en un mercado lateral y volátil.
  3. Sensibilidad de los parámetros: diferentes combinaciones de parámetros pueden generar grandes diferencias en el rendimiento de la estrategia.
  4. Riesgo de liquidez: En mercados de baja liquidez, los cálculos de CVP pueden no ser lo suficientemente precisos.
  5. Dependencia de la zona horaria: la estrategia utiliza la hora de Nueva York como filtro horario y debe prestar atención a las diferencias en los horarios comerciales en los distintos mercados.

Dirección de optimización de la estrategia

  1. Introducción de filtros de volatilidad: los parámetros de la estrategia se pueden ajustar según la volatilidad del mercado para mejorar la adaptabilidad de la estrategia.
  2. Filtro de tiempo optimizado: se pueden agregar múltiples ventanas de tiempo para controlar las sesiones comerciales con mayor precisión.
  3. Aumentar la evaluación de la calidad del volumen: introducir indicadores de análisis de volumen para filtrar las señales de volumen de baja calidad.
  4. Ajuste dinámico de parámetros: desarrollar un sistema de parámetros adaptativo para ajustar automáticamente los períodos EMA y CVP según las condiciones del mercado.
  5. Agregar indicadores de sentimiento del mercado: combine con otros indicadores técnicos para confirmar las señales comerciales.

Resumir

Se trata de una estrategia de trading cuantitativa con una estructura completa y una lógica clara. Al combinar las ventajas de EMA y CVP, se crea un sistema de trading que puede capturar tendencias mientras se centra en el control de riesgos. La estrategia es altamente personalizable y adecuada para su uso en diferentes entornos de mercado. Mediante la implementación de sugerencias de optimización, existe margen para mejorar aún más el rendimiento de la estrategia.

Código Fuente de la Estrategia
/*backtest
start: 2019-12-23 08:00:00
end: 2025-01-04 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// © sapphire_edge 

// # ========================================================================= #
// #                  
// #        _____                   __    _              ______    __         
// #      / ___/____ _____  ____  / /_  (_)_______     / ____/___/ /___ ____ 
// #      \__ \/ __ `/ __ \/ __ \/ __ \/ / ___/ _ \   / __/ / __  / __ `/ _ \
// #     ___/ / /_/ / /_/ / /_/ / / / / / /  /  __/  / /___/ /_/ / /_/ /  __/
// #    /____/\__,_/ .___/ .___/_/ /_/_/_/   \___/  /_____/\__,_/\__, /\___/ 
// #              /_/   /_/                                     /____/       
// #                                      
// # ========================================================================= #

strategy(shorttitle="⟡Sapphire⟡ EMA/CVP", title="[Sapphire] EMA/CVP Strategy", initial_capital= 50000, currency= currency.USD,default_qty_value = 1,commission_type= strategy.commission.cash_per_contract,overlay= true )

// # ========================================================================= #
// #                       // Settings Menu //
// # ========================================================================= #

// --------------------    Main Settings    -------------------- //
groupEMACVP = "EMA / Cumulative Volume Period"
tradeDirection = input.string(title='Trade Direction', defval='LONG', options=['LONG', 'SHORT'], group=groupEMACVP)
emaLength = input.int(25, title='EMA Length', minval=1, maxval=200, group=groupEMACVP)
cumulativePeriod = input.int(100, title='Cumulative Volume Period', minval=1, maxval=200, step=5, group=groupEMACVP)
exitType = input.string(title="Exit Type", defval="Crossover", options=["Crossover", "Custom CVP" ], group=groupEMACVP)
cumulativePeriodForClose = input.int(50, title='Cumulative Period for Close Signal', minval=1, maxval=200, step=5, group=groupEMACVP)
showSignals = input.bool(true, title="Show Signals", group=groupEMACVP)
signalOffset = input.int(5, title="Signal Vertical Offset", group=groupEMACVP)

// --------------------    Time Filter Inputs    -------------------- //
groupTimeOfDayFilter = "Time of Day Filter"
useTimeFilter1  = input.bool(false, title="Enable Time Filter 1", group=groupTimeOfDayFilter)
startHour1      = input.int(0, title="Start Hour (24-hour format)", minval=0, maxval=23, group=groupTimeOfDayFilter)
startMinute1    = input.int(0, title="Start Minute", minval=0, maxval=59, group=groupTimeOfDayFilter)
endHour1        = input.int(23, title="End Hour (24-hour format)", minval=0, maxval=23, group=groupTimeOfDayFilter)
endMinute1      = input.int(45, title="End Minute", minval=0, maxval=59, group=groupTimeOfDayFilter)
closeAtEndTimeWindow = input.bool(false, title="Close Trades at End of Time Window", group=groupTimeOfDayFilter)

// --------------------    Trading Window    -------------------- //
isWithinTradingWindow(startHour, startMinute, endHour, endMinute) =>
    nyTime            = timestamp("America/New_York", year, month, dayofmonth, hour, minute)
    nyHour            = hour(nyTime)
    nyMinute          = minute(nyTime)
    timeInMinutes     = nyHour * 60 + nyMinute
    startInMinutes    = startHour * 60 + startMinute
    endInMinutes      = endHour * 60 + endMinute
    timeInMinutes    >= startInMinutes and timeInMinutes <= endInMinutes

timeCondition =  (useTimeFilter1 ? isWithinTradingWindow(startHour1, startMinute1, endHour1, endMinute1) : true)

// Check if the current bar is the last one within the specified time window
isEndOfTimeWindow() =>
    nyTime            = timestamp("America/New_York", year, month, dayofmonth, hour, minute)
    nyHour            = hour(nyTime)
    nyMinute          = minute(nyTime)
    timeInMinutes     = nyHour * 60 + nyMinute
    endInMinutes      = endHour1 * 60 + endMinute1
    timeInMinutes == endInMinutes

// Logic to close trades if the time window ends
if timeCondition and closeAtEndTimeWindow and isEndOfTimeWindow()
    strategy.close_all(comment="Closing trades at end of time window")

// # ========================================================================= #
// #                       // Calculations //
// # ========================================================================= #

avgPrice = (high + low + close) / 3
avgPriceVolume = avgPrice * volume

cumulPriceVolume = math.sum(avgPriceVolume, cumulativePeriod)
cumulVolume = math.sum(volume, cumulativePeriod)
cumValue = cumulPriceVolume / cumulVolume

cumulPriceVolumeClose = math.sum(avgPriceVolume, cumulativePeriodForClose)
cumulVolumeClose = math.sum(volume, cumulativePeriodForClose)
cumValueClose = cumulPriceVolumeClose / cumulVolumeClose

emaVal = ta.ema(close, emaLength)
emaCumValue = ta.ema(cumValue, emaLength)

// # ========================================================================= #
// #                       // Signal Logic //
// # ========================================================================= #

// Strategy Entry Conditions
longEntryCondition = ta.crossover(emaVal, emaCumValue) and tradeDirection == 'LONG'
shortEntryCondition = ta.crossunder(emaVal, emaCumValue) and tradeDirection == 'SHORT'

// User-Defined Exit Conditions
longExitCondition = false
shortExitCondition = false

if exitType == "Crossover"
    longExitCondition := ta.crossunder(emaVal, emaCumValue)
    shortExitCondition := ta.crossover(emaVal, emaCumValue)

if exitType == "Custom CVP"
    emaCumValueClose = ta.ema(cumValueClose, emaLength)
    longExitCondition := ta.crossunder(emaVal, emaCumValueClose)
    shortExitCondition := ta.crossover(emaVal, emaCumValueClose)

// # ========================================================================= #
// #                       // Strategy Management //
// # ========================================================================= #

// Strategy Execution
if longEntryCondition and timeCondition
    strategy.entry('Long', strategy.long)
    label.new(bar_index, high - signalOffset, "◭", style=label.style_label_up, color = color.rgb(119, 0, 255, 20), textcolor=color.white)

if shortEntryCondition and timeCondition
    strategy.entry('Short', strategy.short)
    label.new(bar_index, low + signalOffset, "⧩", style=label.style_label_down, color = color.rgb(255, 85, 0, 20), textcolor=color.white)

if strategy.position_size > 0 and longExitCondition
    strategy.close('Long')

if strategy.position_size < 0 and shortExitCondition
    strategy.close('Short')

// # ========================================================================= #
// #                         // Plots and Charts //
// # ========================================================================= #

plot(emaVal, title='EMA', color=color.new(color.green, 25))
plot(emaCumValue, title='Cumulative EMA', color=color.new(color.purple, 35))
fill(plot(emaVal), plot(emaCumValue), color=emaVal > emaCumValue ? #008ee6 : #d436a285, title='EMA and Cumulative Area', transp=70)