# BBRS Strategy Documentation ## Overview The BBRS (Bollinger Bands + RSI + Squeeze) Strategy is a sophisticated mean-reversion and momentum strategy that combines Bollinger Bands, RSI (Relative Strength Index), and volume analysis to identify optimal entry and exit points. The strategy adapts to different market regimes and uses volume confirmation to improve signal quality. ## Strategy Concept ### Core Philosophy - **Mean Reversion**: Capitalize on price reversals at Bollinger Band extremes - **Momentum Confirmation**: Use RSI to confirm oversold/overbought conditions - **Volume Validation**: Require volume spikes for signal confirmation - **Market Regime Adaptation**: Adjust parameters based on market conditions - **Squeeze Detection**: Identify low volatility periods before breakouts ### Key Features - **Multi-Indicator Fusion**: Combines price, volatility, momentum, and volume - **Adaptive Thresholds**: Dynamic RSI and Bollinger Band parameters - **Volume Analysis**: Volume spike detection and moving average tracking - **Market Regime Detection**: Automatic switching between trending and sideways strategies - **Squeeze Strategy**: Special handling for Bollinger Band squeeze conditions ## Algorithm Details ### Mathematical Foundation #### Bollinger Bands Calculation ``` Middle Band (SMA) = Sum(Close, period) / period Standard Deviation = sqrt(Sum((Close - SMA)²) / period) Upper Band = Middle Band + (std_dev × Standard Deviation) Lower Band = Middle Band - (std_dev × Standard Deviation) %B = (Close - Lower Band) / (Upper Band - Lower Band) Bandwidth = (Upper Band - Lower Band) / Middle Band ``` #### RSI Calculation (Wilder's Smoothing) ``` Price Change = Close - Previous Close Gain = Price Change if positive, else 0 Loss = |Price Change| if negative, else 0 Average Gain = Wilder's MA(Gain, period) Average Loss = Wilder's MA(Loss, period) RS = Average Gain / Average Loss RSI = 100 - (100 / (1 + RS)) ``` #### Volume Analysis ``` Volume MA = Simple MA(Volume, volume_ma_period) Volume Spike = Current Volume > (Volume MA × spike_threshold) Volume Ratio = Current Volume / Volume MA ``` ## Process Flow Diagram ``` Data Input (OHLCV) ↓ TimeframeAggregator ↓ [15min aggregated data] ↓ ┌─────────────────────────────────────────────────────┐ │ BBRS Strategy │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Bollinger Bands │ │ RSI │ │ │ │ │ │ │ │ │ │ • Upper Band │ │ • RSI Value │ │ │ │ • Middle Band │ │ • Overbought │ │ │ │ • Lower Band │ │ • Oversold │ │ │ │ • %B Indicator │ │ • Momentum │ │ │ │ • Bandwidth │ │ │ │ │ └─────────────────┘ └─────────────────┘ │ │ ↓ ↓ │ │ ┌─────────────────────────────────────────────────┐│ │ │ Volume Analysis ││ │ │ ││ │ │ • Volume Moving Average ││ │ │ • Volume Spike Detection ││ │ │ • Volume Ratio Calculation ││ │ └─────────────────────────────────────────────────┘│ │ ↓ │ │ ┌─────────────────────────────────────────────────┐│ │ │ Market Regime Detection ││ │ │ ││ │ │ if bandwidth < squeeze_threshold: ││ │ │ regime = "SQUEEZE" ││ │ │ elif trending_conditions: ││ │ │ regime = "TRENDING" ││ │ │ else: ││ │ │ regime = "SIDEWAYS" ││ │ └─────────────────────────────────────────────────┘│ │ ↓ │ │ ┌─────────────────────────────────────────────────┐│ │ │ Signal Generation ││ │ │ ││ │ │ TRENDING Market: ││ │ │ • Price < Lower Band + RSI < 50 + Volume Spike ││ │ │ ││ │ │ SIDEWAYS Market: ││ │ │ • Price ≤ Lower Band + RSI ≤ 30 ││ │ │ ││ │ │ SQUEEZE Market: ││ │ │ • Wait for breakout + Volume confirmation ││ │ └─────────────────────────────────────────────────┘│ └─────────────────────────────────────────────────────┘ ↓ IncStrategySignal ↓ Trader Execution ``` ## Implementation Architecture ### Class Hierarchy ``` IncStrategyBase ↓ BBRSStrategy ├── TimeframeAggregator (inherited) ├── BollingerBandsState ├── RSIState ├── MovingAverageState (Volume MA) ├── Market Regime Logic └── Signal Generation Logic ``` ### Key Components #### 1. Bollinger Bands Analysis ```python class BollingerBandsState: def __init__(self, period: int, std_dev: float): self.period = period self.std_dev = std_dev self.sma = MovingAverageState(period) self.price_history = deque(maxlen=period) def update(self, price: float): self.sma.update(price) self.price_history.append(price) def get_bands(self) -> tuple: if not self.is_ready(): return None, None, None middle = self.sma.get_value() std = self._calculate_std() upper = middle + (self.std_dev * std) lower = middle - (self.std_dev * std) return upper, middle, lower def get_percent_b(self, price: float) -> float: upper, middle, lower = self.get_bands() if upper == lower: return 0.5 return (price - lower) / (upper - lower) def is_squeeze(self, threshold: float = 0.1) -> bool: upper, middle, lower = self.get_bands() bandwidth = (upper - lower) / middle return bandwidth < threshold ``` #### 2. RSI Analysis ```python class RSIState: def __init__(self, period: int): self.period = period self.gains = deque(maxlen=period) self.losses = deque(maxlen=period) self.avg_gain = 0.0 self.avg_loss = 0.0 self.previous_close = None def update(self, price: float): if self.previous_close is not None: change = price - self.previous_close gain = max(change, 0) loss = max(-change, 0) # Wilder's smoothing if len(self.gains) == self.period: self.avg_gain = (self.avg_gain * (self.period - 1) + gain) / self.period self.avg_loss = (self.avg_loss * (self.period - 1) + loss) / self.period else: self.gains.append(gain) self.losses.append(loss) if len(self.gains) == self.period: self.avg_gain = sum(self.gains) / self.period self.avg_loss = sum(self.losses) / self.period self.previous_close = price def get_value(self) -> float: if self.avg_loss == 0: return 100 rs = self.avg_gain / self.avg_loss return 100 - (100 / (1 + rs)) ``` #### 3. Market Regime Detection ```python def _detect_market_regime(self) -> str: """Detect current market regime.""" # Check for Bollinger Band squeeze if self.bb.is_squeeze(threshold=0.1): return "SQUEEZE" # Check for trending conditions bb_bandwidth = self.bb.get_bandwidth() rsi_value = self.rsi.get_value() # Trending market indicators if (bb_bandwidth > 0.15 and # Wide bands (rsi_value > 70 or rsi_value < 30)): # Strong momentum return "TRENDING" # Default to sideways return "SIDEWAYS" ``` #### 4. Signal Generation Process ```python def _process_aggregated_data(self, timestamp: int, ohlcv: tuple) -> IncStrategySignal: open_price, high, low, close, volume = ohlcv # Update all indicators self.bb.update(close) self.rsi.update(close) self.volume_ma.update(volume) # Check if indicators are ready if not all([self.bb.is_ready(), self.rsi.is_ready(), self.volume_ma.is_ready()]): return IncStrategySignal.HOLD() # Detect market regime regime = self._detect_market_regime() # Get indicator values upper, middle, lower = self.bb.get_bands() rsi_value = self.rsi.get_value() percent_b = self.bb.get_percent_b(close) volume_spike = volume > (self.volume_ma.get_value() * self.params['volume_spike_threshold']) # Generate signals based on regime if regime == "TRENDING": return self._generate_trending_signal(close, rsi_value, percent_b, volume_spike, lower, upper) elif regime == "SIDEWAYS": return self._generate_sideways_signal(close, rsi_value, percent_b, lower, upper) elif regime == "SQUEEZE": return self._generate_squeeze_signal(close, rsi_value, percent_b, volume_spike, lower, upper) return IncStrategySignal.HOLD() ``` ## Configuration Parameters ### Default Parameters ```python default_params = { "timeframe": "15min", # Data aggregation timeframe "bb_period": 20, # Bollinger Bands period "bb_std": 2.0, # Bollinger Bands standard deviation "rsi_period": 14, # RSI calculation period "rsi_overbought": 70, # RSI overbought threshold "rsi_oversold": 30, # RSI oversold threshold "volume_ma_period": 20, # Volume moving average period "volume_spike_threshold": 1.5, # Volume spike multiplier "squeeze_threshold": 0.1, # Bollinger Band squeeze threshold "trending_rsi_threshold": [30, 70], # RSI thresholds for trending market "sideways_rsi_threshold": [25, 75] # RSI thresholds for sideways market } ``` ### Parameter Descriptions | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `timeframe` | str | "15min" | Data aggregation timeframe | | `bb_period` | int | 20 | Bollinger Bands calculation period | | `bb_std` | float | 2.0 | Standard deviation multiplier for bands | | `rsi_period` | int | 14 | RSI calculation period | | `rsi_overbought` | float | 70 | RSI overbought threshold | | `rsi_oversold` | float | 30 | RSI oversold threshold | | `volume_ma_period` | int | 20 | Volume moving average period | | `volume_spike_threshold` | float | 1.5 | Volume spike detection multiplier | | `squeeze_threshold` | float | 0.1 | Bollinger Band squeeze detection threshold | ### Parameter Optimization Ranges ```python optimization_ranges = { "bb_period": [15, 20, 25, 30], "bb_std": [1.5, 2.0, 2.5, 3.0], "rsi_period": [10, 14, 18, 21], "rsi_overbought": [65, 70, 75, 80], "rsi_oversold": [20, 25, 30, 35], "volume_spike_threshold": [1.2, 1.5, 2.0, 2.5], "squeeze_threshold": [0.05, 0.1, 0.15, 0.2], "timeframe": ["5min", "15min", "30min", "1h"] } ``` ## Signal Generation Logic ### Market Regime Strategies #### 1. Trending Market Strategy **Entry Conditions:** - Price < Lower Bollinger Band - RSI < 50 (momentum confirmation) - Volume > 1.5× Volume MA (volume spike) - %B < 0 (price below lower band) **Exit Conditions:** - Price > Upper Bollinger Band - RSI > 70 (overbought) - %B > 1.0 (price above upper band) #### 2. Sideways Market Strategy **Entry Conditions:** - Price ≤ Lower Bollinger Band - RSI ≤ 30 (oversold) - %B ≤ 0.2 (near lower band) **Exit Conditions:** - Price ≥ Upper Bollinger Band - RSI ≥ 70 (overbought) - %B ≥ 0.8 (near upper band) #### 3. Squeeze Strategy **Entry Conditions:** - Bollinger Band squeeze detected (bandwidth < threshold) - Price breaks above/below middle band - Volume spike confirmation - RSI momentum alignment **Exit Conditions:** - Bollinger Bands expand significantly - Price reaches opposite band - Volume dies down ### Signal Confidence Calculation ```python def _calculate_confidence(self, regime: str, conditions_met: list) -> float: """Calculate signal confidence based on conditions met.""" base_confidence = { "TRENDING": 0.7, "SIDEWAYS": 0.8, "SQUEEZE": 0.9 } # Adjust based on conditions met condition_bonus = len([c for c in conditions_met if c]) * 0.05 return min(1.0, base_confidence[regime] + condition_bonus) ``` ### Signal Metadata Each signal includes comprehensive metadata: ```python metadata = { 'regime': 'TRENDING', # Market regime 'bb_percent_b': 0.15, # %B indicator value 'rsi_value': 28.5, # Current RSI value 'volume_ratio': 1.8, # Volume vs MA ratio 'bb_bandwidth': 0.12, # Bollinger Band bandwidth 'upper_band': 45234.56, # Upper Bollinger Band 'middle_band': 45000.00, # Middle Bollinger Band (SMA) 'lower_band': 44765.44, # Lower Bollinger Band 'volume_spike': True, # Volume spike detected 'squeeze_detected': False, # Bollinger Band squeeze 'conditions_met': ['price_below_lower', 'rsi_oversold', 'volume_spike'], 'timestamp': 1640995200000 # Signal generation timestamp } ``` ## Performance Characteristics ### Strengths 1. **Mean Reversion Accuracy**: High success rate in ranging markets 2. **Volume Confirmation**: Reduces false signals through volume analysis 3. **Market Adaptation**: Adjusts strategy based on market regime 4. **Multi-Indicator Confirmation**: Combines price, momentum, and volume 5. **Squeeze Detection**: Identifies low volatility breakout opportunities ### Weaknesses 1. **Trending Markets**: May struggle in strong trending conditions 2. **Whipsaws**: Vulnerable to false breakouts in volatile conditions 3. **Parameter Sensitivity**: Performance depends on proper parameter tuning 4. **Lag**: Multiple confirmations can delay entry points ### Optimal Market Conditions - **Ranging Markets**: Best performance in sideways trading ranges - **Moderate Volatility**: Works well with normal volatility levels - **Sufficient Volume**: Requires adequate volume for confirmation - **Clear Support/Resistance**: Performs best with defined price levels ## Usage Examples ### Basic Usage ```python from IncrementalTrader import BBRSStrategy, IncTrader # Create strategy with default parameters strategy = BBRSStrategy("bbrs") # Create trader trader = IncTrader(strategy, initial_usd=10000) # Process data for timestamp, ohlcv in data_stream: signal = trader.process_data_point(timestamp, ohlcv) if signal.signal_type != 'HOLD': print(f"Signal: {signal.signal_type} (confidence: {signal.confidence:.2f})") print(f"Regime: {signal.metadata['regime']}") print(f"RSI: {signal.metadata['rsi_value']:.2f}") ``` ### Aggressive Configuration ```python # Aggressive parameters for active trading strategy = BBRSStrategy("bbrs_aggressive", { "timeframe": "5min", "bb_period": 15, "bb_std": 1.5, "rsi_period": 10, "rsi_overbought": 65, "rsi_oversold": 35, "volume_spike_threshold": 1.2 }) ``` ### Conservative Configuration ```python # Conservative parameters for stable signals strategy = BBRSStrategy("bbrs_conservative", { "timeframe": "1h", "bb_period": 25, "bb_std": 2.5, "rsi_period": 21, "rsi_overbought": 75, "rsi_oversold": 25, "volume_spike_threshold": 2.0 }) ``` ## Advanced Features ### Dynamic Parameter Adjustment ```python def adjust_parameters_for_volatility(self, volatility: float): """Adjust parameters based on market volatility.""" if volatility > 0.03: # High volatility self.params['bb_std'] = 2.5 # Wider bands self.params['volume_spike_threshold'] = 2.0 # Higher volume requirement elif volatility < 0.01: # Low volatility self.params['bb_std'] = 1.5 # Tighter bands self.params['volume_spike_threshold'] = 1.2 # Lower volume requirement ``` ### Multi-timeframe Analysis ```python # Combine multiple timeframes for better context strategy_5m = BBRSStrategy("bbrs_5m", {"timeframe": "5min"}) strategy_15m = BBRSStrategy("bbrs_15m", {"timeframe": "15min"}) strategy_1h = BBRSStrategy("bbrs_1h", {"timeframe": "1h"}) # Use higher timeframe for trend context, lower for entry timing ``` ### Custom Regime Detection ```python def custom_regime_detection(self, price_data: list, volume_data: list) -> str: """Custom market regime detection logic.""" # Calculate additional metrics price_volatility = np.std(price_data[-20:]) / np.mean(price_data[-20:]) volume_trend = np.polyfit(range(10), volume_data[-10:], 1)[0] # Enhanced regime logic if price_volatility < 0.01 and self.bb.is_squeeze(): return "SQUEEZE" elif price_volatility > 0.03 and volume_trend > 0: return "TRENDING" else: return "SIDEWAYS" ``` ## Backtesting Results ### Performance Metrics (Example) ``` Timeframe: 15min Period: 2024-01-01 to 2024-12-31 Initial Capital: $10,000 Total Return: 18.67% Sharpe Ratio: 1.28 Max Drawdown: -6.45% Win Rate: 62.1% Profit Factor: 1.54 Total Trades: 156 ``` ### Regime Performance Analysis ``` Performance by Market Regime: TRENDING: Return 12.3%, Win Rate 55.2%, Trades 45 SIDEWAYS: Return 24.1%, Win Rate 68.7%, Trades 89 ← Best SQUEEZE: Return 31.2%, Win Rate 71.4%, Trades 22 ← Highest ``` ## Implementation Notes ### Memory Efficiency - **Constant Memory**: O(1) memory usage for all indicators - **Efficient Calculations**: Incremental updates for all metrics - **State Management**: Minimal state storage for optimal performance ### Real-time Capability - **Low Latency**: Fast indicator updates and signal generation - **Incremental Processing**: Designed for live trading applications - **Stateful Design**: Maintains indicator state between updates ### Error Handling ```python def _process_aggregated_data(self, timestamp: int, ohlcv: tuple) -> IncStrategySignal: try: # Validate input data if not self._validate_ohlcv(ohlcv): self.logger.warning(f"Invalid OHLCV data: {ohlcv}") return IncStrategySignal.HOLD() # Validate volume data if ohlcv[4] <= 0: self.logger.warning(f"Invalid volume: {ohlcv[4]}") return IncStrategySignal.HOLD() # Process data # ... strategy logic ... except Exception as e: self.logger.error(f"Error in BBRS strategy: {e}") return IncStrategySignal.HOLD() ``` ## Troubleshooting ### Common Issues 1. **No Signals Generated** - Check if RSI thresholds are too extreme - Verify volume spike threshold is not too high - Ensure sufficient data for indicator warmup 2. **Too Many False Signals** - Increase volume spike threshold - Tighten RSI overbought/oversold levels - Use wider Bollinger Bands (higher std_dev) 3. **Missed Opportunities** - Lower volume spike threshold - Relax RSI thresholds - Use tighter Bollinger Bands ### Debug Information ```python # Enable debug logging strategy.logger.setLevel(logging.DEBUG) # Access internal state print(f"Current regime: {strategy._detect_market_regime()}") print(f"BB bands: {strategy.bb.get_bands()}") print(f"RSI value: {strategy.rsi.get_value()}") print(f"Volume ratio: {volume / strategy.volume_ma.get_value()}") print(f"Squeeze detected: {strategy.bb.is_squeeze()}") ``` ## Integration with Other Strategies ### Strategy Combination ```python # Combine BBRS with trend-following strategy bbrs_strategy = BBRSStrategy("bbrs") metatrend_strategy = MetaTrendStrategy("metatrend") # Use MetaTrend for trend direction, BBRS for entry timing def combined_signal(bbrs_signal, metatrend_signal): if metatrend_signal.signal_type == 'BUY' and bbrs_signal.signal_type == 'BUY': return IncStrategySignal.BUY(confidence=0.9) elif metatrend_signal.signal_type == 'SELL' and bbrs_signal.signal_type == 'SELL': return IncStrategySignal.SELL(confidence=0.9) return IncStrategySignal.HOLD() ``` --- *The BBRS Strategy provides sophisticated mean-reversion capabilities with market regime adaptation, making it particularly effective in ranging markets while maintaining the flexibility to adapt to different market conditions.*