Bollinger Bands Mean Reversion
Buy at lower band, sell at upper band - fade extremes.
Strategy Overview
- Type: Mean Reversion
- Indicators: Bollinger Bands (20, 2.0), RSI (14)
- Risk Level: Medium
- Assets: Single asset (BTC)
Complete Code
package main
import (
"github.com/backtesting-org/kronos-sdk/pkg/types/connector"
"github.com/backtesting-org/kronos-sdk/pkg/types/kronos"
"github.com/backtesting-org/kronos-sdk/pkg/types/strategy"
"github.com/shopspring/decimal"
)
type BollingerMeanReversion struct {
strategy.BaseStrategy
k kronos.Kronos
}
func NewBollingerMR(k kronos.Kronos) strategy.Strategy {
return &BollingerMeanReversion{k: k}
}
func (s *BollingerMeanReversion) GetSignals() ([]*strategy.Signal, error) {
btc := s.k.Asset("BTC")
bb, _ := s.k.Indicators().BollingerBands(btc, 20, 2.0)
price, _ := s.k.Market().Price(btc)
rsi, _ := s.k.Indicators().RSI(btc, 14)
// Buy at lower band with RSI confirmation
if price.LessThan(bb.Lower) && rsi.LessThan(decimal.NewFromInt(35)) {
s.k.Log().Opportunity("BB-MeanReversion", "BTC",
"Mean reversion from lower band, target middle: %s", bb.Middle)
signal := s.k.Signal(s.GetName()).
Buy(btc, connector.Binance, decimal.NewFromFloat(0.1)).
Build()
return []*strategy.Signal{signal}, nil
}
// Sell at upper band
if price.GreaterThan(bb.Upper) && rsi.GreaterThan(decimal.NewFromInt(65)) {
s.k.Log().Opportunity("BB-MeanReversion", "BTC",
"Mean reversion from upper band, target middle: %s", bb.Middle)
signal := s.k.Signal(s.GetName()).
Sell(btc, connector.Binance, decimal.NewFromFloat(0.1)).
Build()
return []*strategy.Signal{signal}, nil
}
return nil, nil
}
func (s *BollingerMeanReversion) GetName() strategy.StrategyName { return "BB-MeanReversion" }
func (s *BollingerMeanReversion) GetDescription() string { return "Bollinger Bands mean reversion" }
func (s *BollingerMeanReversion) GetRiskLevel() strategy.RiskLevel { return strategy.RiskLevelMedium }
func (s *BollingerMeanReversion) GetStrategyType() strategy.StrategyType { return strategy.StrategyTypeMeanReversion }
How It Works
- Calculate Bands: Get Bollinger Bands (20-period SMA ± 2 std dev)
- Lower Band Touch: When price < lower band and RSI < 35, buy
- Upper Band Touch: When price > upper band and RSI > 65, sell
- Target Middle: Take profit at the middle band (mean reversion)
Key Concepts
- Bollinger Bands: Measure volatility and identify extremes
- Mean Reversion: Assumes price returns to average
- RSI Confirmation: Filters false signals
- Automatic Take Profit: Exits at middle band
Backtesting
Run with:
kronos backtest
Expected characteristics:
- Moderate trade frequency
- Works best in ranging markets
- Struggles in strong trends
- Quick wins, defined exits
Improvements
Consider adding:
- Trend filter (avoid counter-trend trades)
- Band squeeze detection (potential breakouts)
- Dynamic take profit (not always middle)
- Stop loss at opposite band
Related Strategies
- RSI - Similar momentum confirmation
- MA Crossover - Opposite (trend following)