
부린띠와 ATR 동적 트렌드 추적 전략은 부린띠의 돌파 신호와 평균 실제 변동 범위 (ATR) 의 동적 조정 기능을 결합하여 “추적 라인” (Follow Line) 메커니즘을 통해 시장 트렌드를 식별하고 추적하는 첨단 양적 거래 시스템입니다. 이 전략은 특히 다중 시간 프레임 (HTF) 확인 메커니즘을 도입하여 전략의 안정성과 수익성을 크게 향상시키고 더 높은 시간 프레임의 트렌드 방향에 따라 거래 신호를 필터링 할 수 있습니다.
이 전략의 핵심은 “트래킹 라인” 메커니즘으로 다음과 같은 단계를 통해 시장 추세를 동적으로 식별하고 대응합니다.
브린 밴드 신호 생성시스템은 먼저 표준 부린 대역 ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
트래킹 라인 계산: 브린띠 신호와 현재 가격 위치에 따라, 시스템은 임시 추적 선값을 계산한다. 호우 신호의 경우, 추적 선은 현재 K 선 하위점으로 ATR 값을 빼고 ((ATR 필터를 활성화 할 때) 또는 직접 낮은 점을 사용한다.
트래킹 라인 잠금 메커니즘전략: 트래드 라인을 유지하기 위해 “스파인 바퀴” 논리를 사용한다. 상승 추세에서 새로운 트래드 라인 값은 이전 값보다 더 큰 임시 값으로; 하향 추세에서 임시 값은 이전 값보다 작습니다. 이것은 트래드 라인이 동적인 지지 / 저항 수준을 형성하는 방향으로만 이동할 수 있도록 보장합니다.
트렌드 결정: 현재의 추적선과 이전 추적선 값을 비교하여, 시스템은 트렌드 방향을 결정한다. 상승은 다중 경향을 나타내고, 하락은 공중 경향을 나타내고, 평면은 이전 경향을 유지한다.
다중 시간 프레임 분석전략: 비슷한 논리를 사용하여 더 높은 시간 프레임에서 트렌드 라인 및 트렌드 상태를 계산하고, 적절한 더 높은 시간 프레임을 자동으로 또는 수동으로 선택할 수 있습니다 (예: 1 분 자동 대응 15 분 HTF).
입학 조건: 거래 시간 프레임 트렌드가 중립 또는 하락에서 상승으로 바뀌고 HTF가 상승 추세를 확인했을 때, 다중 신호를 생성합니다. 반대로 하위 신호를 생성합니다.
출전 조건: 거래 시간 프레임 트렌드가 반대 방향으로 바뀌거나 HTF 트렌드가 반대 방향으로 바뀌면 (v2.5 버전이 새로 추가되었습니다) 전략 평준화는 현재 위치 .
시간 필터: 특정 거래 시간 내에만 거래하는 것을 선택할 수 있다.
적응력: 트래킹 라인 메커니즘은 시장의 변동성에 따라 자동으로 조정할 수 있으며, 특히 ATR 필터를 활성화하면 다양한 변동률 환경에 대한 동적 적응력을 제공합니다.
트렌드 확인 메커니즘다중 시간 프레임 확인 기능은 “소음” 거래를 효과적으로 필터링하여 HTF 트렌드 방향이 일치하는 경우에만 거래하여 신호 품질을 크게 향상시킵니다.
유연한 구성 옵션: 전략은 부린 밴드 주기 및 오차, ATR 주기, 시간 필터링 및 HTF 선택 방법 등과 같은 풍부한 파라미터 설정을 제공하며, 다른 시장 및 거래 품종에 따라 최적화 할 수 있습니다.
높은 반응성: v2.5 버전의 새로운 HTF 트렌드 변화 반응 메커니즘은 전략이 큰 트렌드 변화에 더 빨리 반응할 수 있도록, 적시에 손실을 막고 심각한 회귀를 피할 수 있도록 해줍니다.
시각적 도움말전략: 거래 시간 프레임과 HTF의 추적선을 차트에 그리고 선택적으로 구매 신호 태그를 표시하여 거래 논리를 직관적으로 만듭니다.
포지션 관리: pyramiding=0을 설정하여 같은 방향으로 여러 번 입구를 방지하여 불필요한 위험 축적을 방지한다.
가짜 침입 위험: 부린밴드 및 HTF 확인이 사용되었음에도 불구하고, 시장은 여전히 가짜 돌파구가 발생할 수 있습니다. 특히 높은 변동률 환경에서. 해결 방법: 부린밴드 오차 값을 증가 시키거나 확정 주기를 연장하거나 추가적인 돌파구 확인 메커니즘을 추가 할 수 있습니다.
매개변수 민감도전략적 성능은 ATR 주기, 브린 띠 설정 등의 파라미터에 민감하다. 해결 방법: 재검토를 통해 특정 거래 품종에 가장 적합한 파라미터 조합을 찾아, 과도한 최적화로 인한 곡선 적합 문제를 피한다.
추세 변화 후기트래킹 라인 메커니즘은 트렌드의 초기 단계에서 반응이 느려 입장이 약간 늦어질 수 있다. 해결 방법: 더 작은 ATR 곱수 또는 브린 주기를 사용하여 응답 속도를 높이는 것을 고려할 수 있지만 신호 품질과 응답성을 균형 잡아야 한다.
시간 프레임 의존잘못된 HTF 선택은 과도한 필터링이나 신호 충돌을 초래할 수 있습니다. 해결 방법: 자동 HTF 선택 기능을 사용하는 것이 좋습니다. 이는 현재 차트 시간 프레임에 따라 적절한 더 높은 시간 프레임을 자동으로 선택합니다.
재무 관리 부족전략 자체는 완전한 자금 관리 메커니즘을 포함하지 않습니다. 해결 방법: 실제 응용에서는 적절한 손실 전략과 고정 비율 위험 또는 ATR 배수 손실과 같은 위치 관리 규칙을 결합해야합니다.
강화 신호 필터링다른 기술적인 지표를 도입하는 것을 고려할 수 있습니다. 상대적으로 약한 지표 ((RSI) 또는 무작위 지표 ((Stochastic) 가 진입 신호를 확인하고 지표가 오버 바이/오버 셀 상태를 표시할 때만 거래를 수행합니다. 이것은 가짜 브레이크 신호를 더욱 줄이고 승률을 높일 것입니다.
동적 변수 조정: 시장 상태에 기반한 적응 파라미터 조정 메커니즘을 개발할 수 있습니다. 예를 들어, 높은 변동률 환경에서 브린 밴드 편차 값을 자동으로 증가시키고 낮은 변동률 환경에서 편차 값을 줄여서 전략이 다른 시장 조건에 더 잘 적응 할 수 있습니다.
HTTP 트렌드 판단을 최적화: HTF 트렌드 확인 알고리즘을 개선할 수 있습니다. 예를 들어, 지수 이동 평균 크로스 또는 다른 트렌드 지표를 도입하여 더 안정적인 트렌드 판단을 위해 추적 라인 방향에만 의존하지 않습니다.
자금 관리 개선포괄적 인 자금 관리 시스템을 통합하여 시장의 변동성과 계정 규모에 따라 포지션 크기를 동적으로 조정하고 ATR 기반의 중지 손실 수준과 수익 목표를 설정하여 리스크 조정 후 수익을 극대화합니다.
시장 상태 분석을 추가하기: 시장 환경 분류를 도입하여 트렌드 시장과 변동 시장을 구분하고, 시장 상태에 따라 전략 매개 변수 또는 거래 규칙을 자동으로 조정하고, 심지어는 전략에 적합하지 않은 시장 환경에서 거래를 중단합니다.
다중 전략 통합이 전략을 하나의 구성요소로, 다른 상호보완적인 전략 (예: 반전 전략 또는 브레이크 콘퍼메이션 전략) 과 결합하여 다양한 시장 환경에서의 성능을 균형 잡는 완전한 전략 포지션을 형성한다.
부린밴드 및 ATR 동적 트렌드 추적 전략은 부린밴드, ATR 및 다중 시간 프레임 분석을 결합하여 시장 트렌드를 효과적으로 식별하고 추적하는 정교하게 설계된 정량 거래 시스템입니다. 이 전략의 핵심 장점은 시장 상황에 따라 동적으로 조정할 수 있는 자율성과 유연성이며, HTF 확인 메커니즘을 통해 신호 품질과 승률을 향상시킵니다.
파라미터 민감성 및 가짜 돌파 문제와 같은 몇 가지 고유한 위험이 있음에도 불구하고, 적절한 파라미터 최적화 및 추가 필터링 메커니즘으로 완화 될 수 있습니다. 강화된 신호 필터링, 동적 파라미터 조정 및 개선된 자금 관리와 같은 전략적 최적화 방향은 전략 성능을 더 향상시키는 데 명확한 경로를 제공합니다.
전체적으로, 이 전략은 중장기 트렌드 트레이더에게 특히 적합하며, 트렌드 변화를 인식하고 유리한 시장 조건에서 거래를 수행하는 데 필요한 안정적인 프레임워크를 제공합니다. 합리적인 매개 변수 설정과 적절한 위험 관리를 통해, 이 전략은 다양한 시장 환경에서 안정적인 수익을 창출할 잠재력을 가지고 있습니다.
/*backtest
start: 2024-07-20 00:00:00
end: 2025-04-07 00:00:00
period: 2d
basePeriod: 2d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=6
//@fenyesk
//Optional Working Hours and ATR based TP/SL removed
// Added Optional Higher Timeframe Confirmation with Auto/Manual Selection
// Revised for improved profitability: Trend-following Entries/Exits
// v2.5: React to HTF trend changes as well
strategy('Follow Line Strategy Version 2.5 (React HTF)', overlay = true, process_orders_on_close = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 1, pyramiding = 0) // Version bump overlay=true, process_orders_on_close=true, default_qty_type=strategy.percent_of_equity, default_qty_value=1, pyramiding=0) // Prevent multiple entries in the same direction )
// --- Settings ---
// Indicator Parameters
atrPeriodInput = input.int(defval = 5, title = 'ATR Period', minval = 1, group = 'Indicator Settings')
bbPeriodInput = input.int(defval = 21, title = 'Bollinger Bands Period', minval = 1, group = 'Indicator Settings')
bbDeviationInput = input.float(defval = 1.00, title = 'Bollinger Bands Deviation', minval = 0.1, step = 0.1, group = 'Indicator Settings')
useAtrFilterInput = input.bool(defval = true, title = 'Use ATR for Follow Line Offset?', group = 'Indicator Settings')
showSignalsInput = input.bool(title = 'Show Trade Signals on Chart?', defval = true, group = 'Indicator Settings')
// --- Higher Timeframe Confirmation ---
htf_group = 'Higher Timeframe Confirmation'
useHTFConfirmationInput = input.bool(false, title = 'Enable HTF Confirmation?', group = htf_group)
htfSelectionMethodInput = input.string('Auto', title = 'HTF Selection Method', options = ['Auto', 'Manual'], group = htf_group)
manualHTFInput = input.timeframe('240', title = 'Manual Higher Timeframe', group = htf_group) // Default to 4h if Manual
showHTFLineInput = input.bool(false, title = 'Show HTF Follow Line?', group = htf_group)
// --- Determine Higher Timeframe ---
// Revised function with explicit return variable
f_getAutoHTF() =>
string htfResult = 'D' // Initialize with a default value (e.g., Daily)
if timeframe.isintraday
if timeframe.multiplier <= 1 and timeframe.isminutes
htfResult := '15' // 1min -> 15min
htfResult
else if timeframe.multiplier <= 5 and timeframe.isminutes
htfResult := '240' // 5min -> 4h (240min)
htfResult
else if timeframe.multiplier <= 30 and timeframe.isminutes
htfResult := '240' // 15-30min -> 4h (240min)
htfResult
else if timeframe.multiplier == 60 and timeframe.isminutes // 1 hour
htfResult := 'D' // 1h -> 1 Day
htfResult
else if timeframe.multiplier <= 240 and timeframe.isminutes // Up to 4 hours
htfResult := 'W' // 4h -> 1 Week
htfResult
// else // The default "D" is already set if none of the above match
// htfResult := "D" // Default for other intraday -> 1 Day (already default)
else if timeframe.isdaily // Daily
htfResult := 'M' // 1 Day -> 1 Month
htfResult
else if timeframe.isweekly // Weekly
htfResult := 'M' // 1 Week -> 1 Month
htfResult
else // Monthly or higher (or unknown)
htfResult := '3M' // Default to 3 Months
htfResult
htfResult // Explicitly return the variable value
autoHTF = f_getAutoHTF()
selectedHTF = htfSelectionMethodInput == 'Auto' ? autoHTF : manualHTFInput
// --- Trade Timeframe Calculations ---
// Bollinger Bands calculation
bbMiddle_trade = ta.sma(close, bbPeriodInput)
bbStdDev_trade = ta.stdev(close, bbPeriodInput)
BBUpper_trade = bbMiddle_trade + bbStdDev_trade * bbDeviationInput
BBLower_trade = bbMiddle_trade - bbStdDev_trade * bbDeviationInput
// ATR calculation
atrValue_trade = ta.atr(atrPeriodInput)
// Signal initialization for Trade TF
var float followLine_trade = na
var int bbSignal_trade = 0
var int trend_trade = 0 // Renamed from iTrend
// Determine BB signal based on current close (Trade TF)
if close > BBUpper_trade
bbSignal_trade := 1
bbSignal_trade
else if close < BBLower_trade
bbSignal_trade := -1
bbSignal_trade
else
bbSignal_trade := 0 // Reset signal if price is within bands
bbSignal_trade
// Calculate potential new FollowLine value for the current bar (Trade TF)
float tempFollowLine_trade = na // Explicit type
if bbSignal_trade == 1
tempFollowLine_trade := useAtrFilterInput ? low - atrValue_trade : low
tempFollowLine_trade
else if bbSignal_trade == -1
tempFollowLine_trade := useAtrFilterInput ? high + atrValue_trade : high
tempFollowLine_trade
// Determine the final FollowLine for the current bar, applying the "ratchet" logic (Trade TF)
if bbSignal_trade == 1 // Price closed above upper BB
followLine_trade := na(followLine_trade[1]) ? tempFollowLine_trade : math.max(tempFollowLine_trade, nz(followLine_trade[1], tempFollowLine_trade))
followLine_trade
else if bbSignal_trade == -1 // Price closed below lower BB
followLine_trade := na(followLine_trade[1]) ? tempFollowLine_trade : math.min(tempFollowLine_trade, nz(followLine_trade[1], tempFollowLine_trade))
followLine_trade
else // Price closed within bands, FollowLine continues from previous bar
if not na(followLine_trade[1])
followLine_trade := followLine_trade[1]
followLine_trade
// else followLine_trade remains na if followLine_trade[1] was na
// Trend direction determination (Based on current FollowLine vs previous FollowLine - Trade TF)
if not na(followLine_trade) and not na(followLine_trade[1])
if followLine_trade > followLine_trade[1]
trend_trade := 1
trend_trade
else if followLine_trade < followLine_trade[1]
trend_trade := -1
trend_trade
else
trend_trade := nz(trend_trade[1], 0) // Maintain previous trend if line is flat but valid
trend_trade
else if not na(followLine_trade) and na(followLine_trade[1])
trend_trade := bbSignal_trade == 1 ? 1 : bbSignal_trade == -1 ? -1 : 0 // Use ternary for initial trend
trend_trade
else if na(followLine_trade)
trend_trade := 0 // Reset trend if FollowLine becomes invalid
trend_trade
// --- Higher Timeframe Calculations ---
// Function revised to return only one value (as float) based on parameter
f_calculateHTFData(htf_close, htf_high, htf_low, return_type) =>
// Explicitly type potentially 'na' indicator results
float htf_atrValue = ta.atr(atrPeriodInput)
float htf_bbMiddle = ta.sma(htf_close, bbPeriodInput)
float htf_bbStdDev = ta.stdev(htf_close, bbPeriodInput)
float htf_BBUpper = na
float htf_BBLower = na
// Calculate BBands only if middle/stdev are valid
if not na(htf_bbMiddle) and not na(htf_bbStdDev)
htf_BBUpper := htf_bbMiddle + htf_bbStdDev * bbDeviationInput
htf_BBLower := htf_bbMiddle - htf_bbStdDev * bbDeviationInput
htf_BBLower
// Determine BB signal (HTF) - Default to 0
int htf_bbSignal = 0
// Check if bands are valid before comparing
if not na(htf_BBUpper) and not na(htf_BBLower)
if htf_close > htf_BBUpper
htf_bbSignal := 1
htf_bbSignal
else if htf_close < htf_BBLower
htf_bbSignal := -1
htf_bbSignal
// Calculate potential new FollowLine (HTF)
float htf_tempFollowLine = na // Explicitly typed float
if htf_bbSignal == 1
htf_tempFollowLine := useAtrFilterInput and not na(htf_atrValue) ? htf_low - htf_atrValue : htf_low
htf_tempFollowLine
else if htf_bbSignal == -1
htf_tempFollowLine := useAtrFilterInput and not na(htf_atrValue) ? htf_high + htf_atrValue : htf_high
htf_tempFollowLine
// Maintain FollowLine state using 'var'
var float htf_followLine = na
var int htf_trend = 0
// Determine the final FollowLine (HTF)
if htf_bbSignal == 1
htf_followLine := na(htf_followLine[1]) ? htf_tempFollowLine : math.max(htf_tempFollowLine, nz(htf_followLine[1], htf_tempFollowLine))
htf_followLine
else if htf_bbSignal == -1
htf_followLine := na(htf_followLine[1]) ? htf_tempFollowLine : math.min(htf_tempFollowLine, nz(htf_followLine[1], htf_tempFollowLine))
htf_followLine
else
if not na(htf_followLine[1])
htf_followLine := htf_followLine[1]
htf_followLine
// else htf_followLine remains na if htf_followLine[1] was na (unless reset below)
// Reset FollowLine if it's based on invalid temp line
if na(htf_tempFollowLine) and htf_bbSignal != 0 // If the signal existed but calc failed (e.g., na ATR)
htf_followLine := na // Reset line
htf_followLine
// Determine Trend (HTF)
if not na(htf_followLine) and not na(htf_followLine[1])
if htf_followLine > htf_followLine[1]
htf_trend := 1
htf_trend
else if htf_followLine < htf_followLine[1]
htf_trend := -1
htf_trend
else
htf_trend := nz(htf_trend[1], 0)
htf_trend
else if not na(htf_followLine) and na(htf_followLine[1])
htf_trend := htf_bbSignal == 1 ? 1 : htf_bbSignal == -1 ? -1 : 0
htf_trend
else if na(htf_followLine) // Trend is 0 if line becomes (or is) na
htf_trend := 0
htf_trend
// Return the requested value as float type (or na)
float return_value = na
if return_type == 'line'
return_value := htf_followLine
return_value
else if return_type == 'trend'
return_value := float(htf_trend) // Convert int trend to float for consistent return type
return_value
return_value // Return the single calculated value
// Explicitly declare variables that will receive the security call result
float followLine_htf = na
int trend_htf = 0 // Initialize with a default value (0 for neutral)
// Request HTF data UNCONDITIONALLY
followLine_htf_result = request.security(syminfo.tickerid, selectedHTF, f_calculateHTFData(close, high, low, 'line'), lookahead = barmerge.lookahead_off)
trend_htf_result_float = request.security(syminfo.tickerid, selectedHTF, f_calculateHTFData(close, high, low, 'trend'), lookahead = barmerge.lookahead_off)
// Conditionally assign the results based on whether the HTF feature is enabled
if useHTFConfirmationInput or showHTFLineInput
// Assign results, handling potential 'na' values safely
followLine_htf := followLine_htf_result // Assign float/na directly
trend_htf := na(trend_htf_result_float) ? 0 : int(nz(trend_htf_result_float)) // Convert float result back to int, default to 0 if na
trend_htf
else // If HTF features are disabled, set variables to 'na'
followLine_htf := na
trend_htf := 0 // or na if preferred
trend_htf
// HTF Filter
// Use the potentially 'na' followLine_htf and the guaranteed non-'na' trend_htf
htfConfirmsLong = not useHTFConfirmationInput or useHTFConfirmationInput and trend_htf == 1
htfConfirmsShort = not useHTFConfirmationInput or useHTFConfirmationInput and trend_htf == -1
// --- Entry/Exit Conditions ---
// Buy & Sell Conditions (Based on Trade TF trend crossover)
longCondition_trade = nz(trend_trade[1]) <= 0 and trend_trade == 1
shortCondition_trade = nz(trend_trade[1]) >= 0 and trend_trade == -1
// Combined Entry Conditions with Filters
goLong = htfConfirmsLong and longCondition_trade and strategy.position_size <= 0 // Only enter long if flat or short & HTF confirms
goShort = htfConfirmsShort and shortCondition_trade and strategy.position_size >= 0 // Only enter short if flat or long & HTF confirms
// Exit conditions based on *either* TTF or HTF changing trend against the position
exitLong = trend_trade == -1 or trend_htf == -1 // TTF to short OR HTF to short
exitShort = trend_trade == 1 or trend_htf == 1 // TTF to long OR HTF to long
// --- Strategy Execution ---
if goLong
strategy.close('Short', comment = 'Close Short for Long')
strategy.entry('Long', strategy.long, comment = 'Enter Long')
if goShort
strategy.close('Long', comment = 'Close Long for Short')
strategy.entry('Short', strategy.short, comment = 'Enter Short')
if exitLong
strategy.close('Long', comment = 'Exit Long')
if exitShort
strategy.close('Short', comment = 'Exit Short')
// --- Alerts ---
// Alerts trigger on the same bar as the entry condition, respecting all filters
// NOTE: Removed dynamic HTF from message as alertcondition requires const string
alertcondition(goLong, title = 'FL Buy Signal', message = 'Follow Line Buy Signal - {{ticker}} {{interval}}')
alertcondition(goShort, title = 'FL Sell Signal', message = 'Follow Line Sell Signal - {{ticker}} {{interval}}')
alertcondition(goLong or goShort, title = 'FL Signal', message = 'Follow Line Signal - {{ticker}} {{interval}}')
// --- Plotting ---
// Plot the Trade Timeframe Follow Line
lineColor_trade = trend_trade > 0 ? color.new(color.blue, 0) : trend_trade < 0 ? color.new(color.red, 0) : color.new(color.gray, 0)
plot(followLine_trade, color = lineColor_trade, linewidth = 2, title = 'Follow Line (Trade TF)')
// Plot the Higher Timeframe Follow Line (optional)
// Use the potentially 'na' followLine_htf and the guaranteed non-'na' trend_htf for coloring
lineColor_htf = trend_htf > 0 ? color.new(color.aqua, 0) : trend_htf < 0 ? color.new(color.orange, 0) : color.new(color.gray, 70)
plot(showHTFLineInput and useHTFConfirmationInput ? followLine_htf : na, color = lineColor_htf, linewidth = 2, style = plot.style_circles, title = 'Follow Line (HTF)', offset = 0)
// Plot shapes on the bar the trade signal occurs (based on trade TF condition), placing them AT the calculated Trade TF price level.
// Use the original trade long/short conditions for plotting shapes for clarity, before plots
plotshape(longCondition_trade and showSignalsInput and not na(followLine_trade) and not na(atrValue_trade) ? followLine_trade - atrValue_trade : na, text = 'BUY', style = shape.labelup, location = location.absolute, color = color.new(color.blue, 0), textcolor = color.new(color.white, 0), offset = 0, size = size.auto)
plotshape(shortCondition_trade and showSignalsInput and not na(followLine_trade) and not na(atrValue_trade) ? followLine_trade + atrValue_trade : na, text = 'SELL', style = shape.labeldown, location = location.absolute, color = color.new(color.red, 0), textcolor = color.new(color.white, 0), offset = 0, size = size.auto)
// Plot BBands for reference if desired
// plot(BBUpper_trade, "Upper BB", color=color.gray)
// plot(BBLower_trade, "Lower BB", color=color.gray)