
Strategi Binary Belt dan ATR Trend Tracking adalah sistem perdagangan kuantitatif canggih yang menggabungkan fitur penyesuaian dinamis dari sinyal terobosan Binary Belt dan Average True Range of Volatility (ATR) untuk mengidentifikasi dan melacak tren pasar melalui mekanisme “Tracking Line” (Follow Line). Strategi ini secara khusus memperkenalkan mekanisme konfirmasi multi-frame (HTF) yang dapat memfilter sinyal perdagangan sesuai dengan arah tren dari frame waktu yang lebih tinggi, yang secara signifikan meningkatkan stabilitas dan profitabilitas strategi. Sistem ini juga mencakup beberapa fitur canggih, seperti pemfilteran periode perdagangan yang dapat dipilih, penyesuaian otomatis tingkat volatilitas ATR, dan mekanisme respons real-time terhadap perubahan tren HTF, membentuk solusi perdagangan kuantitatif yang komprehensif dan fleksibel.
Inti dari strategi ini adalah mekanisme “tracking line” yang secara dinamis mengidentifikasi dan beradaptasi dengan tren pasar melalui langkah-langkah berikut:
Pembuatan sinyal pita BrinSistem pertama kali menghitung standar Bollinger Bands, menghasilkan sinyal bullish ketika harga menerobos uptrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, menghasilkan sinyal bearish ketika harga menerobos downtrend, dan menghasilkan sinyal bearish ketika harga berada di dalam band.
Perhitungan jalur pelacakan: Berdasarkan sinyal Brin dan posisi harga saat ini, sistem menghitung nilai garis tracking sementara. Dalam kasus sinyal bullish, garis tracking diatur sebagai titik rendah K saat ini dikurangi nilai ATR ((saat menyalakan filter ATR) atau langsung menggunakan titik rendah; Dalam kasus sinyal bearish, garis tracking diatur sebagai titik tinggi K saat ini ditambah nilai ATR atau langsung menggunakan titik tinggi.
Mekanisme penguncian jalurStrategi ini menggunakan logika “putaran duri” untuk mempertahankan garis tracking. Dalam tren naik, nilai garis tracking baru diambil sebagai nilai sementara dibandingkan dengan yang lebih besar dari yang sebelumnya; dalam tren turun, diambil sebagai nilai sementara dibandingkan dengan yang lebih kecil dari yang sebelumnya. Ini memastikan bahwa garis tracking hanya dapat bergerak dalam arah tren, membentuk tingkat dukungan / resistensi yang dinamis.
Tren Terkonfirmasi: Dengan membandingkan tracking line saat ini dengan tracking line sebelumnya, sistem menentukan arah tren. Naik menunjukkan tren multihead ((1), turun menunjukkan tren kosong ((-1), dan tetap rata menunjukkan tren sebelumnya.
Analisis multi-frame waktuStrategi: Menggunakan logika serupa untuk menghitung garis pelacakan dan status tren pada kerangka waktu yang lebih tinggi, yang dapat dipilih secara otomatis atau manual untuk kerangka waktu yang lebih tinggi yang sesuai (seperti 1 menit otomatis sesuai dengan 15 menit HTF).
Syarat masuk: Ketika tren frame waktu perdagangan berubah dari netral atau turun ke atas dan HTF mengkonfirmasi tren naik, menghasilkan sinyal do lebih; sebaliknya menghasilkan sinyal do lebih.
Kondisi pertandingan: Saat tren time frame berbalik arah, atau tren HTF berbalik arah (versi v2.5 ditambahkan), strategi posisi kosong ada.
Filter waktuOpsi: Hanya melakukan transaksi dalam waktu perdagangan tertentu (seperti waktu perdagangan saham AS reguler 0930-1600).
Adaptif: Mekanisme tracking line mampu menyesuaikan otomatis sesuai dengan volatilitas pasar, terutama ketika ATR filter diaktifkan, memberikan kemampuan adaptasi dinamis untuk lingkungan tingkat fluktuasi yang berbeda.
Mekanisme pengakuan tren: Fitur konfirmasi multi-frame waktu secara efektif memfilter transaksi “noise” dan hanya melakukan transaksi jika arah tren HTF konsisten, meningkatkan kualitas sinyal secara signifikan.
Opsi konfigurasi yang fleksibelStrategi menawarkan pengaturan parameter yang kaya, termasuk siklus dan defisit Brin, siklus ATR, penyaringan waktu, dan metode pilihan HTF, yang dapat dioptimalkan sesuai dengan pasar dan varietas perdagangan yang berbeda.
ResponsifV2.5 menambahkan mekanisme reaksi perubahan tren HTF yang memungkinkan strategi untuk bereaksi lebih cepat terhadap perubahan tren besar, menghentikan kerugian tepat waktu dan menghindari penarikan balik yang serius.
Bantuan visualStrategi: Menggambar kerangka waktu perdagangan dan jalur pelacakan HTF pada grafik, dan secara opsional menampilkan label sinyal jual beli, sehingga logika perdagangan menjadi intuitif.
Manajemen PosisiDengan pengaturan pyramiding=0 untuk mencegah banyak masuk dari satu arah, risiko yang tidak perlu terakumulasi.
Risiko Penembusan PalsuMeskipun menggunakan Brinband dan HTF konfirmasi, pasar masih dapat menghasilkan false breakout, terutama dalam lingkungan volatilitas yang tinggi. Solusi: Anda dapat meningkatkan nilai defisit Brinband atau memperpanjang periode konfirmasi, atau bahkan menambahkan mekanisme konfirmasi penembusan tambahan.
Parameter SensitivitasPerforma strategi lebih sensitif terhadap parameter seperti siklus ATR, pengaturan Brin. Metode penyelesaian: Kombinasi parameter yang paling cocok untuk varietas perdagangan tertentu harus ditemukan melalui pelacakan, untuk menghindari masalah kesesuaian kurva yang disebabkan oleh pengoptimalan berlebihan.
Perubahan tren yang tertinggalMetode Solusi: Menggunakan ATR atau Brin Periode yang lebih kecil dapat dipertimbangkan untuk meningkatkan kecepatan respons, tetapi harus menyeimbangkan kualitas sinyal dan responsif.
Kerangka waktu ketergantunganSalah memilih HTF dapat menyebabkan penyaringan berlebihan atau sinyal yang bertentangan. Solusi: Disarankan untuk menggunakan fungsi pilihan otomatis HTF, yang secara otomatis memilih frame waktu yang lebih tinggi sesuai dengan frame waktu grafik saat ini.
Kegagalan dalam mengelola danaStrategi itu sendiri tidak menyertakan mekanisme pengelolaan dana yang lengkap. Solusi: Dalam aplikasi praktis, strategi stop loss yang tepat harus dikombinasikan dengan aturan manajemen posisi, seperti stop loss persentase risiko tetap atau stop loss ATR.
Filter sinyal yang diperkuatAnda dapat mempertimbangkan untuk memperkenalkan indikator teknis lainnya, seperti indikator relatif kuat (RSI) atau indikator acak (Stochastic) untuk mengkonfirmasi sinyal masuk, dan hanya melakukan perdagangan jika indikator menunjukkan status overbought / oversold. Ini akan mengurangi lebih lanjut sinyal false breakout dan meningkatkan tingkat kemenangan.
Pengaturan parameter dinamisAdaptive parameter adjustment mechanism dapat dikembangkan berdasarkan kondisi pasar, misalnya dengan meningkatkan nilai defisit Brin band secara otomatis dalam lingkungan dengan volatilitas tinggi dan mengurangi nilai defisit dalam lingkungan dengan volatilitas rendah, sehingga strategi dapat beradaptasi lebih baik dengan kondisi pasar yang berbeda.
Optimalkan penilaian tren HTF: Algoritma pengesahan tren HTF dapat ditingkatkan, seperti pengenalan indeks moving average crossover atau indikator tren lainnya, dan tidak hanya bergantung pada arah jalur pelacakan, untuk mendapatkan penilaian tren yang lebih stabil.
Manajemen Uang yang BaikTerintegrasi sistem manajemen dana yang komprehensif, ukuran posisi disesuaikan secara dinamis sesuai dengan volatilitas pasar dan skala akun, pengaturan stop loss level dan target keuntungan berdasarkan ATR, memaksimalkan pengembalian yang disesuaikan dengan risiko.
Menambahkan analisis kondisi pasar: Memperkenalkan klasifikasi lingkungan pasar, membedakan pasar tren dan pasar goyah, dan secara otomatis menyesuaikan parameter strategi atau aturan perdagangan sesuai dengan kondisi pasar, bahkan menghentikan perdagangan di lingkungan pasar yang tidak sesuai dengan strategi tersebut.
Integrasi multi-strategiStrategi ini digunakan sebagai komponen, dikombinasikan dengan strategi komplementer lainnya (seperti strategi reversal atau strategi konfirmasi terobosan) untuk membentuk kombinasi strategi yang menyeluruh yang menyeimbangkan kinerja dalam berbagai kondisi pasar.
Strategi trend tracking dinamis Brinband dan ATR adalah sistem perdagangan kuantitatif yang dirancang dengan baik yang secara efektif mengidentifikasi dan melacak tren pasar dengan menggabungkan analisis Brinband, ATR, dan multi-frame waktu. Keunggulan inti dari strategi ini adalah kemampuan beradaptasi dan fleksibilitasnya, yang dapat disesuaikan dengan dinamika kondisi pasar, sambil meningkatkan kualitas sinyal dan tingkat kemenangan melalui mekanisme konfirmasi HTF.
Meskipun ada beberapa risiko yang melekat, seperti sensitivitas parameter dan masalah false breakout, ini dapat diatasi dengan optimasi parameter yang tepat dan mekanisme penyaringan tambahan. Arah optimasi strategi, seperti penyaringan sinyal yang ditingkatkan, penyesuaian parameter dinamis, dan pengelolaan dana yang lebih baik, memberikan jalan yang jelas untuk meningkatkan kinerja strategi lebih lanjut.
Secara keseluruhan, strategi ini sangat cocok untuk pedagang tren jangka menengah dan panjang, karena memberikan kerangka kerja yang solid untuk mengidentifikasi perubahan tren dan melakukan perdagangan dalam kondisi pasar yang menguntungkan. Dengan pengaturan parameter yang masuk akal dan manajemen risiko yang tepat, strategi ini berpotensi menghasilkan keuntungan yang stabil dalam berbagai lingkungan pasar.
/*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)