Esta estrategia combina indicadores duales para identificar la dirección de la tendencia y realizar operaciones. En primer lugar, utiliza el cruce de dos promedios móviles (rápidos y medianos) para juzgar la tendencia a corto plazo; en segundo lugar, utiliza el rango de canal y el promedio móvil a largo plazo para determinar la dirección de la tendencia principal. Las señales comerciales se generan solo cuando los dos juicios son consistentes. La estrategia híbrida que utiliza múltiples indicadores puede filtrar eficazmente las señales falsas y mejorar la estabilidad.
La estrategia utiliza tres conjuntos de indicadores para el juicio. Primero, la cruz de oro y la cruz de la muerte de la EMA rápida (26 períodos) y la EMA media (50 períodos) para determinar la tendencia a corto plazo; en segundo lugar, calcular el rango del canal para juzgar la tendencia a mediano plazo; finalmente, calcular la SMA a largo plazo (200 períodos) y comparar con el precio para determinar la dirección de la tendencia principal.
Específicamente, la lógica es:
Cruce de las medias móviles rápidas y medianas (cruz dorada para alcista, cruz de muerte para bajista) para determinar la tendencia a corto plazo.
Si el precio rompe el rango del canal para determinar la tendencia a mediano plazo. El rango del canal se basa en el MA a largo plazo más/menos ATR veces un coeficiente. Romper el límite superior indica alza, romper el límite inferior indica bajista.
Comparación del precio con el MA a largo plazo para determinar la tendencia principal.
Por último, las señales de negociación se generan solo cuando los tres juicios son consistentes.
Esta estrategia híbrida de dos indicadores tiene varias ventajas:
Filtrar eficazmente las señales falsas y mejorar la estabilidad.
Alta flexibilidad para ajustar los parámetros para diferentes mercados. Los parámetros de MA y el rango de canal se pueden ajustar para diversos entornos.
Combina el comercio de tendencias y el comercio de rango. Los indicadores a mediano y corto plazo atrapan tendencias, el indicador a largo plazo determina rango. En general, posee los méritos de las estrategias de tendencia y inversión media.
Eficiencia de uso de capital alta. Poner órdenes sólo cuando varios indicadores coinciden, el capital puede ser utilizado de manera efectiva para evitar operaciones innecesarias.
También hay algunos riesgos:
Parámetros que establecen el riesgo. Los períodos de MA y el rango de canales deben configurarse correctamente, las configuraciones incorrectas pueden no detectar tendencias o causar señales falsas excesivas.
Aumento del costo de oportunidad de los indicadores duales: en comparación con las estrategias de indicadores únicos, algunas oportunidades comerciales pueden perderse, sin poder entrar y salir en los puntos óptimos.
El mecanismo de stop loss requiere prudencia. El stop loss de ruptura aquí puede causar pérdidas innecesarias. El porcentaje de stop loss requiere una configuración cuidadosa.
Esta estrategia funciona mejor en mercados con tendencia aparente.
La estrategia puede mejorarse en los siguientes aspectos:
Prueba diferentes combinaciones de parámetros para encontrar el óptimo. Más pruebas con datos históricos para localizar configuraciones óptimas.
Agregue un mecanismo de stop loss adaptativo, afinando dinámicamente el nivel de stop loss basado en el indicador de volatilidad.
Ayuda con los indicadores de volumen en puntos críticos.
Optimice la lógica de entrada. Considere las entradas escalonadas con un promedio de costos para reducir el riesgo de entrada única.
Combinar modelos de aprendizaje automático, introducir redes neuronales para juzgar la robustez y aptitud del modelo.
Esta estrategia aprovecha indicadores de marco de tiempo triple y doble validación para suprimir señales falsas y mejorar la estabilidad. Mientras tanto, posee los méritos de la tendencia y el comercio de rango, con una alta eficiencia en el uso del capital. Se puede mejorar mediante optimización de parámetros, ajuste de pérdidas, integración con indicadores de volumen, etc. Una estrategia cuantitativa híbrida recomendada.
/*backtest start: 2023-11-19 00:00:00 end: 2023-12-19 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 // Indicator to combines: // Trend Channel[Gu5] (SMA 200) + // EMA's cross (26, 50 ) + // Golden Cross (50, 200) // Author: @gu5tavo71 08/2019 // v2.3.6, 2022.02.18 // Trend Channel [Gu5] // Author: @gu5tavo71 08/2019 // // This source code is subject to these terms: // Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) // https://www.safecreative.org/work/2202190517452-mix1-ema-cross-trend-channel-gu5- // You are free to: // Share, copy and redistribute this script // Adapt, transform and build on this script // Under the following terms: // Non-commercial: You cannot sell my indicator. You can't sell my work. // Attribution: If you post part of my code, you must give me proper credit // // I am using part of this code published by @PineCoders and Public Library // Disclaimer: I am not a financial advisor. // For purpose educate only. Use at your own risk. strategy(title = 'Mix1 : Ema Cross + Trend Channel [Gu5] - Backtest', shorttitle = 'Mix01', overlay = true, initial_capital = 100, default_qty_value = 100, default_qty_type = strategy.percent_of_equity, commission_value = 0.075, commission_type = strategy.commission.percent, format = format.price, precision = 2, process_orders_on_close = true) // --------- Inputs "==============================" | i_maSrc = input.source (close, 'MA Source' , group = 'EMAs') i_maFast1 = input.int (26, 'EMA Fast' , group = 'EMAs') i_maFast2 = input.int (50, 'EMA Medium' , group = 'EMAs') i_maLen = input.int (200, 'MA Trend' , group = 'Trend Channel') o_maLen1 = 'EMA' o_maLen2 = 'SMA' i_maLenSel = input.string (o_maLen2, 'MA Type' , group = 'Trend Channel', options = [o_maLen1, o_maLen2], tooltip = "EMA or SMA") i_htf = input.timeframe ('', 'Select Higher Timeframe' , tooltip = 'Only for MA Trend' , group = 'Trend Channel') i_rangeLen = input.float (0.618, 'Channel Range Length' , tooltip = 'ATR of the MA Trend', group = 'Trend Channel') i_slOn = input.bool (false, '■ Stop Loss On/Off' , group = 'Stop Loss') i_sl = input.float (2.618, 'SL %' , step = 0.1, group = 'Stop Loss') i_periodSw = input.bool (true, '■ Period On/Off' , group = 'Period') o_start = timestamp ( '2020-01-01 00:00 GMT-3' ) o_end = timestamp ( '2099-12-31 00:00 GMT-3' ) i_periodStar = input (o_start, 'Start Time' , group = 'Period') i_periodEnd = input (o_end, 'End Time' , group = 'Period') o_posSel1 = 'Only Long' o_posSel2 = 'Only Short' o_posSel3 = 'Both' i_posSel = input.string (o_posSel3, 'Position Type' , group = 'Strategy', options = [o_posSel1, o_posSel2, o_posSel3], tooltip = "Only Long, Only short or Both") o_typeS1 = 'Strategy 1' o_typeS2 = 'Strategy 2' i_typeS = input.string (o_typeS2, 'Strategy Type' , group = 'Strategy', options = [o_typeS1, o_typeS2], tooltip = "Strategy 1:\nLong, when the price (close) crosses the ema.\nStrategy 2:\nLong, only when ema goes up") i_barColOn = input.bool (true, '■ Bar Color On/Off' , group = 'Display') i_alertOn = input.bool (false, '■ Alert On/Off' , group = 'Display') i_channelOn = input.bool (false, '■ Channel Range On/Off' , tooltip = 'If the price (close) is over than the channel, the trend is bullish. If the price is under, bearish. And if the price is in the channel, it is in range', group = 'Display') i_goldenOn = input.bool (false, '■ Golden Cross On/Off' ) o_alert = '{{strategy.order.comment}}' i_alert = input.string (o_alert, 'Setting alert' , tooltip = 'For Alerts, just copy {{strategy.order.comment}} and paste in alert window.', group = 'Display') // --------- Calculations maFast1 = ta.ema(i_maSrc, i_maFast1) maFast2 = ta.ema(i_maSrc, i_maFast2) maDir = maFast1 > maFast2 ? 1 : -1 maTrend = request.security(syminfo.tickerid, i_htf, i_maLenSel == "SMA" ? ta.sma(close, i_maLen)[1] : ta.ema(close, i_maLen)[1], lookahead = barmerge.lookahead_on) //No repaint maTrendDir = i_maSrc >= maTrend ? 1 : -1 rangeAtr = ta.atr(i_maLen) * i_rangeLen rangeTop = maTrend + rangeAtr rangeBot = maTrend - rangeAtr rangeCh = (open <= rangeTop or close <= rangeTop) and (open >= rangeBot or close >= rangeBot) trendDir = i_typeS == 'Strategy 1' ? rangeCh ? 0 : maTrendDir == 1 and maDir == 1 and maTrend > maFast2 ? 0 : maTrendDir == -1 and maDir == -1 and maTrend < maFast2 ? 0 : maTrendDir == 1 and maDir == 1 ? 1 : maTrendDir == -1 and maDir == -1 ? -1 : 0 : rangeCh ? 0 : maTrendDir == 1 and maDir == 1 ? 1 : maTrendDir == -1 and maDir == -1 ? -1 : 0 GCross = i_goldenOn ? ta.crossover (maFast2, maTrend) : na DCross = i_goldenOn ? ta.crossunder(maFast2, maTrend) : na period = true // Set initial values condition = 0.0 entryLong = trendDir == 1 and i_posSel != 'Only Short' and (i_periodSw ? period : true) entryShort = trendDir == -1 and i_posSel != 'Only Long' and (i_periodSw ? period : true) exitLong = (trendDir != 1 or maDir == -1) and condition[1] == 1 and i_posSel != 'Only Short' and (i_periodSw ? period : true) exitShort = (trendDir != -1 or maDir == 1) and condition[1] == -1 and i_posSel != 'Only Long' and (i_periodSw ? period : true) closeCond = exitLong or exitShort // Stop Loss (sl) slEntry = close * i_sl / 100 slTop = close + slEntry slBot = close - slEntry slTopBuff = ta.valuewhen(condition[1] != 1 and entryLong, slBot, 0) slBotBuff = ta.valuewhen(condition[1] != -1 and entryShort, slTop, 0) slLine = condition[1] == -1 and entryLong ? slTopBuff : condition[1] == 1 and entryShort ? slBotBuff : condition[1] == 1 or entryLong ? slTopBuff : condition[1] == -1 or entryShort ? slBotBuff : na slTopCross = condition[1] == 1 and ta.crossunder(close, slLine) or high > slLine and low < slLine slBotCross = condition[1] == -1 and ta.crossover (close, slLine) or high > slLine and low < slLine slExit = i_slOn ? slTopCross or slBotCross : na // Conditions condition := condition[1] != 1 and entryLong ? 1 : condition[1] != -1 and entryShort ? -1 : condition[1] != 0 and slExit ? 0 : condition[1] != 0 and exitLong ? 0 : condition[1] != 0 and exitShort ? 0 : nz(condition[1]) long = condition[1] != 1 and condition == 1 short = condition[1] != -1 and condition == -1 xl = condition[1] == 1 and exitLong and not slExit xs = condition[1] == -1 and exitShort and not slExit sl = condition[1] != 0 and slExit // --------- Colors c_green = #006400 //Green c_greenLight = #388e3c //Green Light c_red = #8B0000 //Red c_redLight = #b71c1c //Red Light c_emas = xl ? color.new(color.orange, 99) : xs ? color.new(color.orange, 99) : trendDir == 1 and maDir == 1 ? color.new(c_green, 99) : trendDir == -1 and maDir == -1 ? color.new(c_red, 99) : color.new(color.orange, 99) c_maFill = xl ? color.new(color.orange, 70) : xs ? color.new(color.orange, 70) : trendDir == 1 and maDir == 1 ? color.new(c_green, 70) : trendDir == -1 and maDir == -1 ? color.new(c_red, 70) : color.new(color.orange, 70) c_maTrend = trendDir == 0 ? color.new(color.orange, 0) : trendDir == 1 and maTrend[1] < maTrend ? color.new(c_green, 0) : trendDir == 1 and maTrend[1] >= maTrend ? color.new(c_greenLight, 0) : trendDir == -1 and maTrend[1] < maTrend ? color.new(c_redLight, 0) : trendDir == -1 and maTrend[1] >= maTrend ? color.new(c_red, 0) : na c_ch = trendDir == 0 ? color.new(color.orange, 50) : trendDir == 1 ? color.new(c_green, 50) : trendDir == -1 ? color.new(c_red, 50) : na c_slLineUp = ta.rising (slLine, 1) c_slLineDn = ta.falling(slLine, 1) c_slLine = c_slLineUp ? na : c_slLineDn ? na : color.red c_barCol = trendDir == 0 ? color.new(color.orange, 0) : trendDir == 1 and open <= close ? color.new(c_green, 0) : trendDir == 1 and open > close ? color.new(c_greenLight, 0) : trendDir == -1 and open >= close ? color.new(c_red, 0) : trendDir == -1 and open < close ? color.new(c_redLight, 0) : color.new(color.orange, 0) // --------- Plots p_maFast1 = plot( maFast1, title = 'EMA Fast 1', color = c_emas, linewidth = 1) p_maFast2 = plot( maFast2, title = 'EMA Fast 2', color = c_emas, linewidth = 2) fill( p_maFast1, p_maFast2, title = 'EMAs Fill', color = c_maFill) plot( maTrend, title = 'SMA Trend', color = c_maTrend, linewidth = 3) p_chTop = plot( i_channelOn ? rangeTop : na, title = 'Top Channel', color = c_maTrend, linewidth = 1) p_chBot = plot( i_channelOn ? rangeBot : na, title = 'Bottom Channel', color = c_maTrend, linewidth = 1) fill( p_chTop, p_chBot, title = 'Channel', color = c_ch) plot( i_slOn and condition != 0 ? slLine : na, title = 'Stop Loss Line', color = c_slLine, linewidth = 1, style = plot.style_linebr) // --------- Alerts barcolor(i_barColOn ? c_barCol : na) plotshape( i_alertOn and long ? high : na, title = 'Long Label', text = 'Long', textcolor = color.white, color = color.new(c_green, 0), style = shape.labelup, size = size.normal, location = location.belowbar) plotshape( i_alertOn and short ? low : na, title = 'Short Label', text = 'Short', textcolor = color.white, color = color.new(c_red, 0), style = shape.labeldown, size = size.normal, location = location.abovebar) plotshape( i_alertOn and (xl or xs) ? close : na, title = 'Close Label', text = 'Close', textcolor = color.orange, color = color.new(color.orange, 0), style = shape.xcross, size = size.small, location = location.absolute) plotshape( i_alertOn and sl ? slLine : na, title = 'Stop Loss', text = 'Stop\nLoss', textcolor = color.orange, color = color.new(color.orange, 0), style = shape.xcross, size = size.small, location = location.absolute) plotshape( i_alertOn and i_goldenOn and GCross ? maTrend : na, title = 'Golden Cross Label', text = 'Golden\nCross', textcolor = color.white, color = color.new(color.orange, 0), style = shape.labelup, size = size.normal, location = location.absolute) plotshape( i_alertOn and i_goldenOn and DCross ? maTrend : na, title = 'Death Cross Label', text = 'Death\nCross', textcolor = color.white, color = color.new(color.orange, 0), style = shape.labeldown, size = size.normal, location = location.absolute) bgcolor( i_periodSw and not period ? color.new(color.gray, 90) : na, title = 'Session') // --------- Backtest if long and strategy.position_size == 0 and barstate.isconfirmed strategy.entry('Long', strategy.long, comment = 'long') if short and strategy.position_size == 0 and barstate.isconfirmed strategy.entry('Short', strategy.short, comment = 'short') strategy.exit( id = 'XL', from_entry = 'Long', stop = i_slOn ? slLine : na) strategy.exit( id = 'XS', from_entry = 'Short', stop = i_slOn ? slLine : na) strategy.close( 'Long', comment = 'Close', when = xl) strategy.close( 'Short', comment = 'Close', when = xs)