Esta estrategia combina marcos de tiempo y indicadores de impulso duales para lograr una toma de ganancias y un stop loss adaptativos. El marco de tiempo principal monitorea la dirección de la tendencia, mientras que el marco de tiempo secundario se utiliza para confirmar las señales. Las señales de negociación se generan cuando las direcciones de ambos se alinean. Después de ingresar al mercado, los niveles de toma de ganancias y stop loss se actualizan progresivamente.
El marco de tiempo principal utiliza el indicador de regresión lineal Squeeze Momentum (SQM) para determinar la tendencia. El marco de tiempo secundario utiliza una combinación EMA en el indicador SQM para filtrar señales falsas.
Cuando el gráfico principal SQM rompe hacia arriba y el gráfico secundario SQM también sube, se toma una posición larga.
Después de entrar en el mercado, los niveles iniciales de take profit y stop loss se establecen en función de los parámetros de entrada. Cuando el precio alcanza el nivel de take profit, se actualizan los niveles de take profit y stop loss.
Dos marcos de tiempo filtran las señales falsas y aseguran la precisión.
El indicador SQM determina la dirección de la tendencia, evitando el ruido del mercado.
El mecanismo adaptativo de toma de ganancias y parada de pérdidas bloquea las ganancias en la medida máxima y controla eficazmente el riesgo.
Los parámetros incorrectos de SQM pueden pasar por alto los puntos de inflexión de la tendencia, lo que conduce a pérdidas.
Un marco temporal secundario inadecuado puede no filtrar el ruido de manera efectiva, causando operaciones erróneas.
Si la amplitud de stop loss se establece demasiado amplia, la pérdida por operación puede ser sustancial.
Los parámetros del MQS deben ajustarse a los diferentes mercados para garantizar la sensibilidad.
Para determinar el mejor efecto de filtración del ruido, deben probarse diferentes períodos temporales secundarios.
En lugar de un valor fijo, la amplitud de stop loss puede tener un rango establecido dinámicamente en función de la volatilidad del mercado.
En general, esta es una estrategia muy práctica. La combinación de marcos de tiempo duales con un indicador de impulso para determinar las tendencias, junto con el método adaptativo de tomar ganancias y stop loss puede generar ganancias estables. Al optimizar los parámetros de SQM, el período de marco de tiempo secundario y la amplitud de stop loss, los resultados de la estrategia se pueden mejorar aún más para una aplicación y mejora productiva en vivo.
/*backtest start: 2023-11-15 00:00:00 end: 2023-11-22 00:00:00 period: 15m basePeriod: 5m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 strategy("SQZ Multiframe Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10) fast_ema_len = input(11, minval=5, title="Fast EMA") slow_ema_len = input(34, minval=20, title="Slow EMA") sqm_lengthKC = input(20, title="SQM KC Length") kauf_period = input(20, title="Kauf Period") kauf_mult = input(2,title="Kauf Mult factor") min_profit_sl = input(5.0, minval=1, maxval=100, title="Min profit to start moving SL [%]") longest_sl = input(10, minval=1, maxval=100, title="Maximum possible of SL [%]") sl_step = input(0.5, minval=0.0, maxval=1.0, title="Take profit factor") // ADMF CMF_length = input(11, minval=1, title="CMF length") // EMA27 = SMMA/RMA14 ~ lunar month show_plots = input(true, title="Show plots") lower_resolution = timeframe.period=='1'?'5':timeframe.period=='5'?'15':timeframe.period=='15'?'30':timeframe.period=='30'?'60':timeframe.period=='60'?'240':timeframe.period=='240'?'D':timeframe.period=='D'?'W':'M' higher_resolution = timeframe.period=='5'?'1':timeframe.period=='15'?'5':timeframe.period=='30'?'15':timeframe.period=='60'?'30':timeframe.period=='240'?'60':timeframe.period=='D'?'240':timeframe.period=='W'?'D':'W' // Calculate Squeeze Momentum sqm_val = linreg(close - avg(avg(highest(high, sqm_lengthKC), lowest(low, sqm_lengthKC)),sma(close,sqm_lengthKC)), sqm_lengthKC,0) sqm_val_high = security(syminfo.tickerid, higher_resolution, linreg(close - avg(avg(highest(high, sqm_lengthKC), lowest(low, sqm_lengthKC)),sma(close,sqm_lengthKC)), sqm_lengthKC,0), lookahead=barmerge.lookahead_on) sqm_val_low = security(syminfo.tickerid, lower_resolution, linreg(close - avg(avg(highest(high, sqm_lengthKC), lowest(low, sqm_lengthKC)),sma(close,sqm_lengthKC)), sqm_lengthKC,0), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on) // Emas high_close = security(syminfo.tickerid, higher_resolution, close, lookahead=barmerge.lookahead_on) high_fast_ema = security(syminfo.tickerid, higher_resolution, ema(close, fast_ema_len), lookahead=barmerge.lookahead_on) high_slow_ema = security(syminfo.tickerid, higher_resolution, ema(close, slow_ema_len), lookahead=barmerge.lookahead_on) //low_fast_ema = security(syminfo.tickerid, lower_resolution, ema(close, fast_ema_len), lookahead=barmerge.lookahead_on) //low_slow_ema = security(syminfo.tickerid, lower_resolution, ema(close, slow_ema_len), lookahead=barmerge.lookahead_on) // CMF ad = close==high and close==low or high==low ? 0 : ((2*close-low-high)/(high-low))*volume money_flow = sum(ad, CMF_length) / sum(volume, CMF_length) // Entry conditions low_condition_long = (sqm_val_low > sqm_val_low[1]) low_condition_short = (sqm_val_low < sqm_val_low[1]) money_flow_min = (money_flow[4] > money_flow[3]) and (money_flow[3] > money_flow[2]) and (money_flow[2] < money_flow[1]) and (money_flow[1] < money_flow) money_flow_max = (money_flow[4] < money_flow[3]) and (money_flow[3] < money_flow[2]) and (money_flow[2] > money_flow[1]) and (money_flow[1] > money_flow) condition_long = ((sqm_val > sqm_val[1])) and (money_flow_min or money_flow_min[1] or money_flow_min[2] or money_flow_min[3]) and lowest(sqm_val, 5) < 0 condition_short = ((sqm_val < sqm_val[1])) and (money_flow_max or money_flow_max[1] or money_flow_max[2] or money_flow_max[3]) and highest(sqm_val, 5) > 0 high_condition_long = true//high_close > high_fast_ema and high_close > high_slow_ema //(high_fast_ema > high_slow_ema) //and (sqm_val_low > sqm_val_low[1]) high_condition_short = true//high_close < high_fast_ema and high_close < high_slow_ema//(high_fast_ema < high_slow_ema) //and (sqm_val_low < sqm_val_low[1]) enter_long = low_condition_long and condition_long and high_condition_long enter_short = low_condition_short and condition_short and high_condition_short // Stop conditions var current_target_price = 0.0 var current_sl_price = 0.0 // Price limit to take profit var current_target_per = 0.0 var current_profit_per = 0.0 set_targets(isLong, min_profit, current_target_per, current_profit_per) => target = 0.0 sl = 0.0 if isLong target := close * (1.0 + current_target_per) sl := close * (1.0 - (longest_sl/100.0)) // Longest SL else target := close * (1.0 - current_target_per) sl := close * (1.0 + (longest_sl/100.0)) // Longest SL [target, sl] target_reached(isLong, min_profit, current_target_per, current_profit_per) => target = 0.0 sl = 0.0 profit_per = 0.0 target_per = 0.0 if current_profit_per == 0 profit_per := (min_profit*sl_step) / 100.0 else profit_per := current_profit_per + ((min_profit*sl_step) / 100.0) target_per := current_target_per + (min_profit / 100.0) if isLong target := strategy.position_avg_price * (1.0 + target_per) sl := strategy.position_avg_price * (1.0 + profit_per) else target := strategy.position_avg_price * (1.0 - target_per) sl := strategy.position_avg_price * (1.0 - profit_per) [target, sl, profit_per, target_per] hl_diff = sma(high - low, kauf_period) stop_condition_long = 0.0 new_stop_condition_long = low - (hl_diff * kauf_mult) if (strategy.position_size > 0) if (close > current_target_price) [target, sl, profit_per, target_per] = target_reached(true, min_profit_sl, current_target_per, current_profit_per) current_target_price := target current_sl_price := sl current_profit_per := profit_per current_target_per := target_per stop_condition_long := max(stop_condition_long[1], current_sl_price) else stop_condition_long := new_stop_condition_long stop_condition_short = 99999999.9 new_stop_condition_short = high + (hl_diff * kauf_mult) if (strategy.position_size < 0) if (close < current_target_price) [target, sl, profit_per, target_per] = target_reached(false, min_profit_sl, current_target_per, current_profit_per) current_target_price := target current_sl_price := sl current_profit_per := profit_per current_target_per := target_per stop_condition_short := min(stop_condition_short[1], current_sl_price) else stop_condition_short := new_stop_condition_short // Submit entry orders if (enter_long and (strategy.position_size <= 0)) if (strategy.position_size < 0) strategy.close(id="SHORT") current_target_per := (min_profit_sl / 100.0) current_profit_per := 0.0 [target, sl] = set_targets(true, min_profit_sl, current_target_per, current_profit_per) current_target_price := target current_sl_price := sl strategy.entry(id="LONG", long=true) // if show_plots // label.new(bar_index, high, text=tostring("LONG\nSL: ") + tostring(stop_condition_long), style=label.style_labeldown, color=color.green) if (enter_short and (strategy.position_size >= 0)) if (strategy.position_size > 0) strategy.close(id="LONG") current_target_per := (min_profit_sl / 100.0) current_profit_per := 0.0 [target, sl] = set_targets(false, min_profit_sl, current_target_per, current_profit_per) current_target_price := target current_sl_price := sl strategy.entry(id="SHORT", long=false) // if show_plots // label.new(bar_index, high, text=tostring("SHORT\nSL: ") + tostring(stop_condition_short), style=label.style_labeldown, color=color.red) if (strategy.position_size > 0) strategy.exit(id="EXIT LONG", stop=stop_condition_long) if (strategy.position_size < 0) strategy.exit(id="EXIT SHORT", stop=stop_condition_short) // Plot anchor trend plotshape(low_condition_long, style=shape.triangleup, location=location.abovebar, color=color.green) plotshape(low_condition_short, style=shape.triangledown, location=location.abovebar, color=color.red) plotshape(condition_long, style=shape.triangleup, location=location.belowbar, color=color.green) plotshape(condition_short, style=shape.triangledown, location=location.belowbar, color=color.red) //plotshape((close < profit_target_short) ? profit_target_short : na, style=shape.triangledown, // location=location.belowbar, color=color.yellow) plotshape(enter_long, style=shape.triangleup, location=location.bottom, color=color.green) plotshape(enter_short, style=shape.triangledown, location=location.bottom, color=color.red) // Plot emas plot(ema(close, 20), color=color.blue, title="20 EMA") plot(ema(close, 50), color=color.orange, title="50 EMA") plot(sma(close, 200), color=color.red, title="MA 200") // Plot stop loss values for confirmation plot(series=(strategy.position_size > 0) and show_plots ? stop_condition_long : na, color=color.green, style=plot.style_linebr, title="Long Stop") plot(series=(strategy.position_size < 0) and show_plots ? stop_condition_short : na, color=color.green, style=plot.style_linebr, title="Short Stop") plot(series=(strategy.position_size < 0) and show_plots ? current_target_price : na, color=color.yellow, style=plot.style_linebr, title="Short TP") plot(series=(strategy.position_size > 0) and show_plots ? current_target_price : na, color=color.yellow, style=plot.style_linebr, title="Long TP") //plot(series=(strategy.position_size < 0) ? profit_sl_short : na, // color=color.gray, style=plot.style_linebr, // title="Short Stop")