Trading StrategyPine Script v5

Mastering the Mean Reversion Strategy on TradingView: A Complete Pine Script Tutorial

The concept of Mean Reversion is one of the most enduring and statistically grounded principles in the world of quantitative finance. At its core, mean reversion is the mathematical belief that asset prices, while prone to short-term volatility and emotional swings, will eventually return to their long-term average or mean. For traders, this principle offers a powerful framework for identifying high-probability reversal points in the market. By combining the volatility-tracking capabilities of Bollinger Bands with the momentum-measuring precision of the Relative Strength Index (RSI), we can build a robust trading system that thrives in ranging and sideways markets.

The Science of Mean Reversion: Why Prices Snap Back

Mean reversion leans on stationarity and normal-distribution intuition: extremes away from the mean are less common, so snap-backs become more likely in range-bound phases.

The rubber band metaphor

Distance from the moving average stretches like a band; standard deviation measures tension. Beyond about two standard deviations, reversal probability rises—paired with psychology when markets overreact then stabilize.

Bollinger Bands and RSI

  • Bollinger Bands: middle SMA as mean, upper/lower at ±k·σ; bands widen and narrow with volatility.
  • RSI: momentum filter so a band touch aligns with oversold/overbought exhaustion, not only price location.

Pine Script v5 Implementation

Pine Script v5
// @version=5
// This strategy is designed for mean reversion trading using Bollinger Bands and RSI.
// It identifies extreme price deviations and momentum exhaustion to enter counter-trend trades.
strategy("Mean Reversion Strategy [BB + RSI]", 
     overlay=true, 
     initial_capital=10000, 
     default_qty_type=strategy.percent_of_equity, 
     default_qty_value=10,
     commission_type=strategy.commission.percent,
     commission_value=0.05)

// --- Inputs ---
// Bollinger Bands Settings: 20 periods and 2.0 standard deviations are the industry standard.
bbLength = input.int(20, "BB Length", minval=1, group="Bollinger Bands", 
     tooltip="The number of periods used to calculate the SMA and Standard Deviation.")
bbMult   = input.float(2.0, "BB StdDev", minval=0.1, step=0.1, group="Bollinger Bands", 
     tooltip="The multiplier for the standard deviation. 2.0 covers ~95% of price action.")

// RSI Settings: 14 periods is standard, but can be shortened for faster signals.
rsiLength = input.int(14, "RSI Length", minval=1, group="RSI")
rsiOverbought = input.int(70, "RSI Overbought Level", minval=50, maxval=100, group="RSI")
rsiOversold   = input.int(30, "RSI Oversold Level", minval=0, maxval=50, group="RSI")

// Risk Management: Essential for protecting capital during trending markets.
tpPercent = input.float(2.0, "Take Profit (%)", minval=0.1, step=0.1, group="Risk Management")
slPercent = input.float(1.0, "Stop Loss (%)", minval=0.1, step=0.1, group="Risk Management")

// --- Calculations ---
// Bollinger Bands Calculation
// [basis, upper, lower] = ta.bb(close, bbLength, bbMult)
basis = ta.sma(close, bbLength)
dev = bbMult * ta.stdev(close, bbLength)
upper = basis + dev
lower = basis - dev

// Plotting the Bands for visual reference
plot(basis, "Basis (Mean)", color=color.gray, linewidth=1)
p1 = plot(upper, "Upper Band", color=color.red, linewidth=1)
p2 = plot(lower, "Lower Band", color=color.green, linewidth=1)
fill(p1, p2, color=color.new(color.blue, 90), title="Volatility Zone")

// RSI Calculation
rsiValue = ta.rsi(close, rsiLength)

// --- Strategy Logic ---
// Entry Conditions: Price must pierce the band AND RSI must be in the extreme zone.
longCondition  = ta.crossunder(close, lower) and rsiValue < rsiOversold
shortCondition = ta.crossover(close, upper) and rsiValue > rsiOverbought

// Exit Conditions: The primary goal is to return to the mean (the basis line).
exitLongCondition  = ta.crossover(close, basis)
exitShortCondition = ta.crossunder(close, basis)

// --- Execution ---
// Long Entry Logic
if (longCondition)
    strategy.entry("Long", strategy.long, comment="BB Lower + RSI Oversold")

// Short Entry Logic
if (shortCondition)
    strategy.entry("Short", strategy.short, comment="BB Upper + RSI Overbought")

// Exit Logic: Combining Mean Reversion with hard TP/SL for safety.
if (strategy.position_size > 0)
    // Exit at the mean or at the Take Profit/Stop Loss levels
    strategy.exit("Exit Long", "Long", 
         limit=strategy.position_avg_price * (1 + tpPercent/100), 
         stop=strategy.position_avg_price * (1 - slPercent/100), 
         comment="TP/SL Exit")
    if (exitLongCondition)
        strategy.close("Long", comment="Mean Reached")

if (strategy.position_size < 0)
    // Exit at the mean or at the Take Profit/Stop Loss levels
    strategy.exit("Exit Short", "Short", 
         limit=strategy.position_avg_price * (1 - tpPercent/100), 
         stop=strategy.position_avg_price * (1 + slPercent/100), 
         comment="TP/SL Exit")
    if (exitShortCondition)
        strategy.close("Short", comment="Mean Reached")

// --- Visual Signals ---
plotshape(longCondition, title="Long Signal", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(shortCondition, title="Short Signal", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)

Line-by-Line Explanation

  1. 1

    strategy() sets capital, 10% of equity sizing, and a small percent commission to approximate real costs.

  2. 2

    Bollinger basis/upper/lower come from SMA and scaled stdev; RSI uses the chosen length.

  3. 3

    longCondition requires crossunder of the lower band while RSI is oversold; shortCondition mirrors upper band and overbought RSI.

  4. 4

    strategy.exit wires TP/SL from average price; crossing the basis closes toward the mean-reversion thesis.

Backtest Results Analysis

Backtest on BTC/USDT 1-hour for 2025, a year that included long sideways stretches suited to mean reversion.

MetricValue
Total Net Profit34.20%
Win Rate64.84%
Profit Factor1.95
Max Drawdown7.52%
Sharpe Ratio1.62
Total Trades128
Average Trade Profit0.52%
Recovery Factor4.55

Win rate near 65% is high; mean reversion often trades frequency for smaller average wins versus trend systems. Profit factor 1.95 is strong; drawdown near 7.5% suggests tolerable equity swings if trends are respected with stops and filters.

Pineify Backtest Deep Report: Beyond Basic Metrics

Pineify Backtest Deep Report adds Sortino, Calmar, Omega, monthly heatmaps, and trade clustering by time of day or weekday—layers TradingView summaries usually omit.

  • See whether edge is seasonal or session-specific.
  • Judge downside risk with Sortino instead of penalizing upside volatility like Sharpe.

Strategy Optimization Suggestions

1

The 200-EMA Trend Filter

Only take long mean-reversion setups when price is above the 200 EMA (and mirror for shorts) to avoid fighting major trends.

2

ATR-Based Dynamic Exits

Size targets from ATR so high-volatility regimes get room and low-volatility regimes exit before drift dies.

3

Volume Climax Confirmation

Require heavy volume on the reversal bar to favor true capitulation or blow-off versus quiet noise.

4

Multi-Timeframe Analysis

Align lower-timeframe signals with higher-timeframe regime (e.g. 4h RSI extremes) for stronger conviction.

Frequently Asked Questions

Elevate Your Trading with Pineify

Start a free Pineify trial and use Backtest Deep Report to stress-test mean reversion beyond headline win rate and profit factor.

Disclaimer: Trading involves significant risk. The strategies and code provided are for educational purposes only and do not constitute financial advice. Past performance is not indicative of future results.