La estrategia de inversión de media móvil doble es una estrategia de inversión de media típica a corto plazo. La estrategia genera señales de trading por dos medias móviles con diferentes parámetros.
La estrategia utiliza dos promedios móviles para generar señales comerciales. La primera apertura MA se utiliza para determinar la dirección de la tendencia. La segunda maclosing MA se utiliza para generar señales comerciales.
Cuando el maopening sube, indica que el mercado actual está en una tendencia alcista. Cuando el maopening baja, indica que el mercado actual está en una tendencia bajista. el maclosing se multiplica por un coeficiente mayor a 1 para hacerlo más sensible para generar señales tempranas de reversión.
Específicamente, cuando el maopening sube y el maclosing cruza por debajo del maopening, indica una inversión de tendencia. La estrategia abrirá una posición corta. Cuando el maopening baja y el maclosing cruza por encima del maopening, indica una inversión de tendencia. La estrategia abrirá una posición larga.
Los parámetros de la estrategia incluyen el tipo de MA, longitud, fuente de datos, etc. El rendimiento comercial se puede optimizar ajustando estos parámetros. También hay algunas opciones configurables como regla de entrada, stop loss, etc.
Las principales ventajas de la Estrategia de reversión de la doble MA son las siguientes:
Las medias móviles rápidas pueden capturar rápidamente las reversiones a corto plazo con reducciones más pequeñas.
El cruce de dos MAs genera señales comerciales claras.
Muy configurable con múltiples parámetros ajustables.
Fácil de automatizar con un flujo lógico claro. La lógica simple y el comercio de alta frecuencia lo hacen muy adecuado para el comercio automatizado.
El riesgo controlado con un mecanismo de stop loss.
También existen algunos riesgos de la estrategia:
El retraso de las señales de cruce de MA. Los propios MA se quedan atrás del precio. El cruce puede ocurrir después de que la tendencia se haya invertido durante algún tiempo.
La tendencia inversa puede invertirse rápidamente, causando pérdidas consecutivas.
Aunque el stop loss limita la pérdida única, el stop loss consecutivo puede llevar a grandes drawdowns.
Riesgo de sobreajuste: la optimización excesiva de parámetros puede conducir a un sobreajuste y un bajo rendimiento en el comercio en vivo.
Las soluciones incluyen:
Optimice los parámetros para encontrar MAs más rápidos.
Añadir filtros, como indicadores de volumen y volatilidad, para evitar las operaciones de la sierra.
Ajustar la posición de stop loss para disminuir la probabilidad de una stop loss consecutiva.
Prueba de robustez de conjuntos de parámetros para evaluar los riesgos de sobreajuste.
La estrategia se puede optimizar aún más en los siguientes aspectos:
Prueba diferentes tipos de MA para encontrar los más sensibles, como KAMA, ZLEMA, etc.
Optimice las longitudes de MA para encontrar la combinación óptima.
Prueba diferentes fuentes de datos, como el precio cerrado, el precio medio, el precio típico, etc.
Añadir filtro de tendencia para evitar señales de reversión inadecuadas, como el canal Donchian.
Añadir otros indicadores para su confirmación, como MACD, OBV, etc.
Mejorar los mecanismos de gestión de riesgos, como mover el stop loss, la pérdida máxima de la cuenta, etc.
Optimización de la cartera para encontrar la mejor asignación de activos.
Prueba de robustez de los parámetros para evaluar los riesgos de sobreajuste.
La inversión de doble MA es una estrategia de negociación a corto plazo simple y práctica. Es adecuada para capturar inversiones a corto plazo con negociación cuantitativa. Sin embargo, existen riesgos como retrasos y operaciones de whipsaw. La estrategia se puede mejorar optimizando parámetros, agregando filtros, mejorando el control de riesgos, etc. para desarrollar una estrategia estable y eficiente con un buen rendimiento comercial real.
/*backtest start: 2023-10-17 00:00:00 end: 2023-11-16 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy(title = "hamster-bot MRS 2", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, pyramiding = 9, commission_value = 0.045, backtest_fill_limits_assumption = 1) info_options = "Options" on_close = input(false, title = "Entry on close", inline=info_options, group=info_options) OFFS = input.int(0, minval = 0, maxval = 1, title = "| Offset View", inline=info_options, group=info_options) trade_offset = input.int(0, minval = 0, maxval = 1, title = "Trade", inline=info_options, group=info_options) use_kalman_filter = input.bool(false, title="Use Kalman filter", group=info_options) //MA Opening info_opening = "MA Opening" maopeningtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_opening, group=info_opening) maopeningsrc = input.source(ohlc4, title = "", inline=info_opening, group=info_opening) maopeninglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_opening, group=info_opening) //MA Closing info_closing = "MA Closing" maclosingtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_closing, group=info_closing) maclosingsrc = input.source(ohlc4, title = "", inline=info_closing, group=info_closing) maclosinglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_closing, group=info_closing) maclosingmul = input.float(1, step = 0.005, title = "mul", inline=info_closing, group=info_closing) long1on = input(true, title = "", inline = "long1") long1shift = input.float(0.96, step = 0.005, title = "Long", inline = "long1") long1lot = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "long1") short1on = input(true, title = "", inline = "short1") short1shift = input.float(1.04, step = 0.005, title = "short", inline = "short1") short1lot = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "short1") startTime = input(timestamp("01 Jan 2010 00:00 +0000"), "Start date", inline = "period") finalTime = input(timestamp("31 Dec 2030 23:59 +0000"), "Final date", inline = "period") HMA(_src, _length) => ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length))) EHMA(_src, _length) => ta.ema(2 * ta.ema(_src, _length / 2) - ta.ema(_src, _length), math.round(math.sqrt(_length))) THMA(_src, _length) => ta.wma(ta.wma(_src,_length / 3) * 3 - ta.wma(_src, _length / 2) - ta.wma(_src, _length), _length) tema(sec, length)=> tema1= ta.ema(sec, length) tema2= ta.ema(tema1, length) tema3= ta.ema(tema2, length) tema_r = 3*tema1-3*tema2+tema3 donchian(len) => math.avg(ta.lowest(len), ta.highest(len)) ATR_func(_src, _len)=> atrLow = low - ta.atr(_len) trailAtrLow = atrLow trailAtrLow := na(trailAtrLow[1]) ? trailAtrLow : atrLow >= trailAtrLow[1] ? atrLow : trailAtrLow[1] supportHit = _src <= trailAtrLow trailAtrLow := supportHit ? atrLow : trailAtrLow trailAtrLow f_dema(src, len)=> EMA1 = ta.ema(src, len) EMA2 = ta.ema(EMA1, len) DEMA = (2*EMA1)-EMA2 f_zlema(src, period) => lag = math.round((period - 1) / 2) ema_data = src + (src - src[lag]) zl= ta.ema(ema_data, period) f_kalman_filter(src) => float value1= na float value2 = na value1 := 0.2 * (src - src[1]) + 0.8 * nz(value1[1]) value2 := 0.1 * (ta.tr) + 0.8 * nz(value2[1]) lambda = math.abs(value1 / value2) alpha = (-math.pow(lambda, 2) + math.sqrt(math.pow(lambda, 4) + 16 * math.pow(lambda, 2)))/8 value3 = float(na) value3 := alpha * src + (1 - alpha) * nz(value3[1]) //SWITCH ma_func(modeSwitch, src, len, use_k_f=true) => modeSwitch == "SMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.sma(src, len)) : ta.sma(src, len) : modeSwitch == "RMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.rma(src, len)) : ta.rma(src, len) : modeSwitch == "EMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.ema(src, len)) : ta.ema(src, len) : modeSwitch == "TEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(tema(src, len)) : tema(src, len): modeSwitch == "DEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(f_dema(src, len)) : f_dema(src, len): modeSwitch == "ZLEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(f_zlema(src, len)) : f_zlema(src, len): modeSwitch == "WMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.wma(src, len)) : ta.wma(src, len): modeSwitch == "VWMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.vwma(src, len)) : ta.vwma(src, len): modeSwitch == "Hma" ? use_kalman_filter and use_k_f ? f_kalman_filter(HMA(src, len)) : HMA(src, len): modeSwitch == "Ehma" ? use_kalman_filter and use_k_f ? f_kalman_filter(EHMA(src, len)) : EHMA(src, len): modeSwitch == "Thma" ? use_kalman_filter and use_k_f ? f_kalman_filter(THMA(src, len/2)) : THMA(src, len/2): modeSwitch == "ATR" ? use_kalman_filter and use_k_f ? f_kalman_filter(ATR_func(src, len)): ATR_func(src, len) : modeSwitch == "L" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.lowest(len)): ta.lowest(len) : modeSwitch == "H" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.highest(len)): ta.highest(len) : modeSwitch == "DMA" ? donchian(len) : na //Var sum = 0.0 maopening = 0.0 maclosing = 0.0 os = maopeningsrc cs = maclosingsrc pos = strategy.position_size p = 0.0 p := pos == 0 ? (strategy.equity / 100) / close : p[1] truetime = true loss = 0.0 maxloss = 0.0 equity = 0.0 //MA Opening maopening := ma_func(maopeningtyp, maopeningsrc, maopeninglen) //MA Closing maclosing := ma_func(maclosingtyp, maclosingsrc, maclosinglen) * maclosingmul long1 = long1on == false ? 0 : long1shift == 0 ? 0 : long1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * long1shift short1 = short1on == false ? 0 : short1shift == 0 ? 0 : short1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * short1shift //Colors maopeningcol = maopening == 0 ? na : color.blue maclosingcol = maclosing == 0 ? na : color.fuchsia long1col = long1 == 0 ? na : color.green short1col = short1 == 0 ? na : color.red //Lines plot(maopening, offset = OFFS, color = maopeningcol) plot(maclosing, offset = OFFS, color = maclosingcol) long1line = long1 == 0 ? close : long1 short1line = short1 == 0 ? close : short1 plot(long1line, offset = OFFS, color = long1col) plot(short1line, offset = OFFS, color = short1col) //Lots lotlong1 = p * long1lot lotshort1 = p * short1lot //Entry if maopening > 0 and maclosing > 0 and truetime //Long sum := 0 strategy.entry("L", strategy.long, lotlong1, limit = on_close ? na : long1, when = long1 > 0 and pos <= sum and (on_close ? close <= long1[trade_offset] : true)) sum := lotlong1 //Short sum := 0 pos := -1 * pos strategy.entry("S", strategy.short, lotshort1, limit = on_close ? na : short1, when = short1 > 0 and pos <= sum and (on_close ? close >= short1[trade_offset] : true)) sum := lotshort1 strategy.exit("Exit", na, limit = maclosing) if time > finalTime strategy.close_all()