
Chiến lược theo dõi xu hướng động của Brinband và ATR là một hệ thống giao dịch định lượng tiên tiến, kết hợp các tín hiệu đột phá của Brinband và các chức năng điều chỉnh động của phạm vi biến động thực trung bình (ATR) để xác định và theo dõi xu hướng thị trường thông qua cơ chế “đường theo dõi” (Follow Line). Chiến lược này đặc biệt giới thiệu cơ chế xác nhận nhiều khung thời gian (HTF), có thể lọc tín hiệu giao dịch theo hướng xu hướng của khung thời gian cao hơn, cải thiện đáng kể sự ổn định và lợi nhuận của chiến lược. Hệ thống cũng bao gồm nhiều tính năng cao cấp, chẳng hạn như lọc giai đoạn giao dịch có thể chọn, điều chỉnh tự động tỷ lệ biến động của ATR và cơ chế phản ứng thời gian thực đối với thay đổi xu hướng HTF, tạo thành một giải pháp giao dịch định lượng toàn diện và linh hoạt.
Trung tâm của chiến lược này là cơ chế “đường dây theo dõi” (tracking line), nó nhận diện và thích ứng với xu hướng thị trường một cách động thông qua các bước sau:
Tín hiệu Brin được tạo raHệ thống đầu tiên tính các dải Bollinger Bands tiêu chuẩn, tạo ra tín hiệu lạc quan khi giá phá vỡ đường lên, tạo ra tín hiệu giảm khi phá vỡ đường xuống, và trung lập khi ở trong dải.
Tính toán đường theo dõi: Dựa trên tín hiệu vòng Brin và vị trí giá hiện tại, hệ thống tính toán giá trị đường theo dõi tạm thời. Trong trường hợp tín hiệu tăng giá, đường theo dõi được thiết lập là điểm thấp của đường K hiện tại trừ ATR ((khi bật lọc ATR) hoặc sử dụng điểm thấp trực tiếp; trong trường hợp tín hiệu giảm giá, đường theo dõi được thiết lập là điểm cao của đường K hiện tại cộng với giá trị ATR hoặc sử dụng điểm cao trực tiếp.
Cơ chế khóa đường theo dõiChiến lược sử dụng logic “vòng xoáy” để duy trì các đường theo dõi trong xu hướng tăng, các giá trị đường theo dõi mới là giá trị tạm thời so với giá trị lớn hơn trong xu hướng trước; trong xu hướng giảm, giá trị tạm thời so với giá trị nhỏ hơn trong xu hướng trước. Điều này đảm bảo rằng đường theo dõi chỉ có thể di chuyển theo hướng xu hướng, tạo thành một mức hỗ trợ / kháng cự động.
Xu hướng được xác định: Bằng cách so sánh đường theo dõi hiện tại với giá trị đường theo dõi trước đó, hệ thống xác định hướng xu hướng: tăng biểu thị xu hướng đa đầu ((1)), giảm biểu thị xu hướng không đầu ((-1), giữ nguyên xu hướng trước đó.
Phân tích nhiều khung thời gianChiến lược: Sử dụng logic tương tự để tính toán đường theo dõi và trạng thái xu hướng trên khung thời gian cao hơn, có thể chọn khung thời gian cao hơn phù hợp bằng cách tự động hoặc thủ công (ví dụ: 1 phút tự động tương ứng với 15 phút HTF).
Điều kiện nhập học: Khi xu hướng khung thời gian giao dịch chuyển từ trung tính hoặc giảm sang xu hướng tăng và HTF xác nhận xu hướng tăng, tạo ra tín hiệu đa; ngược lại tạo ra tín hiệu ngắn.
Điều kiện thi đấu: Khi xu hướng khung thời gian giao dịch thay đổi theo hướng ngược lại, hoặc xu hướng HTF thay đổi theo hướng ngược lại (được bổ sung trong phiên bản v2.5) thì chiến lược thanh toán hiện tại có vị trí.
Bộ lọc thời gian: Có thể chọn chỉ thực hiện giao dịch trong một khoảng thời gian giao dịch cụ thể ((như giờ giao dịch cổ phiếu Mỹ thông thường 0930-1600).
Khả năng thích nghi: Cơ chế theo dõi dòng có thể tự động điều chỉnh theo biến động của thị trường, đặc biệt là khi bật bộ lọc ATR, cung cấp khả năng thích ứng động cho các môi trường biến động khác nhau.
Cơ chế xác nhận xu hướng: Chức năng xác nhận khung thời gian đa dạng đã lọc hiệu quả các giao dịch “thô” và chỉ giao dịch khi xu hướng HTF phù hợp, cải thiện đáng kể chất lượng tín hiệu.
Tùy chọn cấu hình linh hoạtChiến lược cung cấp các thiết lập tham số phong phú, bao gồm chu kỳ và độ lệch của băng tần Brin, chu kỳ ATR, lọc thời gian và phương pháp chọn HTF, có thể được tối ưu hóa cho các thị trường và loại giao dịch khác nhau.
Phản ứng cao: Bản v2.5 bổ sung một cơ chế phản ứng thay đổi xu hướng HTF cho phép chiến lược phản ứng nhanh hơn với những thay đổi xu hướng lớn, ngăn chặn thiệt hại kịp thời và tránh rút lui nghiêm trọng.
Hỗ trợ hình ảnhChiến lược: Đặt khung thời gian giao dịch và đường theo dõi HTF trên biểu đồ, và tùy chọn hiển thị các thẻ tín hiệu mua bán, để logic giao dịch trở nên trực quan hơn.
Quản lý cổ phiếuThiết lập pyramiding = 0 ngăn chặn nhiều lần vào cùng một hướng, tránh sự tích lũy rủi ro không cần thiết.
Rủi ro đột phá giảMặc dù sử dụng xác nhận Brin và HTF, thị trường vẫn có thể tạo ra đột phá giả, đặc biệt là trong môi trường biến động cao. Giải pháp: Có thể tăng giá trị sai lệch Brin hoặc kéo dài chu kỳ xác nhận, thậm chí thêm cơ chế xác nhận đột phá bổ sung.
Độ nhạy tham sốPhương pháp giải quyết: Bạn nên tìm ra sự kết hợp các tham số phù hợp nhất cho một loại giao dịch cụ thể bằng cách phản hồi để tránh các vấn đề phù hợp với đường cong do tối ưu hóa quá mức.
Sự thay đổi xu hướngPhương pháp giải quyết: Bạn có thể xem xét sử dụng ATR nhỏ hoặc chu kỳ Brin để tăng tốc độ phản ứng, nhưng cần cân bằng chất lượng tín hiệu và khả năng đáp ứng.
Tùy thuộc khung thời gianPhương pháp giải quyết: Lưu ý sử dụng chức năng chọn HTF tự động, tự động chọn khung thời gian cao hơn phù hợp theo khung thời gian biểu đồ hiện tại.
Thiếu quản lý tài chínhCác chiến lược không bao gồm một cơ chế quản lý tiền hoàn chỉnh. Cách giải quyết: Trong ứng dụng thực tế, chiến lược dừng lỗ thích hợp và các quy tắc quản lý vị trí, chẳng hạn như dừng lỗ tỷ lệ phần trăm cố định hoặc ATR.
Bộ lọc tín hiệu tăng cườngBạn có thể xem xét việc giới thiệu các chỉ số kỹ thuật khác, chẳng hạn như chỉ số tương đối yếu ((RSI) hoặc chỉ số ngẫu nhiên ((Stochastic) để xác nhận tín hiệu vào thị trường, chỉ thực hiện giao dịch khi chỉ số hiển thị trạng thái quá mua / quá bán. Điều này sẽ làm giảm thêm tín hiệu phá vỡ giả và tăng tỷ lệ thắng.
Điều chỉnh tham số động: Có thể phát triển cơ chế điều chỉnh tham số thích ứng dựa trên tình trạng thị trường, chẳng hạn như tự động tăng độ lệch vùng Brin trong môi trường biến động cao và giảm độ lệch trong môi trường biến động thấp, giúp chiến lược thích ứng tốt hơn với các điều kiện thị trường khác nhau.
Tối ưu hóa phán đoán xu hướng HTF: Có thể cải thiện các thuật toán xác nhận xu hướng của HTF, chẳng hạn như giới thiệu các đường chéo trung bình di chuyển chỉ số hoặc các chỉ số xu hướng khác, thay vì chỉ phụ thuộc vào hướng của đường theo dõi, để có được phán đoán xu hướng ổn định hơn.
Quản lý tài chínhTích hợp một hệ thống quản lý tiền toàn diện, điều chỉnh kích thước vị trí theo biến động của thị trường và kích thước tài khoản, đặt mức dừng lỗ và mục tiêu lợi nhuận dựa trên ATR, tối đa hóa lợi nhuận khi điều chỉnh rủi ro.
Thêm phân tích thị trườngTiến hành phân loại môi trường thị trường, phân biệt thị trường xu hướng và thị trường biến động, và tự động điều chỉnh các tham số chiến lược hoặc quy tắc giao dịch theo tình trạng thị trường, thậm chí tạm dừng giao dịch trong môi trường thị trường không phù hợp với chiến lược.
Tích hợp nhiều chiến lược: sử dụng chiến lược này như một thành phần, kết hợp với các chiến lược bổ sung khác (chẳng hạn như chiến lược đảo ngược hoặc chiến lược xác nhận đột phá) để tạo thành một danh mục chiến lược hoàn chỉnh, cân bằng hiệu suất trong các môi trường thị trường khác nhau.
Chiến lược theo dõi xu hướng động của Brinband và ATR là một hệ thống giao dịch định lượng được thiết kế tinh tế, nó xác định và theo dõi xu hướng thị trường một cách hiệu quả bằng cách kết hợp Brinband, ATR và phân tích nhiều khung thời gian. Ưu điểm cốt lõi của chiến lược này là khả năng thích ứng và linh hoạt, có thể điều chỉnh theo tình hình thị trường động, đồng thời nâng cao chất lượng tín hiệu và tỷ lệ thắng thông qua cơ chế xác nhận HTF.
Mặc dù có một số rủi ro vốn có, chẳng hạn như sự nhạy cảm của tham số và các vấn đề đột phá giả, nhưng chúng có thể được giảm thiểu bằng việc tối ưu hóa tham số thích hợp và các cơ chế lọc bổ sung. Các hướng tối ưu hóa chiến lược, chẳng hạn như tăng cường lọc tín hiệu, điều chỉnh tham số động và quản lý tài chính hoàn thiện, cung cấp một con đường rõ ràng để nâng cao hiệu suất chiến lược hơn nữa.
Nhìn chung, chiến lược này đặc biệt phù hợp với các nhà giao dịch xu hướng trung và dài hạn, vì nó cung cấp một khuôn khổ vững chắc để nhận ra sự thay đổi xu hướng và thực hiện giao dịch trong điều kiện thị trường thuận lợi. Với thiết lập tham số hợp lý và quản lý rủi ro thích hợp, chiến lược này có tiềm năng tạo ra lợi nhuận ổn định trong nhiều môi trường thị trường.
/*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)