
You know what? This “Bollinger Bandit” strategy is like a market sniper! 📈 It’s not the type that shoots randomly, but specifically targets “boundary violators” at Bollinger Band edges. When price acts like a naughty kid running outside the “safe zone” of Bollinger Bands, this strategy immediately strikes to catch the rebound opportunity!
Key point! The essence of this strategy is “contrarian thinking”: - Price breaks below lower band = Oversold, prepare to go long! 🚀 - Price breaks above upper band = Overbought, prepare to go short! 📉 Like a spring - the harder you compress it, the stronger it bounces back. Bollinger Bands are the visualization tool for this “spring,” with 20-day MA as the center axis and upper/lower bands as extreme positions.
What’s the most brilliant design here? Scaled take profit! Unlike traditional “one-size-fits-all” strategies, this one works like a smart merchant: - When TP1 hits, secure 50% profit first (3 points) 💰 - Hold remaining 50% for TP2 (5 points) 🎯 - If market doesn’t cooperate, 5-point stop loss provides protection 🛡️
It’s like selling spot - sell half to break even, keep the rest for better prices!
Pitfall guide incoming! 📋 - Period Selection: 20-day is classic, but adjust based on trading instrument - Multiplier Setting: 1.0 standard deviation suits most cases, try 1.5-2.0 for high-volatility instruments - SL/TP Levels: 3/5/5 configuration is conservative, try 5/8/10 for more aggressive approach
Remember: This strategy works best in ranging markets, be careful of “false breakouts” in trending conditions!
If you’re the type of trader who prefers “steady wins,” this strategy is tailor-made for you! It won’t make you rich overnight, but helps you profit steadily from market fluctuations. Like running a restaurant - not aiming for daily packed crowds, but ensuring steady customer flow every day!
/*backtest
start: 2024-08-25 00:00:00
end: 2025-01-01 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=6
strategy("Bollinger Bandit + TP Escalonado", overlay=true)
// Configuración básica
length = input.int(20, "Periodo", minval=1)
mult = input.float(1.0, "Multiplicador", minval=0.1, maxval=3.0)
source = input(close, "Fuente")
// Opción para cierre en media
close_on_ma = input.bool(true, "Cierre en Media Móvil")
// SL/TP CONFIGURABLE CON NIVELES FIJOS
use_sltp = input.bool(true, "Usar SL/TP Personalizado", group="Gestión de Riesgo")
sl_points = input.int(5, "Puntos para SL", minval=1, group="Gestión de Riesgo")
tp1_points = input.int(3, "Puntos para TP1", minval=1, group="Gestión de Riesgo")
tp2_points = input.int(5, "Puntos para TP2", minval=1, group="Gestión de Riesgo")
// MOSTRAR TEXTO DE PRECIO
show_price_text = input.bool(true, "Mostrar Precio SL/TP", group="Visualización")
// Cálculo de las Bandas de Bollinger
basis = ta.sma(source, length)
dev = mult * ta.stdev(source, length)
upper = basis + dev
lower = basis - dev
// Detección de cruces
longCondition = ta.crossover(close, lower)
shortCondition = ta.crossunder(close, upper)
// Cálculo de SL/TP con niveles FIJOS EXACTOS - CORREGIDO
var float last_sl_price = na
var float last_tp1_price = na
var float last_tp2_price = na
var int last_entry_bar = 0
var float last_entry_price = na
var bool last_is_long = false
if longCondition or shortCondition
last_entry_price := close
last_is_long := longCondition
if longCondition
// COMPRA: SL = entrada - 5 puntos, TP1 = entrada + 3 puntos, TP2 = entrada + 5 puntos
last_sl_price := last_entry_price - sl_points
last_tp1_price := last_entry_price + tp1_points
last_tp2_price := last_entry_price + tp2_points
else
// VENTA: SL = entrada + 5 puntos, TP1 = entrada - 3 puntos, TP2 = entrada - 5 puntos
last_sl_price := last_entry_price + sl_points
last_tp1_price := last_entry_price - tp1_points
last_tp2_price := last_entry_price - tp2_points
last_entry_bar := bar_index
// Entradas
if (longCondition)
strategy.entry("Long", strategy.long)
if (shortCondition)
strategy.entry("Short", strategy.short)
// DETECCIÓN DE CIERRES CON TEXTO PERSONALIZADO
var bool long_closed_by_sl = false
var bool long_closed_by_tp1 = false
var bool long_closed_by_tp2 = false
var bool short_closed_by_sl = false
var bool short_closed_by_tp1 = false
var bool short_closed_by_tp2 = false
// Para posiciones LARGAS
if (use_sltp and strategy.position_size > 0)
if low <= last_sl_price
strategy.close("Long", comment="LongSL")
long_closed_by_sl := true
else if high >= last_tp1_price and not long_closed_by_tp1
strategy.close("Long", qty_percent=50, comment="LongTP1")
long_closed_by_tp1 := true
else if high >= last_tp2_price and not long_closed_by_tp2
strategy.close("Long", comment="LongTP2")
long_closed_by_tp2 := true
else if (strategy.position_size > 0)
if (ta.crossunder(close, upper))
strategy.close("Long", comment="STOP")
if (close_on_ma and ta.crossunder(close, basis))
strategy.close("Long", comment="STOPMedia")
// Para posiciones CORTAS
if (use_sltp and strategy.position_size < 0)
if high >= last_sl_price
strategy.close("Short", comment="ShortSL")
short_closed_by_sl := true
else if low <= last_tp1_price and not short_closed_by_tp1
strategy.close("Short", qty_percent=50, comment="ShortTP1")
short_closed_by_tp1 := true
else if low <= last_tp2_price and not short_closed_by_tp2
strategy.close("Short", comment="ShortTP2")
short_closed_by_tp2 := true
else if (strategy.position_size < 0)
if (ta.crossover(close, lower))
strategy.close("Short", comment="STOP")
if (close_on_ma and ta.crossover(close, basis))
strategy.close("Short", comment="STOPMedia")
// Reset flags cuando no hay posición
if strategy.position_size == 0
long_closed_by_sl := false
long_closed_by_tp1 := false
long_closed_by_tp2 := false
short_closed_by_sl := false
short_closed_by_tp1 := false
short_closed_by_tp2 := false
// Visualización (manteniendo tus colores y estilo)
plot(basis, "Media", color=color.blue, linewidth=1)
plot(upper, "Banda Superior", color=color.orange, linewidth=2)
plot(lower, "Banda Inferior", color=color.green, linewidth=2)
// Señales de entrada
plotshape(longCondition, "↑ Compra", shape.triangleup, location.belowbar, color=color.green, size=size.tiny)
plotshape(shortCondition, "↓ Venta", shape.triangledown, location.abovebar, color=color.red, size=size.tiny)
// Relleno entre bandas (manteniendo tu estilo)
bgcolor = color.new(color.yellow,80)
fill(plot(upper), plot(lower), bgcolor)