
Стратегия динамического трендового отслеживания Брин-Бенд и ATR - это передовая система количественного трейдинга, которая объединяет в себе прорывные сигналы Брин-Бенда и динамическую корректировку среднего реального колебательного диапазона (ATR), чтобы идентифицировать и отслеживать рыночные тенденции с помощью механизма “следующей линии” (FOLLOW LINE). В этой стратегии, в частности, внедрен механизм подтверждения HTF в многовременных рамках, который может фильтровать торговые сигналы в соответствии с направлением тенденции в более высоких временных рамках, что значительно улучшает стабильность и прибыльность стратегии.
В основе этой стратегии лежит механизм “следующей линии”, который динамически идентифицирует и адаптируется к рыночным тенденциям посредством следующих шагов:
Сигнал Брин-БендаСистема сначала рассчитывает стандартные Bollinger Bands, которые при прорыве цены вверх дают позитивный сигнал, а при прорыве вниз дают пассивный сигнал, а внутри полосы - нейтральный сигнал.
Расчет траектории: В зависимости от сигнала буринского пояса и текущей позиции цены, система вычисляет временную отслеживаемую линию. В случае положительного сигнала, отслеживаемая линия устанавливается как текущая низкая точка K-линии минус ATR-значение ((при включенной фильтрации ATR) или используется непосредственно низкая точка; в случае отрицательного сигнала, отслеживаемая линия устанавливается как текущая высокая точка K-линии плюс ATR-значение или используется непосредственно высокая точка.
Механизм блокировки линии слежения: Стратегия использует логику “спираль” для поддержания отслеживаемой линии в восходящем тренде, новые значения отслеживаемой линии принимаются как временные значения по сравнению с более крупными из предыдущих значений; в нисходящем тренде, принимаются как временные значения по сравнению с меньшими из предыдущих значений. Это гарантирует, что отслеживаемая линия может двигаться только в направлении тренда, образуя динамический уровень поддержки / сопротивления.
Тенденции определены: Сравнивая текущую следовую линию с предыдущей следовой линией, система определяет направление тренда: восходящий указывает на плюсовую тенденцию ((1), нисходящий - на летучую тенденцию ((-1), устойчивый - на предыдущую тенденцию。
Анализ многовременных рамок: Стратегия использует аналогичную логику для расчета линии отслеживания и состояния тренда на более высоких временных рамках, выбирая соответствующие более высокие временные рамки автоматически или вручную (например, 1 минута автоматически соответствует 15 минутам HTF).
Условия приема: Когда тренд временного рама торговли переходит от нейтрального или понижающего к повышающему и HTF подтверждает тенденцию к повышению, генерируется сигнал до плюс; наоборот, генерируется сигнал до минус.
Условия игры: когда тренд временных рамок торговли меняется в противоположном направлении, или тренд HTF меняется в противоположном направлении (в версии v2.5 добавлено), стратегия плавных позиций имеет позицию.
Фильтр времени: вы можете выбрать только в определенный торговый период (например, в обычное время торгов на американских акциях 0930-1600).
Умение адаптироваться: Механизм слежения линий может автоматически корректироваться в зависимости от волатильности рынка, особенно при включении фильтрации ATR, что обеспечивает динамическую адаптацию к различным волатильным условиям.
Механизм признания тенденций: многократное подтверждение временных рамок эффективно фильтрует “шумные” сделки, которые совершаются только при согласовании направления тренда HTF, что значительно улучшает качество сигнала.
Гибкие параметры настройки: Стратегия предлагает богатые параметры, включая циклы и отклонения в буринской полосе, циклы ATR, фильтрацию времени и методы выбора HTF, которые могут быть оптимизированы в зависимости от рынка и вида сделки.
Высокая чувствительность: В версии v2.5 добавлен новый механизм реакции на изменение тренда HTF, который позволяет стратегии быстрее реагировать на изменение большого тренда, своевременно останавливать убытки и избегать серьезных отступлений.
Визуальная помощьСтратегия: на графике нанесены временные рамки торговли и линия отслеживания HTF, а также выборочно отображены ярлыки сигналов покупки и продажи, что делает логику торговли интуитивно понятной.
Управление позициейНастройка pyramiding=0 предотвращает неоднократные входы в одном направлении, что позволяет избежать накопления ненужных рисков.
Риск ложного проникновения: Несмотря на использование подтверждения по буринской полосе и HTF, рынок может иметь ложные прорывы, особенно в условиях высокой волатильности. Решение: можно увеличить значение отклонения по буринской полосе или продлить период подтверждения, или даже добавить дополнительный механизм подтверждения прорыва.
Параметр ЧувствительностьРешение: следует найти наиболее подходящую комбинацию параметров для конкретной торговой разновидности путем обратной связи, чтобы избежать проблем с коррекцией кривой, вызванных чрезмерной оптимизацией.
Отставание от изменения тенденций: Механизм слежения линии может реагировать медленно на начальном этапе тренда, что приводит к более позднему вхождению. . Решение: можно рассмотреть возможность использования меньшего ATR-множественного числа или цикла буринского везения для повышения скорости отклика, но необходимо сбалансировать качество сигнала и отзывчивость.
Зависимость от временных рамокНеправильный выбор HTF может привести к чрезмерной фильтрации или конфликту сигналов. Решение: Рекомендуется использовать функцию автоматического выбора HTF, которая автоматически выбирает подходящий более высокий временной рамок в зависимости от текущего графического временного периода.
Отсутствие финансового управленияСтратегия сама по себе не включает в себя полный механизм управления капиталом. Решение: в практическом применении следует сочетать соответствующую стратегию прекращения убытков и правила управления позициями, такие как фиксированный процентный риск или остановка множественного ATR.
Усиление фильтрации сигнала: можно рассмотреть возможность введения других технических показателей, таких как относительно сильный индикатор ((RSI) или случайный индикатор ((Stochastic) для подтверждения входных сигналов, совершать сделки только в том случае, если индикатор показывает состояние перекупа / перепродажи. Это еще больше уменьшит ложные прорывные сигналы и повысит шансы на победу.
Изменение динамических параметров: можно разработать механизмы для самостоятельной коррекции параметров, основанных на состоянии рынка, например, для автоматического увеличения величины отклонения в полосе бурин в условиях высокой волатильности и уменьшения величины отклонения в условиях низкой волатильности, чтобы стратегия могла лучше адаптироваться к различным рыночным условиям.
Оптимизация определения трендов HTF: можно улучшить алгоритмы подтверждения трендов 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)