Estrategia de cruce de la media móvil del ángulo de tendencia

El autor:¿ Qué pasa?, Fecha: 2024-01-25 14:35:13
Las etiquetas:

img

Resumen general

Esta estrategia determina la dirección de la tendencia calculando el ángulo de pendiente de las medias móviles, combinado con el indicador de tasa de cambio de precios para el comercio largo y corto.

Estrategia lógica

La estrategia se basa principalmente en los siguientes indicadores de evaluación:

  1. Ángulo de inclinación del promedio móvil: Calcule los ángulos de inclinación del promedio móvil de Jurik y del promedio móvil exponencial para determinar la dirección de la tendencia del precio.

Específicamente, la estrategia primero calcula los ángulos de pendiente de Jurik MA y EMA. Luego se calcula el indicador de tasa de cambio de precios para filtrar el período limitado por el rango.

Análisis de ventajas

Las ventajas de esta estrategia:

  1. Usar la pendiente MA para determinar la tendencia es muy confiable con una buena tasa de ganancia.

  2. El indicador de tasa de cambio de precios filtra efectivamente las fluctuaciones de los rangos para evitar operaciones no válidas.

  3. Jurik MA da una respuesta rápida a la ruptura mientras que la EMA ofrece un juicio de tendencia estable, ambos complementarios.

Análisis de riesgos

Algunos riesgos de esta estrategia:

  1. En casos extremos, el MA puede generar señales erróneas, lo que puede reducirse mediante la optimización de parámetros.

  2. Las señales pueden cambiar con frecuencia durante el rango causando operaciones innecesarias.

  3. El stop loss puede romperse en eventos repentinos de brecha de precios.

Direcciones de optimización

La estrategia se puede optimizar en los siguientes aspectos:

  1. Se incluyen los valores de las transacciones en las que el valor de las transacciones no es válido, incluidas las transacciones en las que el valor de las transacciones no es válido.

  2. Incorporar otros indicadores para una posición de stop loss más inteligente.

  3. Desarrollar algoritmos adaptativos de dimensionamiento de la posición para una rentabilidad más estable.

Conclusión

En general, esta es una estrategia de seguimiento de tendencias muy práctica. Determina confiablemente la tendencia utilizando el ángulo de pendiente MA y filtra eficazmente las señales de ruido utilizando el indicador de tasa de cambio de precios. Tomar posiciones largas y cortas podría obtener una buena ganancia. Con optimizaciones continuas, esta estrategia puede convertirse en una estrategia cuantitativa muy estable y confiable.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// Based on ma angles code by Duyck which also uses Everget Jurik MA calulation and angle calculation by KyJ
strategy("Trend Angle BF", overlay=false)

/////////////// Time Frame ///////////////
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
    
src=input(ohlc4,title="source")

// definition of "Jurik Moving Average", by Everget
jma(_src,_length,_phase,_power) =>
    phaseRatio = _phase < -100 ? 0.5 : _phase > 100 ? 2.5 : _phase / 100 + 1.5
    beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2)
    alpha = pow(beta, _power)
    jma = 0.0
    e0 = 0.0
    e0 := (1 - alpha) * _src + alpha * nz(e0[1])
    e1 = 0.0
    e1 := (_src - e0) * (1 - beta) + beta * nz(e1[1])
    e2 = 0.0
    e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1])
    jma := e2 + nz(jma[1])

//// //// Determine Angle by KyJ //// //// 
angle(_src) =>
    rad2degree=180/3.14159265359  //pi 
    ang=rad2degree*atan((_src[0] - _src[1])/atr(14)) 

jma_line=jma(src,10,50,1)
ma=ema(src,input(56))
jma_slope=angle(jma_line)
ma_slope=angle(ma)

///////////// Rate Of Change ///////////// 
source = close
roclength = input(12, minval=1)
pcntChange = input(2, minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

/////////////// Strategy ///////////////
long = ma_slope>=0 and isMoving()
short = ma_slope<=0 and isMoving()

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])
sl_inp = input(2.0, title='Stop Loss %') / 100
tp_inp = input(900.0, title='Take Profit %') / 100 
 
take_level_l = strategy.position_avg_price * (1 + tp_inp)
take_level_s = strategy.position_avg_price * (1 - tp_inp) 

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[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

/////////////// Execution /////////////// 
if testPeriod()
    strategy.entry("Long",  strategy.long, when=long)
    strategy.entry("Short", strategy.short, when=short)
    strategy.exit("Long Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0)
    strategy.exit("Short Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0)
    
///////////// Plotting /////////////
hline(0, title='Zero line', color=color.purple, linewidth=1)
plot(ma_slope,title="ma slope", linewidth=2,color=ma_slope>=0?color.lime:color.red)
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30) 


Más.