La estrategia de canal de regresión dinámica utiliza el análisis de regresión lineal de las tendencias de precios combinado con el stop loss dinámico para implementar el seguimiento de tendencias en el comercio cuantitativo. La estrategia emplea regresión lineal para trazar un canal de precios y generar señales de compra y venta cuando los precios salen del canal. Al mismo tiempo, la estrategia rastrea los precios en tiempo real para actualizar los niveles de stop loss para bloquear las ganancias.
La estrategia primero calcula una curva de regresión lineal de los precios para determinar si los precios rompen por encima o por debajo del canal de regresión. Cuando los precios aumentan por encima del carril superior del canal, se genera una señal de compra. Cuando los precios caen por debajo del carril inferior, se activa una señal de venta.
Después de entrar en una posición, la estrategia sigue el seguimiento si los precios rompen la línea media móvil de stop loss. Para órdenes largas, si los precios caen por debajo de la línea de stop loss, se emitirá una orden de venta de stop loss. Para órdenes cortas, si los precios se elevan por encima de la línea de stop loss, se activará una orden de compra de stop loss. Esto bloquea las ganancias y controla los riesgos.
Es importante tener en cuenta que si los precios rompen el canal de nuevo en dirección inversa, la estrategia se aplanará inmediatamente la posición original y cambiar a la negociación en la dirección opuesta.
Esta estrategia combina los conceptos de seguimiento de tendencia y reversión media, montando con la tendencia general del precio mientras captura reversiones a corto plazo.
En comparación con las estrategias de promedio móvil simples, la estrategia de canal de regresión dinámica es más sensible a los cambios de precios y puede reducir los mistrades.
El principal riesgo radica en el ajuste inexacto de la curva de regresión: si el rango del canal se establece incorrectamente, ya sea demasiado ancho o demasiado estrecho, aumentará las operaciones no válidas o perderá oportunidades comerciales.
Además, el posicionamiento adecuado de stop loss es crítico. Un stop loss demasiado cercano a los precios de mercado es propenso a la liquidación prematura por volatilidad a corto plazo, mientras que un stop loss demasiado lejos no puede cumplir con su propósito de control de riesgos.
Considere la optimización automática de parámetros para diferentes períodos o productos para hacer que el canal de regresión y la línea de stop loss se adapten mejor a las tendencias de precios.
Alternativamente, se pueden probar diferentes tipos de regresión, como la regresión polinomial y la regresión ponderada localmente, para mejorar el ajuste.
La estrategia de canal de regresión dinámica utiliza hábilmente tanto las técnicas de seguimiento de tendencias como las técnicas de reversión media, montando la tendencia general del precio mientras captura reversiones a corto plazo.
/*backtest start: 2024-01-01 00:00:00 end: 2024-01-31 23:59:59 period: 2h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy("Estratégia de Regressão Linear", shorttitle="Regressão Linear Estratégia", overlay=true, initial_capital = 100, default_qty_value = 10, default_qty_type = strategy.percent_of_equity) // média móvel exponencial para definição de regressao linear var SlopeEMASize = input.int(defval = 21, title = "Slope EMA" ) // ema_length = 21 slope_ema = ta.ema(close, SlopeEMASize) // média móvel exponencial para definição de nivel de stop var StopEMASize = input.int(defval = 13, title = "Stop EMA" ) stop_ema = ta.ema(close, StopEMASize) // Variáveis para controle de posição var float long_stop_level = na var float long_entry_level = na var bool long_signal = false var bool long_order_open = false var int long_order_id = 0 var float short_stop_level = na var float short_entry_level = na var bool short_signal = false var bool short_order_open = false var int short_order_id = 0 // Regressão linear para uso como sinal de entrada var SlopeLenght = input.int(defval = 21, title = "Slope Lenght" ) entry_signal = ta.linreg(slope_ema, SlopeLenght, 0) //Variaveis com a indicação do pivot da regressao long_entry_signal = ta.crossover(entry_signal, entry_signal[1]) short_entry_signal = ta.crossunder(entry_signal, entry_signal[1]) // Condição de entrada (reversão da regressão) if long_entry_signal long_signal := true short_signal := false long_entry_level := high long_stop_level := low if short_entry_signal short_signal := true long_signal := false short_entry_level := low short_stop_level := high // Indica quando o preço cruzou o nível de stop price_cross_stop_ema_up = ta.crossover(close, stop_ema) price_cross_stop_ema_down = ta.crossunder(close, stop_ema) // Mover o stop quando o preço cruzar a nível stop e operação long ativa if long_signal and long_order_open and price_cross_stop_ema_down if low > long_entry_level long_stop_level := high // Mover o stop quando o preço cruzar a nível stop e operação short ativa if short_signal and short_order_open and price_cross_stop_ema_up if high < short_stop_level short_stop_level := low // Sair da posição se houver nova reversão da regressão if long_order_open or short_order_open if long_entry_signal //and short_order_open strategy.close(str.tostring(short_order_id), comment ="Inversão Sinal("+str.tostring(short_order_id)+")") short_order_open:= false if short_entry_signal //and long_order_open strategy.close(str.tostring(long_order_id), comment = "Inversão Sinal("+str.tostring(long_order_id)+")") long_order_open:=false // Sinais de compra e venda com base no stop if long_signal and close > long_entry_level and not long_order_open if strategy.opentrades != 0 strategy.cancel_all() long_order_id+=1 // strategy.order(str.tostring(long_order_id), strategy.long, comment="Open Long("+str.tostring(long_order_id)+")", limit = long_entry_level) strategy.entry(str.tostring(long_order_id), strategy.long, comment="Open Long("+str.tostring(long_order_id)+")", limit = long_entry_level) long_order_open := true // log.info("Open Long:"+str.tostring(long_order_id)) if short_signal and close < short_entry_level and not short_order_open if strategy.opentrades != 0 strategy.cancel_all() short_order_id+=1 // strategy.order(str.tostring(short_order_id), strategy.short, comment="Open Short("+str.tostring(short_order_id)+")", limit = short_entry_level) strategy.entry(str.tostring(short_order_id), strategy.short, comment="Open Short("+str.tostring(short_order_id)+")", limit = short_entry_level) short_order_open := true // log.info("Open Short:"+str.tostring(short_order_id)) // Sinais de compra e venda com base no stop if long_signal and close < long_stop_level and long_order_open strategy.close(str.tostring(long_order_id), comment = "Stop Atingido("+str.tostring(long_order_id)+")", immediately = true) long_order_open := false if short_signal and close > short_stop_level and short_order_open strategy.close(str.tostring(short_order_id),comment = "Stop Atingido("+str.tostring(short_order_id)+")", immediately = true) short_order_open := false // Plotagem da regressão e do stop plot(stop_ema, title="Stop Signal", color=color.red) plot(entry_signal,"Entry Signal", linewidth = 5, color = color.rgb(155, 0, 140)) plotshape(long_order_open?long_stop_level:na, title = "Long Stop Level", color = color.green, location = location.absolute) plotshape(long_order_open?long_entry_level:na, title="Long Entry Value",location=location.absolute, color = color.green, style = shape.circle) plotshape(series=long_entry_signal, title="Long Signal", location=location.abovebar, color=color.green, style=shape.triangleup, size=size.small, text = "Long Signal") plotshape(short_order_open?short_stop_level:na, title = "Short Stop Level", color = color.red, location = location.absolute) plotshape(short_order_open?short_entry_level:na, title="Short Entry Value",location=location.absolute, color = color.red, style = shape.circle) plotshape(series=short_entry_signal, title="Short Signal", location=location.belowbar, color=color.red, style=shape.triangledown, size=size.small, text="Short Signal")