Méta Trader 5... par Franck Chambon
Pine script pour le BOBP v2.6
//@version=5
strategy("BOPB V2.6 - Bollinger Band Breakout Strategy (RSI Long/Short)", overlay=true)
// === Sélection du type de marché ===
market_type = input.string("Forex", title="Type de marché", options=["Forex", "Crypto"])
// === Paramètres des Bollinger Bands ===
bb_length = input.int(10, title="Période des BB", minval=5, maxval=50)
bb_mult = input.float(1.8, title="Multiplicateur des BB", minval=1.0, maxval=5.0, step=0.1)
use_atr_sl = input.bool(true, title="Utiliser ATR pour SL/TP")
risk_reward_ratio = input.float(2.9, title="Ratio RR", minval=1.0, maxval=5.0, step=0.1)
// === Paramètres des EMA en fonction du marché ===
ema_short_length = market_type == "Forex" ? input.int(9, title="Longueur EMA courte (Forex)") : input.int(7, title="Longueur EMA courte (Crypto)")
ema_long_length = market_type == "Forex" ? input.int(21, title="Longueur EMA longue (Forex)") : input.int(50, title="Longueur EMA longue (Crypto)")
// === Paramètres du RSI ===
use_rsi_filter = input.bool(true, title="Utiliser RSI pour filtre")
rsi_length = input.int(20, title="Longueur RSI")
rsi_long_threshold = input.int(30, title="Seuil RSI Long")
rsi_short_threshold = input.int(63, title="Seuil RSI Short")
// === Calcul des indicateurs ===
src = close
basis = ta.sma(src, bb_length)
dev = bb_mult ta.stdev(src, bb_length)
upper_band = basis + dev
lower_band = basis - dev
ema_short = ta.ema(close, ema_short_length)
ema_long = ta.ema(close, ema_long_length)
rsi_value = ta.rsi(close, rsi_length)
// === Indicateur ATR pour SL/TP dynamiques ===
atr_length = 14
atr_value = ta.atr(atr_length)
stop_mult_atr = input.float(2.3, title="Multiplicateur Stop ATR", minval=0.5, maxval=3.0, step=0.1)
// === Filtres de volatilité ===
atr_threshold = input.float(2.0, title="Seuil de volatilité ATR", minval=0.5, maxval=5.0, step=0.1)
valid_volatility = atr_value > atr_threshold
// === Conditions d’entrée avec filtre EMA et RSI ===
buy_signal = ta.crossunder(close, lower_band) and valid_volatility and ema_short > ema_long and (not use_rsi_filter or rsi_value < rsi_long_threshold)
sell_signal = ta.crossover(close, upper_band) and valid_volatility and ema_short < ema_long and (not use_rsi_filter or rsi_value > rsi_short_threshold)
// === Définition du Stop-Loss et Take-Profit ===
sl_long = close - (stop_mult_atr atr_value)
tp_long = close + (risk_reward_ratio atr_value)
sl_short = close + (stop_mult_atr atr_value)
tp_short = close - (risk_reward_ratio * atr_value)
// === Exécution des trades ===
if buy_signal
strategy.entry("Long", strategy.long)
strategy.exit("TP/SL Long", from_entry="Long", stop=sl_long, limit=tp_long)
if sell_signal
strategy.entry("Short", strategy.short)
strategy.exit("TP/SL Short", from_entry="Short", stop=sl_short, limit=tp_short)
// === Affichage des signaux Buy/Sell seulement (sans bruit visuel) ===
plotshape(buy_signal, location=location.belowbar, color=color.green, style=shape.labelup, title="BUY Signal", size=size.small)
plotshape(sell_signal, location=location.abovebar, color=color.red, style=shape.labeldown, title="SELL Signal", size=size.small)
// === Alertes de trading ===
alertcondition(buy_signal, title="BUY Alert", message="Prix sous la bande BB et tendance haussière - Achat !")
alertcondition(sell_signal, title="SELL Alert", message="Prix au-dessus de la bande BB et tendance baissière - Vente !")
Analyse visuelle pour entrer en trade :
✅ Entrée Short :
le prix franchit la bande supérieure de Bollinger (signifiant une possible condition de surachat).
Ensuite, tu attends la confirmation avec une bougie rouge qui clôture sous la bande supérieure.
→ Cette approche est excellente, elle réduit énormément les faux signaux.
✅ Placement du SL :
Placer le Stop Loss juste au-dessus de la mèche de la bougie précédente est optimal.
Tu utilises un niveau technique logique et non pas seulement un Multiplicateur ATR arbitraire.
→ Cela protège efficacement ton capital, tout en laissant de l'espacE au trade.
✅ Take Profit (RR = 2 + suivi) :
TP initial fixé avec un RR = 2 est réaliste et optimal pour sécuriser rapidement un profit.
Ensuite, tu utilises un suivi pour maximiser davantage le gain.
→ Approche excellente pour optimiser le RR global.


//@version=5
indicator("Tableau SMB - Backtest Visuel", overlay=true)
// === INPUTS ===
emaLength = input.int(50, "EMA Length")
lookback = input.int(5, "Bougies pour moyenne volume / taille")
positionOption = input.string("Bottom Gauche", "Position du tableau", options=["Top Gauche", "Top Droite", "Bottom Droite", "Bottom Gauche"])
stochLongMax = input.float(60, "Stock RSI max si LONG")
stochShortMin = input.float(40, "Stock RSI min si SHORT")
rsiLongMin = input.float(40, "RSI min si LONG")
rsiShortMax = input.float(60, "RSI max si SHORT")
// === PERSONNALISATION GUI ===
bgColor = input.color(color.new(color.black, 50), "Couleur Fond Tableau")
textColor = input.color(color.white, "Couleur Texte Tableau")
fontSizeOption = input.string("small", "Taille Police", options=["tiny", "small", "normal", "large", "huge"])
// === LIMITES D'OVERRIDE STOCK RSI ===
stockRsiMaxLongForOverride = input.float(80, "Limite Stock RSI Override LONG (Max)")
stockRsiMinShortForOverride = input.float(20, "Limite Stock RSI Override SHORT (Min)")
// === CALCULS ===
ema = ta.ema(close, emaLength)
volumeMoy = ta.sma(volume, lookback)
hauteurBougie = high - low
grosseurMoy = ta.sma(hauteurBougie, lookback)
// === DIRECTION ===
breakoutHaut = high > high[1] and close > close[1] and close > open
breakoutBas = low < low[1] and close < close[1] and close < open
direction = breakoutHaut ? "Long" : breakoutBas ? "Short" : ""
// === INDICATEURS CORRIGÉS AVEC LISSAGE ===
rsi = ta.rsi(close, 14)
// Vrai Stock RSI brut classique
rsiMin = ta.lowest(rsi, 14)
rsiMax = ta.highest(rsi, 14)
stochRsiBrut = (rsi - rsiMin) / (rsiMax - rsiMin) * 100
// Lissage K identique à ton indicateur graphique (lissage simple de 3 périodes)
stochK = ta.sma(stochRsiBrut, 3)
// === VALIDATIONS ===
smb = breakoutHaut or breakoutBas
stockRSI_valide = (direction == "Long" and stochK <= stochLongMax) or (direction == "Short" and stochK >= stochShortMin)
rsi_valide = (direction == "Long" and rsi >= rsiLongMin) or (direction == "Short" and rsi <= rsiShortMax)
ema_valide = (direction == "Long" and close > ema) or (direction == "Short" and close < ema)
volume_valide = volume > volumeMoy
grosseur_valide = hauteurBougie > grosseurMoy
// Override corrigé avec limites
stockRSI_override = (not stockRSI_valide and volume_valide and grosseur_valide) and ((direction == "Long" and stochK <= stockRsiMaxLongForOverride) or (direction == "Short" and stochK >= stockRsiMinShortForOverride))
// === DÉCISION ===
valide_final = smb and (stockRSI_valide or stockRSI_override) and rsi_valide and ema_valide and volume_valide and grosseur_valide
// === POSITION DU TABLEAU ===
getPosition(p) =>
p == "Top Gauche" ? position.top_left : p == "Top Droite" ? position.top_right : p == "Bottom Droite" ? position.bottom_right : position.bottom_left
// === TABLEAU ===
var table t = table.new(getPosition(positionOption), 3, 10, bgcolor=bgColor, border_color=color.gray, border_width=1)
// Taille police dynamique
getFontSize() =>
fontSizeOption == "tiny" ? size.tiny :
fontSizeOption == "small" ? size.small :
fontSizeOption == "normal" ? size.normal :
fontSizeOption == "large" ? size.large : size.huge
if barstate.islast
ts = getFontSize()
table.cell(t, 0, 0, "Critère", text_color=textColor, text_size=ts)
table.cell(t, 1, 0, "Valeur numérique", text_color=textColor, text_size=ts)
table.cell(t, 2, 0, "OUI/NON", text_color=textColor, text_size=ts)
table.cell(t, 0, 1, "Actif", text_color=textColor, text_size=ts)
table.cell(t, 1, 1, str.tostring(close, format.mintick) + " $", text_color=textColor, text_size=ts)
table.cell(t, 2, 1, direction, text_color=textColor, text_size=ts)
table.cell(t, 0, 2, "SMB", text_color=textColor, text_size=ts)
table.cell(t, 1, 2, smb ? "Oui" : "Non", text_color=textColor, text_size=ts)
table.cell(t, 2, 2, smb ? "OUI" : "NON", text_color=smb ? color.green : color.red, text_size=ts)
table.cell(t, 0, 3, "Stock RSI (" + str.tostring(stochLongMax) + "/" + str.tostring(stochShortMin) + ")", text_color=textColor, text_size=ts)
table.cell(t, 1, 3, str.tostring(stochK, format.mintick), text_color=textColor, text_size=ts)
table.cell(t, 2, 3, stockRSI_valide ? "OUI" : "NON", text_color=stockRSI_valide ? color.green : color.red, text_size=ts)
table.cell(t, 0, 4, "RSI (<" + str.tostring(rsiShortMax) + "/>=" + str.tostring(rsiLongMin) + ")", text_color=textColor, text_size=ts)
table.cell(t, 1, 4, str.tostring(rsi, format.mintick), text_color=textColor, text_size=ts)
table.cell(t, 2, 4, rsi_valide ? "OUI" : "NON", text_color=rsi_valide ? color.green : color.red, text_size=ts)
table.cell(t, 0, 5, "EMA", text_color=textColor, text_size=ts)
table.cell(t, 1, 5, str.tostring(ema, format.mintick) + " $", text_color=textColor, text_size=ts)
table.cell(t, 2, 5, ema_valide ? "OUI" : "NON", text_color=ema_valide ? color.green : color.red, text_size=ts)
table.cell(t, 0, 6, "Volume", text_color=textColor, text_size=ts)
table.cell(t, 1, 6, str.tostring(volume), text_color=textColor, text_size=ts)
table.cell(t, 2, 6, volume_valide ? "OUI" : "NON", text_color=volume_valide ? color.green : color.red, text_size=ts)
table.cell(t, 0, 7, "Grosseur", text_color=textColor, text_size=ts)
table.cell(t, 1, 7, str.tostring(hauteurBougie, format.mintick), text_color=textColor, text_size=ts)
table.cell(t, 2, 7, grosseur_valide ? "OUI" : "NON", text_color=grosseur_valide ? color.green : color.red, text_size=ts)
table.cell(t, 0, 8, "Décision", text_color=textColor, text_size=ts)
table.cell(t, 1, 8, "", text_color=textColor, text_size=ts)
table.cell(t, 2, 8, valide_final ? "OUI" : "NON", text_color=valide_final ? color.green : color.red, text_size=ts)
table.cell(t, 0, 9, "Override (Volume+Grosseur)", text_color=textColor, text_size=ts)
table.cell(t, 1, 9, "", text_color=textColor, text_size=ts)
table.cell(t, 2, 9, stockRSI_override ? "OUI" : "NON", text_color=stockRSI_override ? color.green : color.red, text_size=ts)
// === LABEL TEMPORAIRE POUR VALIDATION RAPIDE ===
atrValue = ta.atr(14) // ATR standard 14 périodes
labelContent = "ATR : " + str.tostring(atrValue, format.mintick) + "\n" +
"Grosseur : " + str.tostring(hauteurBougie, format.mintick) + "\n" +
"Volume : " + str.tostring(volume, format.volume) + "\n" +
"Volume Moy : " + str.tostring(volumeMoy, format.volume)
// Efface l'ancien label avant d'en créer un nouveau
var label validationLabel = na
if barstate.islast
if not na(validationLabel)
label.delete(validationLabel)
validationLabel := label.new(bar_index, high + (atrValue * 0.5), labelContent,
color=color.new(color.white, 0),
textcolor=color.black,
style=label.style_label_down,
size=size.normal)
plot(na)



































