Estrategia de tendencia de cruce de medias móviles


Fecha de creación: 2023-10-27 16:19:00 Última modificación: 2023-10-27 16:19:00
Copiar: 0 Número de Visitas: 742
1
Seguir
1700
Seguidores

Estrategia de tendencia de cruce de medias móviles

Descripción general

La estrategia de cruce de media móvil es una estrategia de impulso que utiliza la señal de cruce de dos medias móviles para determinar la dirección de la tendencia y generar señales de compra y venta. La estrategia utiliza 2 medias móviles simples y 1 media móvil indexada para determinar el margen de diferencia en función de su cruce.

Principio de estrategia

La estrategia utiliza tres promedios móviles:

  • EMA1: Un promedio móvil de un índice de un período más corto, representado por una línea rápida
  • SMA1: promedio móvil simple de un período más largo, que representa una línea lenta
  • SMA2: una media móvil simple de un período más largo para determinar la dirección de la tendencia

La estrategia determina las tendencias en función de la relación entre el tamaño de EMA1, SMA1 y SMA2:

  • Tendencia al alza: EMA1 > SMA1 > SMA2
  • Tendencia a la baja: EMA1 < SMA1 < SMA2

La señal de entrada:

  • Entradas múltiples: Hacer más cuando se cruza la línea lenta en la línea rápida
  • Entrada en blanco: hacer vacío cuando se cruza la línea lenta

La señal de salida:

  • La salida de muchos: bajo la línea rápida, la línea lenta, la posición de equilibrio.
  • Salida en blanco: la línea rápida se queda en la línea lenta.

La estrategia ofrece una configuración de varios parámetros que permiten elegir diferentes promedios móviles para juzgar entradas y salidas.

Análisis de las ventajas

La estrategia tiene las siguientes ventajas:

  1. Capture Momentum: estrategias para capturar cambios en las tendencias del mercado.
  2. Configuración flexible: ofrece varias opciones de promedios móviles que se pueden configurar de manera flexible
  3. filtro de tendencia: utiliza las medias móviles de largo plazo para determinar la dirección de la tendencia y evitar el comercio en contra
  4. Gestión de riesgos: Configuración de paradas y paradas para controlar el riesgo de una sola transacción

Análisis de riesgos

La estrategia también tiene los siguientes riesgos:

  1. Whipsaws: Se espera que la conmoción continúe antes de la ruptura, lo que podría conducir a múltiples falsas rupturas.
  2. sensible to MA parameters: la configuración incorrecta de los parámetros de las medias móviles puede resultar demasiado frecuente o no lo suficientemente sensible
  3. lagging: la naturaleza de las medias móviles es laterales y pueden perder el mejor momento de ruptura
  4. No fundamentals: impulsado por indicadores puramente tecnológicos, sin tener en cuenta los fundamentos

Para el riesgo de whipsaws, se puede ajustar adecuadamente el ciclo de las medias móviles; para el riesgo de sensibilidad a los parámetros, se pueden optimizar los parámetros; para el riesgo de atraso, se pueden optimizar en combinación con otros indicadores previos.

Dirección de optimización

La estrategia puede ser optimizada en los siguientes aspectos:

  1. Añadir filtros de otros indicadores técnicos, como RSI, Brinks, etc., para mejorar la calidad de la señal
  2. Optimización de los parámetros del ciclo de la media móvil para encontrar el parámetro óptimo
  3. Adición de modelos de aprendizaje automático para determinar tendencias y fiabilidad de la señal
  4. Combinando el volumen de transacciones para evitar falsas rupturas en los precios de baja cantidad
  5. Combinación de factores fundamentales para evitar el comercio contra el ciclo económico

Resumir

La estrategia de cruce de la media móvil es en general más simple y directa, y determina la dirección de la tendencia y el momento de participación a través del cruce de la media lenta y rápida. La estrategia tiene la ventaja de poder capturar el momento, los parámetros de configuración flexibles, pero también existe cierto riesgo de whipsaw, el riesgo de atraso, etc. La estrategia puede ser una estrategia de negociación cuantitativa muy práctica mediante la introducción de otros indicadores para la optimización del filtrado.

Código Fuente de la Estrategia
/*backtest
start: 2023-09-26 00:00:00
end: 2023-10-26 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Decam9

//@version=5
strategy(title = "Moving Average Crossover", shorttitle = "MA Crossover Strategy", overlay=true,
     initial_capital = 100000,default_qty_type = strategy.percent_of_equity, default_qty_value = 10)

//Moving Average Inputs
EMA1 = input.int(title="Fast EMA", group = "Moving Averages:", 
     inline = "EMAs", defval=5, minval = 1)
isDynamicEMA = input.bool(title = "Dynamic Exponential Moving Average?", defval = true,
     inline = "EMAs", group = "Moving Averages:", tooltip = "Changes the source of the MA based on trend")

SMA1 = input.int(title = "Slow SMA", group = "Moving Averages:",
     inline = "SMAs", defval = 10, minval = 1)
isDynamicSMA = input.bool(title = "Dynamic Simple Moving Average?", defval = false,
     inline = "SMAs", group = "Moving Averages:", tooltip = "Changes the source of the MA based on trend")

SMA2 = input.int(title="Trend Determining SMA", group = "Moving Averages:",
     inline = "MAs", defval=13, minval = 1)

//Moving Averages
Trend = ta.sma(close, SMA2)
Fast = ta.ema(isDynamicEMA ? (close > Trend ? low : high) : close, EMA1)
Slow = ta.sma(isDynamicSMA ? (close > Trend ? low : high) : close, SMA1)

//Allowed Entries
islong = input.bool(title = "Long", group = "Allowed Entries:",
     inline = "Entries",defval = true)
isshort = input.bool(title = "Short", group = "Allowed Entries:",
     inline = "Entries", defval= true)

//Entry Long Conditions
buycond = input.string(title="Buy when", group = "Entry Conditions:", 
     inline = "Conditions",defval="Fast-Slow Crossing", 
     options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     
intrendbuy = input.bool(title = "In trend", defval = true, group = "Entry Conditions:",
     inline = "Conditions", tooltip = "In trend if price is above SMA 2")

//Entry Short Conditions
sellcond = input.string(title="Sell when", group = "Entry Conditions:", 
     inline = "Conditions2",defval="Fast-Slow Crossing", 
     options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     
intrendsell = input.bool(title = "In trend",defval = true, group = "Entry Conditions:",
     inline = "Conditions2", tooltip = "In trend if price is below SMA 2?")

//Exit Long Conditions
closebuy = input.string(title="Close long when", group = "Exit Conditions:", 
     defval="Fast-Slow Crossing", options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])

//Exit Short Conditions
closeshort = input.string(title="Close short when", group = "Exit Conditions:", 
     defval="Fast-Slow Crossing", options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     

//Filters
filterlong =input.bool(title = "Long Entries", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
filtershort =input.bool(title = "Short Entries", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
filterend =input.bool(title = "Exits", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
usevol =input.bool(title = "", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = false)
rvol = input.int(title = "Volume >", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = 1)
len_vol = input.int(title = "Avg. Volume Over Period", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = 30, minval = 1,
     tooltip="The current volume must be greater than N times the M-period average volume.")
useatr =input.bool(title = "", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = false)
len_atr1 = input.int(title = "ATR", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = 5, minval = 1)
len_atr2 = input.int(title = "> ATR", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = 30, minval = 1,
     tooltip="The N-period ATR must be greater than the M-period ATR.")
usersi =input.bool(title = "", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = false)
rsitrhs1 = input.int(title = "", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = 0, minval=0, maxval=100)
rsitrhs2 = input.int(title = "< RSI (14) <", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = 100, minval=0, maxval=100,
     tooltip="RSI(14) must be in the range between N and M.")
issl =  input.bool(title = "SL", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = false)
slpercent =  input.float(title = ", %", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = 10, minval=0.0)
istrailing =  input.bool(title = "Trailing", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = false)
istp =  input.bool(title = "TP", inline = 'linetp1', group = 'Stop Loss / Take Profit:', 
     defval = false)
tppercent =  input.float(title = ", %", inline = 'linetp1', group = 'Stop Loss / Take Profit:', 
     defval = 20)
     
//Conditions for Crossing
fscrossup = ta.crossover(Fast,Slow)
fscrossdw = ta.crossunder(Fast,Slow)
ftcrossup = ta.crossover(Fast,Trend)
ftcrossdw = ta.crossunder(Fast,Trend)
stcrossup = ta.crossover(Slow,Trend)
stcrossdw = ta.crossunder(Slow,Trend)

//Defining in trend
uptrend = Fast >= Slow and Slow >= Trend
downtrend = Fast <= Slow and Slow <= Trend
justCrossed = ta.cross(Fast,Slow) or ta.cross(Slow,Trend)


//Entry Signals
crosslong = if intrendbuy
    (buycond =="Fast-Slow Crossing" and uptrend ? fscrossup:(buycond =="Fast-Trend Crossing" and uptrend ? ftcrossup:(buycond == "Slow-Trend Crossing" and uptrend ? stcrossup : na))) 
else
    (buycond =="Fast-Slow Crossing"?fscrossup:(buycond=="Fast-Trend Crossing"?ftcrossup:stcrossup))

crossshort = if intrendsell
    (sellcond =="Fast-Slow Crossing" and downtrend ? fscrossdw:(sellcond =="Fast-Trend Crossing" and downtrend ? ftcrossdw:(sellcond == "Slow-Trend Crossing" and downtrend ? stcrossdw : na))) 
else
    (sellcond =="Fast-Slow Crossing"?fscrossdw:(buycond=="Fast-Trend Crossing"?ftcrossdw:stcrossdw))
crossexitlong = (closebuy =="Fast-Slow Crossing"?fscrossdw:(closebuy=="Fast-Trend Crossing"?ftcrossdw:stcrossdw))
crossexitshort = (closeshort =="Fast-Slow Crossing"?fscrossup:(closeshort=="Fast-Trend Crossing"?ftcrossup:stcrossup))


// Filters
rsifilter = usersi?(ta.rsi(close,14) > rsitrhs1 and ta.rsi(close,14) < rsitrhs2):true
volatilityfilter = useatr?(ta.atr(len_atr1) > ta.atr(len_atr2)):true
volumefilter = usevol?(volume > rvol*ta.sma(volume,len_vol)):true
totalfilter = volatilityfilter and volumefilter and rsifilter

//Filtered signals
golong  = crosslong  and islong  and (filterlong?totalfilter:true) 
goshort = crossshort and isshort and (filtershort?totalfilter:true)
endlong  = crossexitlong and (filterend?totalfilter:true)
endshort = crossexitshort and (filterend?totalfilter:true)

// Entry price and TP
startprice = ta.valuewhen(condition=golong or goshort, source=close, occurrence=0)
pm = golong?1:goshort?-1:1/math.sign(strategy.position_size)
takeprofit = startprice*(1+pm*tppercent*0.01)
// fixed stop loss
stoploss = startprice * (1-pm*slpercent*0.01)
// trailing stop loss
if istrailing and strategy.position_size>0
    stoploss := math.max(close*(1 - slpercent*0.01),stoploss[1])
else if istrailing and strategy.position_size<0
    stoploss := math.min(close*(1 + slpercent*0.01),stoploss[1])
    
if golong and islong
    strategy.entry("long",   strategy.long )
if goshort and isshort
    strategy.entry("short",  strategy.short)
if endlong
    strategy.close("long")
if endshort
    strategy.close("short")

// Exit via SL or TP
strategy.exit(id="sl/tp long", from_entry="long", stop=issl?stoploss:na, 
              limit=istp?takeprofit:na)
strategy.exit(id="sl/tp short",from_entry="short",stop=issl?stoploss:na, 
              limit=istp?takeprofit:na)