
この戦略は,二重時間枠と動量指標の組み合わせを採用し,自主的にストップ・ロスを実現する. 主要時間枠はトレンドの方向を監視し,補助時間枠は確認信号に使用する. 両方方向が一致するときに取引信号を生成する. 市場に出回った後に,進出ストップ方式でストップ・ロスを更新する.
主時間枠は線形回帰指標Sqqueeze Momentum ((SQM) を用いてトレンドを判断し,補助時間枠はSQM指標のEMA組み合わせを用いて偽信号をフィルターする.
主図SQMが上を突破し,補助図SQMも上を突破すると,多めにする.主図SQMが下を突破し,補助図SQMも下を突破すると,空きをする.
入場後,入力パラメータに基づいて初期ストップとストップ・ロスを設定する.価格がストップ・ロスを達成すると,ストップ・ロスを更新する.具体的には,ストップ・ロスは設定された割合で増加し,ストップ・ロスは割合で減少し,漸進ストップを実現する.
信号の正確性を確保するために,ダブルタイムフレームは偽信号をフィルターします.
SQM指標は,市場騒音に邪魔されないようにトレンドの方向性を判断します.
自動ストップ・ストップ・メカニズムにより,利益の最大化とリスクの有効な管理を行う.
SQM指標のパラメータが正しく設定されていなければ,トレンドの転換点を逃し,損失をもたらす可能性があります.
補助グラフのタイムフレームが正しく選択されず,ノイズが効果的にフィルターされず,誤った取引が起こります.
ストップ・ロスの幅が大きすぎると,単一の損失はかなり大きいかもしれません.
SQM指標のパラメータは,異なる市場に応じて調整され,その感受性を確保する必要があります.
補助グラフの時間枠は,どの周期がフィルタリングに最も効果的かを確認するために,異なる周期をテストする必要があります.
ストップ・ロスの幅は,固定値ではなく波動範囲を設定することができ,市場の波動程度に応じて調整することができる.
この戦略は,全体的に非常に実用的で,動量指標を組み合わせた2つの時間枠でトレンドを判断し,自己適応のストップ・ストップ・ロスを利用して安定した利益を達成します.SQM指標パラメータを最適化して,図周期とストップ・ロスの幅の設定を補助することで,戦略の効果をより良くすることができ,実用化して最適化することが重要です.
/*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")