Esta estratégia combina quadros de tempo duplos e indicadores de momentum para alcançar o aproveitamento adaptativo e o stop loss. O quadro de tempo principal monitora a direção da tendência, enquanto o quadro de tempo secundário é usado para confirmar sinais. Os sinais de negociação são gerados quando as direções de ambos se alinham. Após entrar no mercado, os níveis de aproveitamento e stop loss são atualizados progressivamente.
O quadro de tempo principal usa o indicador de regressão linear Squeeze Momentum (SQM) para determinar a tendência. O quadro de tempo secundário usa uma combinação EMA no indicador SQM para filtrar sinais falsos.
Quando o gráfico principal SQM rompe para cima e o gráfico secundário SQM também sobe, uma posição longa é tomada.
Após a entrada no mercado, os níveis iniciais de take profit e stop loss são definidos com base nos parâmetros de entrada. Quando o preço atinge o nível de take profit, os níveis de take profit e stop loss são atualizados. Especificamente, o nível de take profit é aumentado progressivamente e o nível de stop loss é apertado, alcançando uma gradual take profit.
Duas marcas de tempo filtram os falsos sinais e garantem a precisão.
O indicador SQM determina a direcção da tendência, evitando o ruído do mercado.
O mecanismo adaptativo de captação de lucros e stop loss bloqueia os lucros na medida máxima e controla efetivamente o risco.
As configurações incorretas dos parâmetros SQM podem deixar de lado pontos de virada da tendência, levando a perdas.
Um quadro temporal secundário inadequado pode não filtrar o ruído de forma eficaz, causando trocas errôneas.
Se a amplitude de stop loss for demasiado larga, a perda por transacção pode ser substancial.
Os parâmetros do MQQ devem ser ajustados para diferentes mercados para garantir a sensibilidade.
Devem ser testados diferentes períodos de tempo secundários para determinar o melhor efeito de filtragem do ruído.
Em vez de um valor fixo, a amplitude de stop loss pode ter um intervalo definido dinamicamente com base na volatilidade do mercado.
No geral, esta é uma estratégia muito prática. A combinação de quadros de tempo duplos com um indicador de impulso para determinar tendências, juntamente com o método adaptativo de lucro e stop loss, pode gerar lucros estáveis. Ao otimizar os parâmetros do SQM, o período de período de tempo secundário e a amplitude de stop loss, os resultados da estratégia podem ser melhorados para aplicação e aprimoramento produtivos ao 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")