动态回归通道策略是一种利用线性回归分析价格趋势,并结合动态止损来实现趋势跟踪的量化交易策略。该策略运用线性回归绘制价格通道,判断价格突破通道的信号,发出买入和卖出指令。同时,策略会跟踪价格实时更新止损位置,锁定利润。
该策略首先计算价格的线性回归曲线,判断价格是否突破上行或下行回归通道。当价格超过通道上轨时,产生买入信号;当价格跌破通道下轨时,产生卖出信号。
在入市后,策略会实时跟踪价格突破止损均线的情况。如果是做多订单,价格跌破止损均线,会发出止损卖出指令;如果是做空订单,价格超过止损均线,会发出止损买入指令。这样可以锁定利润,控制风险。
需要注意的是,如果价格重新突破通道实施反向操作,策略会立即平仓原有头寸,改为反向交易。
该策略结合趋势和反转交易思路,能够顺应价格总体走势,同时抓住短期调整机会。实时更新的止损策略也可以有效控制风险,是一种较为均衡的交易方法。
相比简单的移动均线策略,动态回归通道策略对价格变化更为敏感,可以减少误交易。此外,该策略仅在价格突破通道上下轨时出手,有利于避免无序的激进交易。
该策略主要面临回归曲线拟合不精确带来的风险。如果回归通道范围设定不当,过于宽泛,会增加无效交易的概率。过于窄小的通道则会错过交易机会。
此外,止损位置的设定也很关键。止损过于靠近,容易被短期价格波动触发;而过于宽松的止损无法起到风险控制的效果。需要根据不同品种来调整参数。
可以考虑根据不同周期或品种自动优化参数,使回归通道和止损线更贴合价格趋势。例如可以结合机器学习算法来训练最优参数。
另一方面,可以尝试不同类型的回归方法,如多项式回归、局部加权回归等,使拟合效果更好。或者结合多个回归指标构建交易规则,提高策略稳定性。
动态回归通道策略综合运用了趋势和反转分析方法,在顺应价格总体走势的同时,抓住短期调整机会进行交易。关键的回归通道和止损位置设定对策略效果有重要影响。通过参数优化和模型迭代,可以进一步完善该交易策略。
/*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")