Esta estrategia es una versión de varios marcos de tiempo de mi anterior estrategia simple de stop loss de seguimiento. La estrategia anterior solo utilizaba la pérdida básica de stop loss de seguimiento para ingresar posiciones. Funcionó bastante bien, así que traté de mejorarla. Pensé qué pasaría si uso el mismo ATR de seguimiento de stop loss en diferentes marcos de tiempo y los combino en una señal.
En esta estrategia, solo puede usar paradas ATR y elegir otros 3 marcos de tiempo más altos además de su marco de tiempo actual. La pérdida de parada posterior de todos estos marcos de tiempo se trazará en el gráfico. Ingrese una posición larga si todos los 4 marcos de tiempo están de acuerdo con la señal larga. Cierre posiciones largas cuando al menos 2 marcos de tiempo no están de acuerdo con la señal larga. La lógica para las posiciones cortas es la misma.
El núcleo de esta estrategia radica en el seguimiento de la tendencia y el seguimiento de la tendencia. El seguimiento de la tendencia se utiliza para establecer el nivel de stop loss basado en el valor de ATR, que puede evitar efectivamente que se produzca un stop loss.
Específicamente, la estrategia primero calcula el valor de ATR en diferentes marcos de tiempo y establece la distancia de stop loss. Luego genera señales largas / cortas cuando el precio rompe el nivel de stop loss. Si las señales de múltiples marcos de tiempo coinciden, se tomará una posición. Después de eso, siga rastreando el nivel de stop loss por dirección de tendencia. Si las señales de un cierto porcentaje de marcos de tiempo se invierten, cierre la posición.
Al combinar el juicio de tendencia a través de diferentes períodos, las rupturas falsas se pueden filtrar de manera efectiva.
Soluciones:
La estrategia se puede optimizar en los siguientes aspectos:
Esta estrategia combina el seguimiento de tendencias y el control de riesgos a través de paradas de seguimiento de ATR de múltiples plazos. En comparación con la parada única, identifica la dirección de la tendencia con más claridad; en comparación con el marco de tiempo único, filtra mucho ruido. La configuración adecuada en los parámetros de parada y los plazos es clave para lograr los mejores resultados. Es adecuado para los inversores que pueden tolerar ciertas reducciones y proporciona rendimientos constantes. También hay más espacio de mejora y expansibilidad.
/*backtest start: 2023-01-01 00:00:00 end: 2024-01-07 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 strategy(title="MTF Trailing SL Strategy [QuantNomad]", shorttitle = "MTF TrailingSL [QN]", overlay = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100) //////////// // Inputs // atr_length = input(14, title = "ATR Length") atr_mult = input(2, title = "ATR Mult", type = input.float) tf2 = input('120', title = "TF2", type = input.string) tf3 = input('180', title = "TF3", type = input.string) tf4 = input('240', title = "TF4", type = input.string) // BACKTESTING RANGE // From Date Inputs fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31) fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12) fromYear = input(defval = 2016, title = "From Year", minval = 1970) // To Date Inputs toDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31) toMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12) toYear = input(defval = 2100, title = "To Year", minval = 1970) // Calculate start/end date and time condition startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00) finishDate = timestamp(toYear, toMonth, toDay, 00, 00) time_cond = time >= startDate and time <= finishDate ////////////////// // CALCULATIONS // tsl() => // SL values sl_val = atr_mult * atr(atr_length) // Init Variables pos = 0 trailing_sl = 0.0 // Signals long_signal = nz(pos[1]) != 1 and high > nz(trailing_sl[1]) short_signal = nz(pos[1]) != -1 and low < nz(trailing_sl[1]) // Calculate SL trailing_sl := short_signal ? high + sl_val : long_signal ? low - sl_val : nz(pos[1]) == 1 ? max(low - sl_val, nz(trailing_sl[1])) : nz(pos[1]) == -1 ? min(high + sl_val, nz(trailing_sl[1])) : nz(trailing_sl[1]) // Position var pos := long_signal ? 1 : short_signal ? -1 : nz(pos[1]) trailing_sl trailing_sl1 = tsl() trailing_sl2 = security(syminfo.tickerid, tf2, tsl()) trailing_sl3 = security(syminfo.tickerid, tf3, tsl()) trailing_sl4 = security(syminfo.tickerid, tf4, tsl()) pos1 = 0 pos1 := low <= trailing_sl1 ? -1 : high >= trailing_sl1 ? 1 : nz(pos1[1]) pos2 = 0 pos2 := low <= trailing_sl2 ? -1 : high >= trailing_sl2 ? 1 : nz(pos2[1]) pos3 = 0 pos3 := low <= trailing_sl3 ? -1 : high >= trailing_sl3 ? 1 : nz(pos3[1]) pos4 = 0 pos4 := low <= trailing_sl4 ? -1 : high >= trailing_sl4 ? 1 : nz(pos4[1]) total_pos = pos1 + pos2 + pos3 + pos4 ////////////// // PLOTINGS // plot(trailing_sl1, linewidth = 2 , color = pos1 == 1 ? color.green : color.red, title = "TSL TF1") plot(trailing_sl2, linewidth = 2 , color = pos2 == 1 ? color.green : color.red, title = "TSL TF2", transp = 25) plot(trailing_sl3, linewidth = 2 , color = pos3 == 1 ? color.green : color.red, title = "TSL TF3", transp = 50) plot(trailing_sl4, linewidth = 2 , color = pos4 == 1 ? color.green : color.red, title = "TSL TF4", transp = 75) ////////////// // STRATEGY // //strategy.entry("long", true, stop = trailing_sl1) //strategy.entry("short", false, stop = trailing_sl1) strategy.entry("long", true, when = total_pos == 4) strategy.entry("short", false, when = total_pos == -4) strategy.close("long", when = total_pos <= 0) strategy.close("short", when = total_pos >= 0)