
La stratégie de trading multi-indicateurs est une méthode de trading quantitative qui combine l’analyse technique des indicateurs et du comportement des prix pour capturer deux types d’opportunités de trading majeures sur le marché: les revirements de prix et les ruptures de tendance. La stratégie intègre habilement plusieurs indicateurs techniques tels que les moyennes mobiles, les indices relativement faibles (RSI), la portée réelle moyenne (ATR) et le prix moyen pondéré (VWAP), tout en introduisant un mécanisme de rupture d’intervalle d’ouverture (ORB) pour augmenter la fiabilité des signaux d’entrée. La stratégie adopte une conception de stop-loss à double objectif et dispose d’un mécanisme de gestion du risque qui ajuste automatiquement les pertes d’arrêt aux points d’équilibre.
Le principe central de la stratégie est de filtrer et de confirmer les opportunités de transactions potentiellement avantageuses en trois catégories, à travers plusieurs indicateurs:
Signaux de négociation inversés:
Signal de rupture de tendance:
Signal de rupture de l’ORB:
La stratégie utilise l’indicateur ATR pour calculer la position de stop-loss dynamique, définie par la régression du prix minimum / maximum d’une période donnée (par défaut 7) et le multiple de la valeur ATR plus ou moins (par défaut 0.5). Après l’entrée, la stratégie définit deux objectifs de stop-loss:
Lorsque le premier objectif de stop est atteint, la stratégie ajuste automatiquement le stop loss au prix d’entrée (le point d’équilibre des pertes et des pertes), protégeant ainsi efficacement les bénéfices déjà réalisés.
Signaux d’entrée diversifiésEn intégrant trois types de signaux d’entrée différents: inversion, rupture et rupture de la zone d’ouverture, la stratégie peut s’adapter à une variété d’environnements de marché, augmentant efficacement les opportunités de négociation tout en conservant une qualité de signal élevée.
Une bonne gestion des risquesLa stratégie utilise un mécanisme d’arrêt gradué, permettant de réaliser une partie des bénéfices tout en conservant des bénéfices potentiellement plus importants. Lorsque le premier objectif d’arrêt est atteint, le stop loss est automatiquement ajusté au point d’équilibre des pertes et des profits, ce qui permet de protéger le capital tout en “laissant courir les bénéfices”.
Calcul de la perte dynamique: Le calcul de la position de stop-loss est effectué à l’aide de l’indicateur ATR, ce qui permet de modifier le niveau de stop-loss en fonction de la dynamique de la volatilité du marché, afin de refléter plus précisément la situation actuelle du marché et d’éviter des paramètres de stop-loss trop serrés ou trop lâches.
Confirmation de la transaction: Introduction d’un mécanisme de confirmation de volume de transactions, en particulier dans les signaux ORB, qui exige que le volume de transactions au moment de la rupture doit dépasser un certain nombre de multiples du volume de transactions moyen sur la période d’ouverture, afin de filtrer efficacement les ruptures de mauvaise qualité.
Filtrage des tendances: Déterminer l’orientation de la tendance à long terme à l’aide de la moyenne mobile simple à 200 périodes (SMA200) pour s’assurer que la direction des transactions est cohérente avec les principales tendances et améliorer le taux de réussite des transactions
Intégration de la gestion des fondsStratégie: mécanisme de gestion de fonds intégré, limite le pourcentage de fonds utilisés pour chaque transaction (default de 50% de capital), assure une diversification des fonds et réduit le seuil de risque pour une seule transaction.
La solution: envisager d’ajouter des indicateurs prospectifs tels que la reconnaissance des modèles de comportement des prix, ou de réduire les paramètres des moyennes mobiles à plus longues périodes, afin d’améliorer la sensibilité aux changements du marché.
La solution: adopter des méthodes d’optimisation de paramètres appropriées, telles que la vérification avancée et la simulation Monte Carlo, pour éviter une optimisation excessive; ou utiliser des paramètres fixes et se concentrer sur une conception de règles plus robuste.
La solution: mettre en place un système de priorité des signaux plus strict, ou introduire des mécanismes de confirmation supplémentaires pour s’assurer que les transactions ne sont exécutées que dans des cas de forte probabilité.
La solution: envisager d’utiliser une stratégie de couverture d’options, ou d’augmenter la distance de rupture dans des conditions de marché très volatiles, voire de réduire temporairement la taille de la position.
La solution: mettre en place un contrôle global des risques, limiter la taille des positions globales ou diversifier les transactions entre les différentes catégories d’actifs pour réduire les risques associés.
Justification de l’optimisation: les combinaisons d’indicateurs à poids fixe traditionnelles ont du mal à s’adapter aux différentes phases du marché, tandis que l’apprentissage automatique peut apprendre automatiquement le modèle de combinaison d’indicateurs optimal à partir des données historiques.
Motifs d’optimisation: l’humeur du marché a une influence significative sur les mouvements de prix à court terme. L’intégration de ces indicateurs permet de capturer les points de retournement du marché à l’avance et d’optimiser les moments d’entrée et de sortie.
Justification de l’optimisation: la rentabilité du risque fixe peut ne pas être suffisamment flexible dans différents environnements de marché, l’ajustement dynamique peut permettre de fixer des objectifs plus éloignés dans les marchés à forte volatilité et plus conservateurs dans les marchés à faible volatilité.
Motifs d’optimisation: l’activité du marché présente des variations significatives à différents moments de la journée, et le filtrage des heures peut aider la stratégie à se concentrer sur les heures de négociation les plus avantageuses.
Motifs d’optimisation: le risque est directement lié à la volatilité du marché, la gestion dynamique des positions permet de maintenir un niveau de risque plus cohérent et d’améliorer les rendements après ajustement du risque à long terme.
La stratégie de trading multi-indicateurs est un système de trading quantitatif intégré qui intègre plusieurs méthodes d’analyse technique. Elle est conçue pour capturer les opportunités de trading dans divers environnements de marché en intégrant des signaux de revers, de rupture de tendance et de rupture d’ouverture, ainsi qu’un mécanisme de gestion des risques et de gestion des fonds.
/*backtest
start: 2025-01-01 00:00:00
end: 2025-03-31 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Reversal & Breakout Strategy with ORB", overlay=true, pyramiding=2, initial_capital=50000)
// --- Inputs ---
ema9Length = input.int(9, "9 EMA Length", minval=1)
ema20Length = input.int(20, "20 EMA Length", minval=1)
sma50Length = input.int(50, "50 SMA Length", minval=1)
sma200Length = input.int(200, "200 SMA Length", minval=1)
rsiLength = input.int(14, "RSI Length", minval=1)
rsiOverbought = input.int(70, "RSI Overbought", minval=0, maxval=100)
rsiOversold = input.int(30, "RSI Oversold", minval=0, maxval=100)
atrLength = input.int(14, "ATR Length", minval=1)
stopMulti = input.float(0.5, "Stop Loss ATR Multiplier", minval=0.1, step=0.1)
stopLookback = input.int(7, "Stop Loss Lookback", minval=1)
rr1 = input.float(0.5, "Risk:Reward Target 1", minval=0.1, step=0.1)
rr2 = input.float(1.1, "Risk:Reward Target 2", minval=0.1, step=0.1)
target1Percent = input.float(25, "Profit % Target 1", minval=0, maxval=100)
orbBars = input.int(15, "Opening Range Bars", minval=1, tooltip="Number of bars to define the opening range (e.g., 15 bars = 30 min on 2-min chart)")
volThreshold = input.float(1.5, "Volume Threshold Multiplier", minval=1.0, step=0.1, tooltip="Volume must be this multiple of the opening range average")
// --- Indicators ---
// Moving Averages
ema9 = ta.ema(close, ema9Length)
ema20 = ta.ema(close, ema20Length)
sma50 = ta.sma(close, sma50Length)
sma200 = ta.sma(close, sma200Length)
// VWAP
vwapValue = ta.vwap(close)
// RSI
rsi = ta.rsi(close, rsiLength)
// ATR
atr = ta.atr(atrLength)
// --- Opening Range Breakout ---
var float openingRangeHigh = na
var float openingRangeLow = na
var float openingRangeAvgVol = na
if bar_index < orbBars
openingRangeHigh := na
openingRangeLow := na
openingRangeAvgVol := na
else if bar_index == orbBars
openingRangeHigh := ta.highest(high, orbBars)
openingRangeLow := ta.lowest(low, orbBars)
openingRangeAvgVol := ta.sma(volume, orbBars)
orbLong = not na(openingRangeHigh) and ta.crossover(close, openingRangeHigh) and volume > openingRangeAvgVol * volThreshold
orbShort = not na(openingRangeLow) and ta.crossunder(close, openingRangeLow) and volume > openingRangeAvgVol * volThreshold
// --- Trend Detection ---
trendUp = close > sma200
trendDown = close < sma200
// --- Reversal Conditions ---
reversalLong = ta.crossover(close, sma50) and rsi < rsiOversold and close < vwapValue and trendUp
reversalShort = ta.crossunder(close, sma50) and rsi > rsiOverbought and close > vwapValue and trendDown
// --- Range Breakout Conditions ---
breakoutLong = ta.crossover(ema9, ema20) and close > vwapValue and trendUp
breakoutShort = ta.crossunder(ema9, ema20) and close < vwapValue and trendDown
// Combine conditions
longCondition = (reversalLong or breakoutLong or orbLong)
shortCondition = (reversalShort or breakoutShort or orbShort)
// --- Calculate Position Size ---
equityPerPosition = 25000.0 // $50,000 / 2 positions
positionSizeLong = math.floor(equityPerPosition / close)
positionSizeShort = math.floor(equityPerPosition / close)
// --- Stop Loss Calculation ---
longStop = ta.lowest(low, stopLookback) - (atr * stopMulti)
shortStop = ta.highest(high, stopLookback) + (atr * stopMulti)
// --- Variables to Store Trade Levels ---
var float tradeStop = na
var float tradeTarget1 = na
var float tradeTarget2 = na
var float initialPositionSize = na
var bool breakEvenSet = false // Track if stop has been moved to break-even
var float stopLevel = na // Dedicated variable for stop loss in exits
var float target1Level = na // Dedicated variable for first take profit
var float target2Level = na // Dedicated variable for second take profit
var float qtyTotal = na // Track total quantity
// --- Reset Levels Before New Trade ---
var bool newTrade = false
if longCondition or shortCondition
newTrade := true
else
newTrade := false
if strategy.position_size == 0 and newTrade
tradeStop := na
tradeTarget1 := na
tradeTarget2 := na
stopLevel := na
target1Level := na
target2Level := na
initialPositionSize := na
qtyTotal := na
breakEvenSet := false
// --- Strategy Entries ---
if longCondition and strategy.position_size == 0
strategy.entry("Long", strategy.long, qty=positionSizeLong * 2)
tradeStop := longStop
stopLevel := longStop
stopDistance = close - tradeStop
tradeTarget1 := close + (stopDistance * rr1)
tradeTarget2 := close + (stopDistance * rr2)
target1Level := tradeTarget1
target2Level := tradeTarget2
initialPositionSize := positionSizeLong * 2
qtyTotal := positionSizeLong * 2
breakEvenSet := false // Reset break-even flag
if shortCondition and strategy.position_size == 0
strategy.entry("Short", strategy.short, qty=positionSizeShort * 2)
tradeStop := shortStop
stopLevel := shortStop
stopDistance = tradeStop - close
tradeTarget1 := close - (stopDistance * rr1)
tradeTarget2 := close - (stopDistance * rr2)
target1Level := tradeTarget1
target2Level := tradeTarget2
initialPositionSize := positionSizeShort * 2
qtyTotal := positionSizeShort * 2
breakEvenSet := false // Reset break-even flag
// --- Trade Exits ---
if strategy.position_size > 0
qty_tp1 = qtyTotal * (target1Percent / 100)
qty_tp2 = qtyTotal * ((100 - target1Percent) / 100)
strategy.exit("Long Exit 1", "Long", qty=qty_tp1, stop=stopLevel, limit=target1Level)
strategy.exit("Long Exit 2", "Long", qty=qty_tp2, stop=stopLevel, limit=target2Level)
if strategy.position_size < 0
qty_tp1 = qtyTotal * (target1Percent / 100)
qty_tp2 = qtyTotal * ((100 - target1Percent) / 100)
strategy.exit("Short Exit 1", "Short", qty=qty_tp1, stop=stopLevel, limit=target1Level)
strategy.exit("Short Exit 2", "Short", qty=qty_tp2, stop=stopLevel, limit=target2Level)
// --- Move Stop to Break-even ---
if strategy.position_size != 0 and not na(initialPositionSize) and not breakEvenSet
if math.abs(strategy.position_size) < math.abs(initialPositionSize)
tradeStop := strategy.position_avg_price
stopLevel := strategy.position_avg_price
tradeTarget1 := na // Clear first target for plotting
breakEvenSet := true // Mark break-even as set
// --- Manual Close Fallback ---
if strategy.position_size > 0
if close >= target2Level or close <= stopLevel
strategy.close("Long", qty=qtyTotal, comment="Manual Close")
if strategy.position_size < 0
if close <= target2Level or close >= stopLevel
strategy.close("Short", qty=qtyTotal, comment="Manual Close")
// --- Reset Levels When No Position ---
if strategy.position_size == 0 and not newTrade
tradeStop := na
tradeTarget1 := na
tradeTarget2 := na
stopLevel := na
target1Level := na
target2Level := na
initialPositionSize := na
qtyTotal := na
breakEvenSet := false
// --- Plotting ---
plot(tradeStop, title="Stop Loss", color=color.red, linewidth=1, style=plot.style_linebr)
plot(tradeTarget1, title="Take Profit 1", color=color.green, linewidth=1, style=plot.style_linebr)
plot(tradeTarget2, title="Take Profit 2", color=color.blue, linewidth=1, style=plot.style_linebr)