← Back to Blog
STRATEGY

Bollinger Band Trading Strategy: Mean Reversion on LMEX Perpetuals

May 29, 2026 · 6 min read · LMEX.AI

Bollinger Bands are visually intuitive — a moving average sandwiched between standard deviation bands. The textbook says "buy at the lower band, sell at the upper." If only it were that easy. Used straight from the textbook, Bollinger Bands lose money on most modern markets. Used with the right additions, they're genuinely useful.


This article walks through what Bollinger Bands actually measure, the failure modes of textbook strategies, and the variations that produce real edge on crypto perpetuals.


What Bollinger Bands measure


Three lines:

  • **Middle band**: 20-period simple moving average
  • **Upper band**: middle + 2 standard deviations
  • **Lower band**: middle - 2 standard deviations

  • Standard deviation captures recent volatility. When the market is calm, bands narrow. When it's volatile, bands widen. The bands adapt automatically to changing conditions.


    The textbook interpretation:

  • Price touches upper band: overbought, expect mean reversion
  • Price touches lower band: oversold, expect mean reversion
  • Bands narrow ("squeeze"): low volatility, expect breakout
  • Bands widen: trend underway

  • Each of these has some validity. Together they don't form a complete strategy. Used in isolation, they generate losses.


    Why textbook usage fails


    Three common reasons:


    **Strong trends ride the upper or lower band.** During a sustained uptrend, price can hug the upper band for days. The "overbought" signal repeatedly fires; mean reversion never happens. Traders following the textbook short repeatedly and get destroyed by the trend.


    **Mean reversion is asymmetric.** Markets reach oversold conditions quickly (panic) but recover slowly. By the time RSI confirms a reversal, the textbook buy signal was hours ago and price has already moved.


    **The 20-period default is rarely optimal.** Modern crypto markets behave differently from 1980s stock markets where Bollinger Bands were developed. The default lookback may be too fast or too slow depending on timeframe and asset.


    What works: Bollinger squeezes for breakout trading


    The most reliable Bollinger Band signal isn't price touching a band — it's the bands themselves getting narrow.


    When bands tighten (low volatility period), a breakout often follows. The strategy:


    1. Detect when bandwidth is at its lowest in 100+ periods

    2. Wait for price to break out of the bands

    3. Trade in the direction of the breakout

    4. Exit when bands re-widen significantly


    This works because volatility is cyclical. Low-vol periods tend to be followed by high-vol periods. Catching the start of the high-vol period (the breakout) gets you in early on the new trend.


    A Python implementation:


    import pandas as pd
    import ccxt
    
    exchange = ccxt.lmex()
    
    def calculate_bollinger_bands(df, period=20, std_dev=2):
        df['middle'] = df['c'].rolling(period).mean()
        df['std'] = df['c'].rolling(period).std()
        df['upper'] = df['middle'] + std_dev * df['std']
        df['lower'] = df['middle'] - std_dev * df['std']
        df['bandwidth'] = (df['upper'] - df['lower']) / df['middle']
        return df
    
    def detect_squeeze(df, lookback=100, percentile=0.10):
        df['bandwidth_pct'] = df['bandwidth'].rolling(lookback).rank(pct=True)
        df['squeeze'] = df['bandwidth_pct'] < percentile
        return df
    
    def squeeze_breakout_signal(df):
        # Squeeze condition was true 5 bars ago
        squeezed_recently = df['squeeze'].shift(5).fillna(False)
        
        # Now broken out
        broke_up = (df['c'] > df['upper']) & (df['c'].shift() <= df['upper'].shift())
        broke_down = (df['c'] < df['lower']) & (df['c'].shift() >= df['lower'].shift())
        
        df['signal'] = 0
        df.loc[squeezed_recently & broke_up, 'signal'] = 1
        df.loc[squeezed_recently & broke_down, 'signal'] = -1
        return df

    This identifies breakouts that follow squeeze conditions — much more reliable than naive band touches.


    What works: %B for mean reversion


    %B measures where price is relative to the bands:


    %B = (close - lower band) / (upper band - lower band)

    %B of 0 means price is at the lower band. %B of 1 means at upper band. %B of 0.5 means at the middle band.


    The mean reversion signal: extreme %B values combined with a trend filter.


    def calculate_percent_b(df):
        df['pct_b'] = (df['c'] - df['lower']) / (df['upper'] - df['lower'])
        return df
    
    def mean_reversion_signal(df, trend_period=50):
        df['trend_ma'] = df['c'].rolling(trend_period).mean()
        in_uptrend = df['c'] > df['trend_ma']
        in_downtrend = df['c'] < df['trend_ma']
        
        df['signal'] = 0
        # Only fade extremes WITH the trend (not against it)
        df.loc[(df['pct_b'] < 0.1) & in_uptrend, 'signal'] = 1   # buy dips in uptrend
        df.loc[(df['pct_b'] > 0.9) & in_downtrend, 'signal'] = -1  # sell rallies in downtrend
        return df

    Buying dips during uptrends and selling rallies during downtrends is fundamentally different from naive mean reversion. You're trading WITH the trend, using Bollinger to identify good entry points.


    What works: bandwidth as a volatility filter


    Even without trading on Bollinger Bands directly, bandwidth is useful as a volatility indicator:


  • Narrow bands → low volatility → favor mean reversion strategies
  • Wide bands → high volatility → favor trend-following strategies
  • Sudden expansion → trend likely starting

  • Use bandwidth as a regime filter for other strategies. RSI mean reversion works better when bands are narrow. EMA crossover works better when bands are wide.


    Parameter tuning


    The 20-period default with 2 standard deviations is the textbook. For crypto perpetuals on different timeframes:


  • **1-hour BTC/ETH**: 20-30 period, 2 stdev. Default works reasonably.
  • **4-hour BTC/ETH**: 20 period, 2 stdev. Standard.
  • **Daily BTC/ETH**: 20 period, 2.5 stdev. Slightly wider bands for swing trading.
  • **Altcoins**: 14-20 period, 2-2.5 stdev. Adjust for higher volatility.

  • Standard deviation higher than 2.5 makes the bands too wide to be useful. Below 1.5 makes them too narrow (price is constantly outside).


    What doesn't work


    A few approaches to avoid:


    **Naive "buy lower, sell upper."** Without a trend filter, this loses money in trending markets.


    **Trading every squeeze breakout.** Many squeezes don't lead to clean trends. Filter for additional confirmation (volume, momentum direction).


    **Using Bollinger Bands as standalone stops.** The bands move with volatility, which means your stops move with volatility too. This isn't always what you want.


    **Tightening the bands aggressively.** Tighter bands generate more signals but most are noise. Stick with 2 standard deviations.


    Frequently Asked Questions


    Q: Should I use SMA or EMA for the middle band?

    SMA is the original. EMA is more responsive. SMA is more common in literature and backtests. Either works; pick one and use it consistently.


    Q: What timeframe is best for Bollinger Bands?

    1-hour to daily for swing trading. Below 15-minute, bands get too noisy. Above daily, signals are too infrequent to be useful.


    Q: Can I combine Bollinger Bands with other indicators?

    Yes, recommended. Bollinger + RSI is a classic combo. Bollinger + MACD for trend confirmation also works. Bollinger alone is incomplete.


    Q: Does %B work better than absolute band position?

    %B is just normalized band position. Same information presented differently. Some traders find %B easier to systematize because it's bounded between 0 and 1.


    Related Articles


    → RSI Mean Reversion: A Deep Dive Strategy Guide
    → EMA Crossover: A Complete Guide for Crypto Perpetuals
    → Order Book Imbalance Strategies on LMEX: A Python Implementation Guide
    ← All ArticlesBuild a Bot →