Estrategia de seguimiento de tendencias basada en medias móviles cuantitativas


Fecha de creación: 2023-09-18 13:23:52 Última modificación: 2023-09-18 13:23:52
Copiar: 0 Número de Visitas: 637
1
Seguir
1617
Seguidores

Descripción general

La estrategia se basa en el cálculo de dos promedios móviles basados en el volumen de transacciones y en la dirección de su diferencia para determinar la dirección de la tendencia actual, y luego realizar una posición larga o corta. La estrategia es sencilla y fácil de manejar y puede seguir eficazmente la tendencia del mercado.

Principio de estrategia

  1. Calcular la línea rápida y la línea lenta. La línea rápida es una media móvil cuantitativa basada en el ciclo de la línea rápida definida por el usuario, y la línea lenta es una media móvil cuantitativa basada en el ciclo de la línea lenta.

  2. Calcular la diferencia entre dos líneas. La línea rápida menos la línea lenta obtiene la curva de diferencia.

  3. Para determinar la dirección de la tendencia. Cuando la línea rápida atraviesa la línea lenta, haga más para señales positivas; cuando la línea rápida atraviesa la línea lenta para señales negativas, haga vacío.

  4. Emite una señal de negociación. Emite una señal de más cuando está en alza; emite una señal de vacío cuando está en baja.

  5. Configuración de la parada. La posición de la parada se configura a través de un porcentaje de parada fijo definido por el usuario o una parada dinámica basada en el ATR.

  6. Condiciones de salida: Si se activa un stop loss o se produce una señal de reversión, la posición se despega al mantener la posición.

Análisis de las ventajas

  1. El uso de indicadores cuantitativos para identificar tendencias no es fácil de confundir con falsos avances.

  2. La línea rápida y lenta se combina para filtrar el ruido del mercado y evitar el comercio frecuente.

  3. La configuración Stop Loss es un control efectivo del riesgo de pérdidas.

  4. La lógica de la estrategia es simple, clara y fácil de entender.

  5. Los parámetros se pueden personalizar para satisfacer las necesidades de diferentes variedades y períodos de tiempo.

Análisis de riesgos

  1. La configuración incorrecta de los parámetros puede causar una frecuencia de transacción excesiva o una tendencia perdida.

  2. El stop loss fijo puede ser demasiado mecánico para adaptarse a los cambios en el mercado.

  3. Los cambios en la relación entre la cantidad y el precio pueden afectar la eficacia de los indicadores cuantitativos.

  • El riesgo 1 se puede encontrar a través de los parámetros de optimización.

  • El riesgo 2 puede ser reemplazado por el stop fijo con un stop ATR dinámico.

  • El riesgo 3 requiere la atención sobre el impacto de los cambios en el volumen de negocios en la estrategia.

Dirección de optimización

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

  2. Pruebe otros indicadores de tipo cuantitativo, como el OBV, el índice William, etc.

  3. Aumentar el stop loss basado en la volatilidad.

  4. Evaluar el efecto de la combinación con otros indicadores.

  5. Evaluación de la eficacia en las diferentes variedades de transacciones.

Resumir

La estrategia sigue la tendencia a través de una combinación de líneas rápidas y lentas de medias cuantificadas, la lógica de negociación es simple y clara, y los parámetros se pueden ajustar de manera óptima. La configuración de stop loss ayuda a controlar el riesgo.

Código Fuente de la Estrategia
/*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)