Tendencia de la media móvil cuantitativa siguiendo la estrategia

El autor:¿ Qué pasa?, Fecha: 2023-09-18 13: 23:52
Las etiquetas:

Resumen general

Esta estrategia calcula dos promedios móviles ponderados por volumen como líneas rápidas y lentas. Determina la dirección de la tendencia en función de la diferencia entre las dos líneas y toma posiciones largas o cortas en consecuencia. La estrategia es simple y efectiva en el seguimiento de las tendencias del mercado.

Estrategia lógica

  1. Calcular líneas rápidas y lentas utilizando promedios móviles ponderados por volumen basados en períodos rápidos y lentos definidos por el usuario.

  2. Calcula la diferencia entre las líneas rápidas y lentas.

  3. Determinar la dirección de la tendencia: el cruce de la línea rápida por encima de la línea lenta indica una tendencia al alza y el cruce por debajo indica una tendencia a la baja.

  4. Emitir señales largo/corto. Ir largo cuando la línea rápida cruza por encima de la línea lenta. Ir corto cuando la línea rápida cruza por debajo de la línea lenta.

  5. Se establecerá un stop loss basado en un porcentaje fijo definido por el usuario o en un ATR dinámico.

  6. Reglas de salida: cierre de posición si se alcanza la stop loss o se produce la señal de marcha atrás.

Ventajas

  1. Utiliza un indicador cuantitativo para identificar tendencias y evitar falsas rupturas.

  2. La combinación de líneas rápidas y lentas filtra el ruido del mercado y evita el exceso de negociación.

  3. El stop loss controla eficazmente el riesgo a la baja.

  4. Una lógica sencilla y fácil de entender.

  5. Parámetros personalizables para diferentes productos y plazos.

Los riesgos

  1. La configuración incorrecta de los parámetros puede provocar un exceso de negociación o tendencias perdidas.

  2. El stop loss fijo puede ser demasiado rígido para las condiciones cambiantes del mercado.

  3. Los cambios en las relaciones de volumen y precio pueden afectar a la eficacia.

  • El riesgo 1 puede mitigarse mediante la optimización de parámetros.

  • El riesgo 2 se puede abordar a través de la parada de pérdida ATR dinámica.

  • El riesgo 3 necesita monitorear los cambios de volumen.

Oportunidades de mejora

  1. Prueba diferentes combinaciones de parámetros de línea rápida y lenta.

  2. Pruebe con otros indicadores de volumen-precio como OBV, Williams %R, etc.

  3. Añadir paradas basadas en la volatilidad.

  4. Evaluar la combinación con otros indicadores.

  5. Prueba de la eficacia en diferentes instrumentos de negociación.

Conclusión

Esta estrategia utiliza promedios móviles cuantificados rápidos y lentos para rastrear las tendencias con una lógica simple. Los parámetros se pueden optimizar y se detiene el control del riesgo.


/*backtest
start: 2023-08-18 00:00:00
end: 2023-09-17 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("EVWMA 6HR", overlay=false, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)
// Credit to QuantNomad for the main idea behind this code
/////////////// Time Frame ///////////////
_1 = input(false,  "════════ Test Period ═══════")
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

///////////// EVWMA /////////////
_2 = input(false,  "════════ EVMA ═══════")

fast_sum_length = input(5, title = "Fast Sum Length",  type = input.integer)
slow_sum_length = input(11, title = "Slow Sum Length",  type = input.integer)

fast_vol_period = sum(volume, fast_sum_length)
slow_vol_period = sum(volume, slow_sum_length)

fast_evwma = 0.0
fast_evwma := ((fast_vol_period - volume) * nz(fast_evwma[1], close) + volume * close) / (fast_vol_period)
slow_evwma = 0.0
slow_evwma := ((slow_vol_period - volume) * nz(slow_evwma[1], close) + volume * close) / (slow_vol_period)

diff = fast_evwma - slow_evwma

///////////////  Strategy  /////////////// 
long = fast_evwma > slow_evwma 
short = fast_evwma < slow_evwma 

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

/////////////// Dynamic ATR Stop Losses ///////////////
_4 = input(false,  "════════ Stop Loss ═══════")
SL_type = input("Fixed", options=["Fixed", "ATR Derived"], title="Stop Loss Type")
sl_inp = input(9.0, title='Fixed Stop Loss %') / 100
atrLkb = input(20, minval=1, title='ATR Stop Period')
atrMult = input(1.5, step=0.25, title='ATR Stop Multiplier') 
atr1 = atr(atrLkb)

longStop1 = 0.0
longStop1 :=  short_signal ? na : long_signal ? close - (atr1 * atrMult) : longStop1[1]
shortStop1 = 0.0
shortStop1 := long_signal ? na : short_signal ? close + (atr1 * atrMult) : shortStop1[1]

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

_5 = input(false,  "══════ Longs or Shorts ═════")
useLongs = input(true, title="Use Longs")
useShorts = input(true, title="Use Shorts")

/////////////// Execution ///////////////
if testPeriod()
    if useLongs
        strategy.entry("L", strategy.long, when=long)
        strategy.exit("L SL", "L", stop = SL_type == "Fixed" ? long_sl : longStop1, when=since_longEntry > -1)
    if useShorts
        strategy.exit("S SL", "S", stop = SL_type == "Fixed" ? short_sl : shortStop1, when=since_shortEntry > -1)
        strategy.entry("S", strategy.short, when=short)
    if not useShorts
        strategy.close("L", when=short)
    if not useLongs
        strategy.close("S", when=long)

/////////////// Plotting /////////////// 
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
p1 = plot(diff, title = "Delta", color = long ? color.lime : short ? color.red : na, transp=0)
p2 = plot(0, color = color.white)
fill(p1, p2, color = long ? color.lime : short ? color.red : na, transp=60)

Más.