
다주기 동적 변동률 추적 전략은 빠른/ 느린 지수 이동 평균 (EMA) 과 비교적 강한 지수 (RSI) 필터를 결합한 단선 거래 시스템이다. 이 전략은 지배적인 단기 트렌드 내에서 회귀 기회를 찾는 데 초점을 맞추고, 다수의 확인 메커니즘을 통해 거래 소음을 줄인다. 핵심 특징은 평균 실제 파도 (ATR) 에 기반한 위험 제어, 적응 추적 스톱 로스, 거래량에 기반한 스톱 로스 조정 및 3단계 부분 수익을 목표로 하는 것이다.
이 전략은 다층적인 신호 스택 아키텍처를 기반으로 작동한다:
전략의 핵심 혁신은 다중 기술 지표와 시장 행동 지표 (거래량, 변동률과 같은) 를 유기적으로 결합하여 다양한 시장 조건에 따라 변수를 자동으로 조정할 수 있는 적응력있는 거래 시스템을 형성하는 것입니다.
다주기 역동적인 변동률 추적 전략은 고전적인 기술 분석 도구와 현대적인 수치적 위험 관리 방법을 결합한 단선 거래 시스템이다. EMA 트렌드 식별, RSI 동량 필터링, 연속 K 라인 확인 메커니즘, ATR 변동률 조정 및 다주기 분석과 결합한 다층 신호 스택 아키텍처를 통해 포괄적인 거래 의사 결정 프레임워크를 구축한다. 이 전략의 가장 눈에 띄는 특징은 시장의 변동률, 거래량 및 트렌드 성숙도에 따라 자동으로 거래 매개 변수와 위험 제어 조치를 조정할 수 있는 자율 적응 이다.
변수 민감성, 고주파 거래 비용 및 지연 위험 등과 같은 일부 고유한 위험이 있음에도 불구하고, 합리적인 자금 관리 및 지속적인 최적화를 통해 이러한 위험을 효과적으로 제어 할 수 있습니다. 미래의 최적화 방향은 주로 기계 학습 변수 최적화, 시장 상태 분류, 다중 지표 합의 메커니즘 및 동적 위험 관리 등에 집중합니다.
이 전략은 단선 시장에서 트렌드 내의 회귀 기회를 잡기를 원하는 거래자에게 거래 기회 포착과 위험 통제의 필요성을 균형 잡는 구조화된 프레임 워크를 제공합니다. 그러나 모든 거래 전략과 마찬가지로 실제 적용 시 모의 계좌에서 충분히 테스트하고 개인 위험 감수성과 자본 규모에 따라 파라미터를 적절하게 조정해야합니다.
/*backtest
start: 2024-09-15 00:00:00
end: 2025-06-09 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
//@strategy_alert_message {{strategy.order.comment}}
// © AlgoSystems
strategy("Scalping Trend Power for MT5 - Updated", overlay=true, calc_on_every_tick=false)
//-------------------------------------------------------------------
// Function: confirm a condition for N consecutive bars
//-------------------------------------------------------------------
f_confirm(cond, bars) =>
_ok = true
for i = 0 to bars - 1
_ok := _ok and cond[i]
_ok
//-------------------------------------------------------------------
// Inputs: strategy parameters & PineConnector
//-------------------------------------------------------------------
lotSize = input.float(0.1, title="Lot Size")
lotMultiplier = input.float(1.0, title="Lot Multiplier", minval=0.1, step=0.1)
contractType = input.string("FX", title="Contract Type", options=["FX", "CFD", "Futures"])
// (kept for potential future use)
riskPercentage = input.float(1.0, title="Risk per Trade (%)")
riskRewardRatio = input.float(1.2, title="Risk/Reward Ratio", step=0.1)
trailingStopMultiplier = input.float(1.2, title="Trailing-Stop Multiplier", step=0.1)
emaShortLength = input.int(9, title="EMA Short Length")
emaLongLength = input.int(21, title="EMA Long Length")
rsiLength = input.int(14, title="RSI Length")
atrLength = input.int(14, title="ATR Length")
rsiOverbought = input.int(70, title="RSI Overbought Level")
rsiOversold = input.int(30, title="RSI Oversold Level")
higherTF = input.timeframe("30", title="Higher Time-Frame for Exit")
higherRsiOverbought = input.int(70, title="Higher-TF RSI Overbought", minval=50)
higherRsiOversold = input.int(30, title="Higher-TF RSI Oversold", minval=10)
pivotLookback = input.int(5, title="Pivot Look-Back Period", minval=2, step=1)
volumeLookback = input.int(20, title="Volume Look-Back Period", minval=5, step=1)
volumeMultiplier = input.float(1.0, title="Volume Multiplier", minval=0.1, step=0.1)
enablePartialExit = input.bool(true, title="Enable Partial Exit")
tp1ProfitMult = input.float(1.0, title="TP1 Profit Multiplier", step=0.1)
tp2ProfitMult = input.float(1.5, title="TP2 Profit Multiplier", step=0.1)
tp3ProfitMult = input.float(2.0, title="TP3 Profit Multiplier", step=0.1)
tp1ExitPercentage = input.float(33, title="TP1 Exit (%)", minval=1, maxval=100, step=1)
tp2ExitPercentage = input.float(33, title="TP2 Exit (%)", minval=1, maxval=100, step=1)
tp3ExitPercentage = input.float(34, title="TP3 Exit (%)", minval=1, maxval=100, step=1)
confirmBars = input.int(2, title="Confirmation Bars", minval=1, step=1)
baseLongTrades = 5
tradeDecreaseFactor = input.int(0, title="Trade Decrease Factor", minval=0)
maxLongTradesPerTrend = math.max(1, baseLongTrades - tradeDecreaseFactor)
activatePineConnector = input.bool(false, title="Activate PineConnector")
pineConnectorLicense = input.string("", title="PineConnector License Code")
//-------------------------------------------------------------------
// Indicator calculations
//-------------------------------------------------------------------
emaShort = ta.ema(close, emaShortLength)
emaLong = ta.ema(close, emaLongLength)
rsiValue = ta.rsi(close, rsiLength)
atrValue = ta.atr(atrLength)
// ATR-based TP & SL
dynamicTP = atrValue * riskRewardRatio
dynamicSL = atrValue * trailingStopMultiplier
rawLongSignal = emaShort > emaLong and rsiValue < rsiOverbought
rawShortSignal = emaShort < emaLong and rsiValue > rsiOversold
longSignal = f_confirm(rawLongSignal, confirmBars)
shortSignal = f_confirm(rawShortSignal, confirmBars)
//-------------------------------------------------------------------
// Dynamic ticker symbol (remove exchange prefix if any)
//-------------------------------------------------------------------
var string dynSymbol = na
if bar_index == 0
parts = str.split(syminfo.tickerid, ":")
dynSymbol := array.size(parts) > 1 ? array.get(parts, 1) : syminfo.tickerid
//-------------------------------------------------------------------
// PineConnector messages (no "lots=" or "contract=" – updated syntax)
// The value after risk= is interpreted as LOTS if EA’s VolumeType = "Lots".
//-------------------------------------------------------------------
prefix = activatePineConnector and (pineConnectorLicense != "") ? pineConnectorLicense + "," : ""
calculatedLot = lotSize * lotMultiplier // actual order volume
// ENTRY messages
riskValue = str.tostring(calculatedLot) // risk= interpreted as lots
txtBuy = prefix + "buy," + dynSymbol + ",risk=" + riskValue
txtSell = prefix + "sell," + dynSymbol + ",risk=" + riskValue
// CLOSE FULL messages
txtCloseLong = prefix + "closelong," + dynSymbol
txtCloseShort = prefix + "closeshort," + dynSymbol
// Helper to compute risk= for partial exits
f_partialRisk(pct) => str.tostring(calculatedLot * pct / 100)
// PARTIAL EXIT messages
msgTP1Long = prefix + "closelongvol," + dynSymbol + ",risk=" + f_partialRisk(tp1ExitPercentage)
msgTP2Long = prefix + "closelongvol," + dynSymbol + ",risk=" + f_partialRisk(tp2ExitPercentage)
msgTP3Long = prefix + "closelongvol," + dynSymbol + ",risk=" + f_partialRisk(tp3ExitPercentage)
msgTP1Short = prefix + "closeshortvol," + dynSymbol + ",risk=" + f_partialRisk(tp1ExitPercentage)
msgTP2Short = prefix + "closeshortvol," + dynSymbol + ",risk=" + f_partialRisk(tp2ExitPercentage)
msgTP3Short = prefix + "closeshortvol," + dynSymbol + ",risk=" + f_partialRisk(tp3ExitPercentage)
//-------------------------------------------------------------------
// Higher-time-frame RSI request
//-------------------------------------------------------------------
higherRsi = request.security(syminfo.tickerid, higherTF, ta.rsi(close, rsiLength))
//-------------------------------------------------------------------
// State variables
//-------------------------------------------------------------------
var bool inLongTrade = false
var bool inShortTrade = false
var int longTradeCount = 0
var float trailingStopLevel = na
var bool tp1_exited = false
var bool tp2_exited = false
var bool tp3_exited = false
//-------------------------------------------------------------------
// Entry/Exit logic
//-------------------------------------------------------------------
if barstate.isconfirmed
avgVol = ta.sma(volume, volumeLookback)
volRatio = avgVol != 0 ? volume / avgVol : 1.0
adjSL = dynamicSL / (volRatio * volumeMultiplier)
pivotH = ta.pivothigh(high, pivotLookback, pivotLookback)
pivotL = ta.pivotlow(low, pivotLookback, pivotLookback)
// LONG entry
if longSignal and not inLongTrade and not inShortTrade and longTradeCount < maxLongTradesPerTrend
strategy.entry("Long", strategy.long, qty=calculatedLot, comment="Long Entry")
if activatePineConnector
alert(txtBuy, alert.freq_once_per_bar)
inLongTrade := true
inShortTrade := false
longTradeCount += 1
trailingStopLevel := low - adjSL
tp1_exited := false
tp2_exited := false
tp3_exited := false
// SHORT entry
if shortSignal and not inShortTrade and not inLongTrade
strategy.entry("Short", strategy.short, qty=calculatedLot, comment="Short Entry")
if activatePineConnector
alert(txtSell, alert.freq_once_per_bar)
inShortTrade := true
inLongTrade := false
trailingStopLevel := high + adjSL
tp1_exited := false
tp2_exited := false
tp3_exited := false
// Trailing-stop update
if inLongTrade
baseStop = close - adjSL
trailingStopLevel := (not na(pivotL) and pivotL > trailingStopLevel) ? pivotL : math.max(trailingStopLevel, baseStop)
if inShortTrade
baseStop = close + adjSL
trailingStopLevel := (not na(pivotH) and pivotH < trailingStopLevel) ? pivotH : math.min(trailingStopLevel, baseStop)
// Dynamic TPs & partial exits
if enablePartialExit and strategy.position_size != 0
avgPrice = strategy.position_avg_price
direction = strategy.position_size > 0 ? 1 : -1
tp1 = avgPrice + direction * dynamicTP * tp1ProfitMult
tp2 = avgPrice + direction * dynamicTP * tp2ProfitMult
tp3 = avgPrice + direction * dynamicTP * tp3ProfitMult
// TP1
if not tp1_exited and f_confirm(direction > 0 ? close >= tp1 : close <= tp1, confirmBars)
strategy.exit("TP1", from_entry=direction>0 ? "Long" : "Short", qty_percent=tp1ExitPercentage, limit=tp1, comment=direction>0 ? msgTP1Long : msgTP1Short)
if activatePineConnector
alert(direction>0 ? msgTP1Long : msgTP1Short, alert.freq_once_per_bar)
tp1_exited := true
// TP2
if not tp2_exited and f_confirm(direction > 0 ? close >= tp2 : close <= tp2, confirmBars)
strategy.exit("TP2", from_entry=direction>0 ? "Long" : "Short", qty_percent=tp2ExitPercentage, limit=tp2, comment=direction>0 ? msgTP2Long : msgTP2Short)
if activatePineConnector
alert(direction>0 ? msgTP2Long : msgTP2Short, alert.freq_once_per_bar)
tp2_exited := true
// TP3
if not tp3_exited and f_confirm(direction > 0 ? close >= tp3 : close <= tp3, confirmBars)
strategy.exit("TP3", from_entry=direction>0 ? "Long" : "Short", qty_percent=tp3ExitPercentage, limit=tp3, comment=direction>0 ? msgTP3Long : msgTP3Short)
if activatePineConnector
alert(direction>0 ? msgTP3Long : msgTP3Short, alert.freq_once_per_bar)
tp3_exited := true
// FULL exit (trailing stop or opposite signals)
exitCondLong = inLongTrade and (close < trailingStopLevel or rsiValue > rsiOverbought or higherRsi > higherRsiOverbought)
exitCondShort = inShortTrade and (close > trailingStopLevel or rsiValue < rsiOversold or higherRsi < higherRsiOversold)
if exitCondLong and f_confirm(exitCondLong, confirmBars)
strategy.exit("ExitLong", from_entry="Long", stop=trailingStopLevel, comment=txtCloseLong)
if activatePineConnector
alert(txtCloseLong, alert.freq_once_per_bar)
inLongTrade := false
if exitCondShort and f_confirm(exitCondShort, confirmBars)
strategy.exit("ExitShort", from_entry="Short", stop=trailingStopLevel, comment=txtCloseShort)
if activatePineConnector
alert(txtCloseShort, alert.freq_once_per_bar)
inShortTrade := false
// Reset counter when the bullish trend ends
if not rawLongSignal
longTradeCount := 0
//-------------------------------------------------------------------
// Plot & styling
//-------------------------------------------------------------------
plot(emaShort, color=color.blue, linewidth=1, title="EMA Short")
plot(emaLong , color=color.red , linewidth=1, title="EMA Long")
barcolor(inLongTrade ? color.new(color.green,0) : inShortTrade ? color.new(color.red,0) : na)
bgcolor(rawLongSignal ? color.new(color.green,90) : rawShortSignal ? color.new(color.red,90) : na)
// Signal arrows disabled (user request):
// plotshape(longSignal , title="Long signal", style=shape.triangleup, location=location.belowbar, color=color.green, size=size.tiny)
// plotshape(shortSignal, title="Short signal", style=shape.triangledown, location=location.abovebar, color=color.red, size=size.tiny)
//-------------------------------------------------------------------
// HOW TO USE with PineConnector (quick checklist):
// 1. Attach this script to the chart.
// 2. Click the “Alert” bell → Create Alert.
// 3. Condition: “Scalping Trend Power … (Any alert() call)” (or “Order fills only”).
// 4. Webhook URL: https://webhook.pineconnector.com
// 5. Leave the Message box empty – the script fills it.
// 6. On MT5, run the PineConnector EA on the same symbol (dynSymbol) and keep VolumeType = Lots.
// 7. Enter your License ID in the input and tick “Activate PineConnector”.
//-------------------------------------------------------------------