
La stratégie de suivi des tendances dynamiques Brinbelt et ATR est un système de trading quantitatif avancé qui combine les fonctionnalités d’ajustement dynamique des signaux de rupture de Brinbelt et de la plage de fluctuation réelle moyenne (ATR) pour identifier et suivre les tendances du marché via le mécanisme de “ligne de suivi” (Follow Line). La stratégie introduit en particulier le mécanisme de confirmation multi-temps (HTF), capable de filtrer les signaux de trading en fonction de la direction de la tendance des périodes de temps plus élevées, ce qui améliore considérablement la stabilité et la rentabilité de la stratégie. Le système comprend également de nombreuses fonctionnalités avancées telles que le filtrage des périodes de négociation optionnelles, l’ajustement automatique des taux d’oscillation ATR et le mécanisme de réponse en temps réel aux changements de tendance HTF, formant une solution de trading quantitatif complète et flexible.
Au cœur de cette stratégie se trouve le mécanisme de “trace des lignes”, qui identifie et s’adapte dynamiquement aux tendances du marché en suivant les étapes suivantes:
Génération du signal de la bande de BrynLe système calcule d’abord les bandes de Bollinger standard, produisant un signal positif lorsque le prix franchit la trajectoire ascendante, un signal négatif lorsque le prix franchit la trajectoire descendante, et un signal négatif lorsque le prix est à l’intérieur de la bande.
Calcul de la ligne de suivi: En fonction du signal de la ceinture de Brin et de la position actuelle des prix, le système calcule la valeur de la ligne de suivi temporaire. Dans le cas d’un signal de hausse, la ligne de suivi est définie comme le point bas de la ligne K actuelle moins l’ATR (lorsque le filtre ATR est activé) ou utilise directement le point bas. Dans le cas d’un signal de baisse, la ligne de suivi est définie comme le point haut de la ligne K actuelle plus l’ATR ou utilise directement le point haut.
Mécanisme de verrouillage des lignes de suivi: la stratégie utilise la logique de la “roue de l’épine” pour maintenir la courbe de suivi dans une tendance à la hausse, la nouvelle valeur de la ligne de suivi est prise comme une valeur temporaire par rapport à la plus grande valeur de la précédente; dans une tendance à la baisse, la valeur temporaire est prise par rapport à la plus petite valeur de la précédente. Cela garantit que la ligne de suivi ne peut se déplacer que dans la direction de la tendance, formant un niveau de soutien / résistance dynamique.
La tendance est établie: En comparant la ligne de suivi actuelle avec la valeur de la ligne de suivi précédente, le système détermine la direction de la tendance. La montée indique une tendance à plusieurs têtes (); la baisse indique une tendance à la tête vide (<-1) et le maintien de la tendance précédente.
Analyse de plusieurs périodesLa stratégie utilise une logique similaire pour calculer les lignes de suivi et l’état de la tendance sur des périodes plus longues, en choisissant automatiquement ou manuellement les périodes plus longues appropriées (par exemple, 1 minute correspond automatiquement à 15 minutes HTF).
Conditions d’entrée: génère un signal de plus lorsque la tendance du cadre de temps de négociation est passée de neutre ou à la baisse à la hausse et que le HTF confirme la tendance à la hausse; au contraire, génère un signal de moins.
Conditions de jeu: La stratégie de liquidation de position existante lorsque la tendance du cadre de temps de négociation change de direction ou que la tendance du HTF change de direction (nouveau ajout de la version v2.5)
Filtre par tempsOption: Option permettant d’effectuer une transaction uniquement pendant une période spécifique (comme les heures normales de négociation des actions américaines 0930-1600).
Une grande capacité d’adaptation: Le mécanisme de ligne de suivi est capable de s’adapter automatiquement à la volatilité du marché, en particulier lorsque le filtrage ATR est activé, offrant une adaptabilité dynamique à différents environnements de volatilité.
Mécanisme de reconnaissance des tendances: la fonction de confirmation multi-cadres temporels filtre efficacement les transactions “bruyantes” et ne les effectue que lorsque la direction de la tendance HTF est cohérente, améliorant considérablement la qualité du signal.
Des options de configuration flexiblesLes stratégies offrent une large gamme de paramètres, y compris les cycles et les déviations des bandes de Bryn, les cycles ATR, les filtres temporels et les méthodes de sélection HTF, qui peuvent être optimisés en fonction des différents marchés et types de transactions.
Très réactif: Le nouveau mécanisme de réponse aux changements de tendance HTF de la version 2.5 permet à la stratégie de réagir plus rapidement aux changements de tendance majeurs, d’arrêter les pertes en temps opportun et d’éviter les retraits graves.
Aide visuelleStratégie: tracer les lignes de suivi de l’horizon et du HTF sur le graphique et afficher les balises de signaux d’achat et de vente de manière sélective pour rendre la logique des transactions intuitive.
Gestion des positions: Le réglage pyramiding=0 empêche l’accès multiple dans la même direction, évitant ainsi une accumulation inutile de risques.
Risque de fausse percée: Malgré l’utilisation de confirmations en bandes de Brin et en HTF, il est possible que le marché produise de fausses percées, en particulier dans un environnement à forte volatilité. Solution: Il est possible d’augmenter les valeurs de déviation en bandes de Brin ou de prolonger le cycle de confirmation, voire d’ajouter un mécanisme de confirmation de percée supplémentaire.
Paramètre SensibilitéLes performances stratégiques sont sensibles aux paramètres tels que le cycle ATR, les réglages des bandes de Bryn. La solution: il convient de trouver la combinaison de paramètres la plus appropriée pour une variété de transactions particulière en faisant des retours, afin d’éviter les problèmes de correspondance de la courbe causés par une optimisation excessive.
Le changement de tendance est en retard: Les mécanismes de suivi des lignes peuvent être plus lents à réagir au début d’une tendance, ce qui entraîne une entrée plus tardive. Solution: Vous pouvez envisager d’utiliser un plus petit nombre d’ATR ou un cycle de Bryn pour améliorer la vitesse de réponse, mais en équilibrant la qualité du signal et la réactivité.
Dépendance du cadre temporelUne mauvaise sélection de l’HTF peut entraîner des filtres excessifs ou des conflits de signaux. Solution: Utilisation de la fonction de sélection automatique de l’HTF, qui sélectionne automatiquement le cadre de temps supérieur approprié en fonction du cadre de temps du graphique actuel.
Manque de gestion des fonds: La stratégie ne contient pas de mécanisme de gestion de fonds complet. Solution: Dans la pratique, une stratégie de stop-loss appropriée doit être combinée avec des règles de gestion de position, telles que des stop-loss pour un risque de pourcentage fixe ou des multiples ATR.
Filtrage des signaux améliorésIl est possible d’envisager d’introduire d’autres indicateurs techniques, tels que l’indicateur relativement faible ((RSI) ou l’indicateur aléatoire ((Stochastic) pour confirmer les signaux d’entrée, et d’exécuter la transaction uniquement lorsque l’indicateur affiche un état de survente/survente. Cela réduira encore plus les faux signaux de rupture et augmentera le taux de victoire.
Ajustement des paramètres dynamiquesIl est possible de développer des mécanismes d’ajustement des paramètres d’adaptation basés sur l’état du marché, tels que l’augmentation automatique de l’écart des bandes de Bryn dans un environnement à forte volatilité et la réduction de l’écart dans un environnement à faible volatilité, afin que la stratégie puisse mieux s’adapter aux différentes conditions du marché.
Optimiser les jugements de tendance HTFIl est possible d’améliorer les algorithmes de confirmation de tendance de l’HTF, par exemple en introduisant des indices de croisement de moyennes mobiles ou d’autres indicateurs de tendance, plutôt que de s’appuyer uniquement sur la direction de la ligne de suivi, pour obtenir des jugements de tendance plus stables.
Améliorer la gestion des fondsL’intégration d’un système de gestion de fonds complet qui ajuste dynamiquement la taille des positions en fonction de la volatilité du marché et de la taille du compte, définit des objectifs de stop loss et de profit basés sur l’ATR et maximise le rendement après ajustement du risque.
Ajout d’une analyse du marchéIntroduction d’une classification des environnements de marché, qui distingue les marchés tendance et les marchés oscillant, et qui ajuste automatiquement les paramètres de la stratégie ou les règles de négociation en fonction de l’état du marché, voire suspend la négociation dans des environnements de marché qui ne conviennent pas à la stratégie.
Intégration de plusieurs stratégies: La stratégie est utilisée comme un composant, combiné avec d’autres stratégies complémentaires (comme la stratégie de retournement ou la stratégie de confirmation de rupture) pour former une combinaison complète de stratégies qui équilibrent les performances dans différents environnements de marché.
La stratégie de suivi des tendances dynamiques Brinband et ATR est un système de négociation quantitative sophistiqué qui identifie et suit efficacement les tendances du marché en combinant la stratégie de suivi des tendances dynamiques Brinband, ATR et multi-frame. Le principal avantage de cette stratégie réside dans son adaptabilité et sa flexibilité, sa capacité à s’adapter à la dynamique des conditions du marché, tout en améliorant la qualité du signal et le taux de victoire grâce au mécanisme de confirmation HTF.
Bien que certains risques inhérents, tels que la sensibilité des paramètres et les problèmes de fausses percées, puissent être atténués par une optimisation appropriée des paramètres et des mécanismes de filtrage supplémentaires. Les orientations d’optimisation stratégique, telles que le renforcement des filtrages de signaux, l’ajustement des paramètres dynamiques et l’amélioration de la gestion des fonds, offrent une voie claire pour améliorer encore la performance de la stratégie.
Dans l’ensemble, cette stratégie est particulièrement adaptée aux traders de tendances à moyen et long terme, car elle fournit un cadre solide pour identifier les changements de tendance et exécuter des transactions dans des conditions de marché favorables. Grâce à un réglage de paramètres raisonnable et une gestion appropriée des risques, la stratégie a le potentiel de générer des rendements stables dans une variété d’environnements de marché.
/*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)