
여러 시간 프레임 이동 평균 크로스 오버 전략 (Multi Timeframe Moving Average Crossover Strategy) 은 트렌드 방향을 판단하기 위해 다른 시간 주기 이동 평균 사이의 교차 신호를 사용하는 알고리즘 거래 전략이다. 이 전략은 트렌드 지표, 운동 지표 및 변동률 지표의 조합을 종합적으로 활용하여 전략 신호를 더 신뢰할 수 있습니다.
이 전략은 다른 주기의 CCI 지표를 계산하여 시장의 경향 방향을 판단하고, MACD 지표와 결합하여 황금 포크 사다리 신호를 찾고, 마지막으로 ATR 지표로 스톱 로즈 포지션을 설정하여 낮은 가격으로 높은 가격으로 판매한다.
구체적으로, 먼저 20주기의 CCI 지표를 계산하여 시장의 흐름을 판단합니다. MACD 지표의 급속도 평균선이 교차하는지 계산하여 매매 신호가 발생하는지 판단합니다. 그 다음 ATR 지표를 사용하여 추적 스톱 손실 메커니즘을 생성하여 수익을 더욱 고정합니다. 마지막으로 위의 여러 지표의 신호를 통합하여 최종 매매 전략 신호를 생성합니다.
이 전략은 CCI, MACD, ATR의 3가지 지표의 조합을 사용하여 시장의 추세, 동력 및 변동률을 종합적으로 판단하여 전략 신호를 더 정확하고 신뢰할 수 있도록 합니다.
다른 주기의 CCI를 사용하여 시장의 전반적인 움직임을 판단하고, 고기 MACD와 함께 낮은 구매 고 판매 노드를 찾고, 시장의 더 큰 추세 속도를 파악할 수 있다.
ATR 지표가 생성하는 스톱 로스를 통해 시장의 변동율에 따라 합리적인 스톱 로스를 설정할 수 있으며, 스톱 로스를 추적하는 기능을 통해 전략의 위험을 잘 제어할 수 있다.
이 전략의 대부분의 변수들의 조정 공간은 그리 크지 않아 효과의 한계에 도달하기 쉬우며, 전략의 효과를 더 향상시키는 것을 제한한다.
전략이 여러 지표를 사용하여 조합 연산을 하기 때문에 전략의 계산 부하가 어느 정도 증가한다. 고주파 거래에서 카톤 문제가 발생할 수 있다.
전략적 신호는 더 자주 발생할 수 있으며, ATR 지표의 손실 추적에 의존하는 리스크 통제는 극단적인 상황에 대한 리스크 통제는 완전하지 않습니다.
몇 가지 기계 학습의 초변수 최적화 알고리즘을 사용할 수 있습니다. 예를 들어, 베이스 최적화, 유전 알고리즘 등으로 변수 조정을 더 지능적이고 효율적으로 할 수 있습니다.
전략의 적응성과 융통성을 향상시키기 위해, 유동성 지표, 양력 지표, 감정 지표와 같은 몇 가지 다른 기능적 지표를 추가하는 것을 고려할 수 있습니다.
더 과학적인 상쇄 원칙을 설계할 수도 있고, 특정 포지션 제어 또는 자금 관리 모듈을 추가할 수도 있으며, 극단적인 상황의 위험을 더 잘 보호하고, 전략의 안정성을 보장할 수 있다.
다중 시간 프레임 횡단 평평선 전략은 CCI, MACD 및 ATR의 3 대 지표의 조합을 사용하여보다 신뢰할 수 있는 추세 판단과 효율적인 위험 통제를 달성합니다. 이 전략은 종합적으로 추세, 운동량 및 변동률의 3 차원을 고려하고, 신호 정확도가 높으며 시장의 속도를 파악하고 효과적으로 위험을 통제하는 장점이 있습니다. 물론, 전략에는 특정 파라미터 최적화 공간, 제한된 계산 부하 및 위험 통제를 향상시킬 수있는 문제가 있습니다. 더 많은 지표를 도입하고, 더 나은 파라미터 최적화 방법을 사용하고, 더 강력한 위험 제어 모듈을 설계함으로써이 전략은 더욱 향상되고 최적화 될 수 있습니다.
/*backtest
start: 2024-01-01 00:00:00
end: 2024-01-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy('smplondonclinic Strategy', shorttitle='SMPLC Strategy', overlay=true, pyramiding = 0, process_orders_on_close = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100)
direction = input.string(title='Entry Direction', defval='Long', options=['Long', 'Short', 'Both'],group = "Strategy Entry Direction")
TPPerc = input.float(title='Take Profit (%)', minval=0.0, step=0.1, defval=0.5, group='Strategy TP & SL')
SLPerc = input.float(title='Stop Loss (%)', minval=0.0, step=0.1, defval=0.5, group='Strategy TP & SL')
period = input(20, 'CCI period',group = "TREND MAGIC")
coeff = input(1, 'ATR Multiplier',group = "TREND MAGIC")
AP = input(5, 'ATR Period',group = "TREND MAGIC")
ATR = ta.sma(ta.tr, AP)
srctm = close
upT = low - ATR * coeff
downT = high + ATR * coeff
MagicTrend = 0.0
MagicTrend := ta.cci(srctm, period) >= 0 ? upT < nz(MagicTrend[1]) ? nz(MagicTrend[1]) : upT : downT > nz(MagicTrend[1]) ? nz(MagicTrend[1]) : downT
color1 = ta.cci(srctm, period) >= 0 ? #0022FC : #FC0400
plot(MagicTrend, color=color1, linewidth=3)
tmb = ta.cci(srctm, period) >= 0 and close>MagicTrend
tms = ta.cci(srctm, period) <= 0 and close<MagicTrend
//MACD
res = input.timeframe("", "Indicator TimeFrame", group = "MACD")
fast_length = input.int(title="Fast Length", defval=12, group = "MACD")
slow_length = input.int(title="Slow Length", defval=26, group = "MACD")
src = input.source(title="Source", defval=close, group = "MACD")
signal_length = input.int(title="Signal Smoothing", minval = 1, maxval = 999, defval = 9, group = "MACD")
sma_source = input.string(title="Oscillator MA Type", defval="EMA", options=["SMA", "EMA"], group = "MACD")
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group = "MACD")
fast_ma = request.security(syminfo.tickerid, res, sma_source == "SMA" ? ta.sma(src, fast_length) : ta.ema(src, fast_length))
slow_ma = request.security(syminfo.tickerid, res, sma_source == "SMA" ? ta.sma(src, slow_length) : ta.ema(src, slow_length))
macd = fast_ma - slow_ma
signal = request.security(syminfo.tickerid, res, sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length))
hist = macd - signal
trend_up = macd > signal
trend_dn = macd < signal
cross_UP = signal[1] >= macd[1] and signal < macd
cross_DN = signal[1] <= macd[1] and signal > macd
cross_UP_A = (signal[1] >= macd[1] and signal < macd) and macd > 0
cross_DN_B = (signal[1] <= macd[1] and signal > macd) and macd < 0
//UT Bot
srcut = close
showut = input.bool(false, 'Show UT Bot Labels', group = "UT BOT")
keyvalue = input.float(2, title='Key Vaule. \'This changes the sensitivity\'', step=.5, group = "UT BOT")
atrperiod = input(7, title='ATR Period', group = "UT BOT")
xATR = ta.atr(atrperiod)
nLoss = keyvalue * xATR
xATRTrailingStop = 0.0
iff_1 = srcut > nz(xATRTrailingStop[1], 0) ? srcut - nLoss : srcut + nLoss
iff_2 = srcut < nz(xATRTrailingStop[1], 0) and srcut[1] < nz(xATRTrailingStop[1], 0) ? math.min(nz(xATRTrailingStop[1]), srcut + nLoss) : iff_1
xATRTrailingStop := srcut > nz(xATRTrailingStop[1], 0) and srcut[1] > nz(xATRTrailingStop[1], 0) ? math.max(nz(xATRTrailingStop[1]), srcut - nLoss) : iff_2
pos = 0
iff_3 = srcut[1] > nz(xATRTrailingStop[1], 0) and srcut < nz(xATRTrailingStop[1], 0) ? -1 : nz(pos[1], 0)
pos := srcut[1] < nz(xATRTrailingStop[1], 0) and srcut > nz(xATRTrailingStop[1], 0) ? 1 : iff_3
xcolor = pos == -1 ? color.red : pos == 1 ? color.green : color.blue
//plot(xATR, color=xcolor, title='Trailing Stop')
buy = ta.crossover(srcut, xATRTrailingStop)
sell = ta.crossunder(srcut, xATRTrailingStop)
barcolor = srcut > xATRTrailingStop
plotshape(showut ? buy:na, title='Buy', text='Buy', style=shape.labelup, location=location.belowbar, color=color.new(color.green, 0), textcolor=color.new(color.white, 0), size=size.tiny)
plotshape(showut ? sell:na, title='Sell', text='Sell', style=shape.labeldown, color=color.new(color.red, 0), textcolor=color.new(color.white, 0), size=size.tiny)
//barcolor(barcolor ? color.green : color.red)
goLong = buy and tmb and cross_UP
goShort = sell and tms and cross_DN
plotshape(goLong, location=location.bottom, style=shape.triangleup, color=color.lime, size=size.small)
plotshape(goShort, location=location.top, style=shape.triangledown, color=color.red, size=size.small)
percentAsPoints(pcnt) =>
strategy.position_size != 0 ? math.round(pcnt / 100.0 * strategy.position_avg_price / syminfo.mintick) : float(na)
percentAsPrice(pcnt) =>
strategy.position_size != 0 ? (pcnt / 100.0 + 1.0) * strategy.position_avg_price : float(na)
current_position_size = math.abs(strategy.position_size)
initial_position_size = math.abs(ta.valuewhen(strategy.position_size[1] == 0.0, strategy.position_size, 0))
TP = strategy.position_avg_price + percentAsPoints(TPPerc) * syminfo.mintick * strategy.position_size / math.abs(strategy.position_size)
SL = strategy.position_avg_price - percentAsPoints(SLPerc) * syminfo.mintick * strategy.position_size / math.abs(strategy.position_size)
var long = false
var short = false
if direction == 'Long'
long := goLong
short := false
if direction == 'Short'
short := goShort
long := false
if direction == 'Both'
long := goLong
short := goShort
if long and strategy.opentrades == 0
strategy.entry(id='Long', direction=strategy.long)
if short and strategy.opentrades == 0
strategy.entry(id='Short', direction=strategy.short)
if strategy.position_size > 0
strategy.exit('TPSL', from_entry='Long', qty=initial_position_size, limit=TP, stop=SL)
if strategy.position_size < 0
strategy.exit('TPSL2', from_entry='Short', qty=initial_position_size, limit=TP, stop=SL)