Roll Window Reversion
Futures contracts expire on fixed dates and must be "rolled" forward (the position closed in the expiring contract and reopened in the next contract month) by traders holding positions. This creates a predictable, compulsory trading window: in the final days before a contract expires, large position holders must trade simultaneously, draining liquidity from the front contract and generating mechanical price patterns. This strategy trades that window, entering mean-reversion trades 5-2 days before expiry and exiting at or just after the expiry date, capturing the volatility and range-bound behavior of a contract in its final days.
Why This Might Work
Contract expiration is not a market choice; it is an exchange-enforced deadline. Every futures contract has a fixed expiry date specified in the contract's rulebook [1]. Positions that are not closed (or rolled) by the stated deadline are subject to delivery or cash settlement, making the days immediately preceding expiry a forced trading window [2].
As a contract approaches expiry, two observable behaviors emerge. First, open interest (the number of contracts still open) collapses sharply. Practitioners consistently report that most of the open interest in a front contract migrates to the next contract month in the week before expiry, as traders and portfolio managers roll forward rather than take delivery or accept settlement [2]. This is not optional for large position holders.
Second, liquidity in the front contract thins. Market makers and algorithm traders typically offer better prices in the next contract month, where the position can remain open longer. The first contract becomes "sticky", buyers and sellers have fewer options and worse pricing. This is reflected in widening bid-ask spreads and less depth on both sides of the order book. The contract also becomes more volatile relative to the broader market, as the remaining volume is concentrated in fewer hands and residual orders are swept or lifted by desperate traders trying to exit before the deadline [2].
These mechanics create a behavioral pattern: in the roll window (typically days −7 to −2 before expiry), price action becomes choppy and mean-reverting. A price move that would persist on a normal day often reverses quickly, because the liquidity profile is distorted and traders exiting forced positions are less sensitive to price than usual [3]. Mean-reversion strategies, which bet that prices that move too far from their mean will snap back, perform measurably better during roll windows than outside them. This is not a psychology story; it is a mechanical consequence of mandatory, concentrated trading into a thin order book.
The win rate and profitability of this pattern depend on contract, volatility environment, and position size, but the pattern itself is solid and independent of broader market direction [3]. It is a calendar effect: it occurs on predictable dates driven by exchange rules, not by fundamental news or sentiment.
The Rules
Instrument and Timeframe E-mini S&P 500 Futures (ES), daily bars. The strategy is applicable to any liquid quarterly futures contract (ES, NQ, YM, GC, CL, etc.), but ES is the most liquid and has well-defined quarterly expirations on the 3rd Friday of March, June, September, and December.
Entry Trigger The strategy enters trades only within the roll window: 7 to 2 calendar days before the contract's expiry date. Within that window, it uses mean-reversion: it enters long when the daily close crosses above the lower Bollinger Band (20-period, 2 standard deviations), and enters short when the close crosses below the upper Bollinger Band.
Initial Stop Loss Fixed at 50 points per contract. This is ~2× the average intraday ATR on ES during normal periods and accounts for the wider volatility typical in roll weeks. Alternatively, set as a percentage of account (e.g., 0.5% per trade).
Exit Two exits: (1) take profit at 30 points per contract, or (2) time-based close of all open positions at the end of the expiry date. A trader should not carry positions through expiry into the next contract month without explicit intention and proper margin.
Position Sizing One contract per trade. Scale up only after out-of-sample testing has confirmed edge on a larger account.
Session and Time Filters Enter trades only during regular trading hours (9:30-16:00 ET for ES) to avoid low-liquidity overnight periods and to align with typical broker hours and margin availability. Do not enter trades on the expiry date itself (Friday of the 3rd week); only close out existing positions.
Expected Trade Frequency E-mini S&P 500 has 4 quarterly expirations per year (Mar, Jun, Sep, Dec). Each expiration creates a 6-trading-day window (days −7 to −2). Depending on volatility, the mean-reversion bands will trigger 2-4 times per expiration window. Expected annual frequency: 8-16 trades per year, enough for a modest statistical sample but not so frequent as to require real-time monitoring.
Pine Script v6 Implementation
strategy("Roll Window Reversion", overlay=true, default_qty_type=strategy.fixed, default_qty_value=1, commission_type=strategy.commission.percent, commission_value=0.0005, initial_capital=10000)
// User inputs
expiryYear = input(2025, "Expiry Year")
expiryMonth = input(3, "Expiry Month (1-12)")
expiryDay = input(21, "Expiry Day (3rd Friday)")
bbPeriod = input(20, "Bollinger Band Period")
bbStdDev = input(2.0, "Bollinger Band Std Dev")
stopLossPoints = input(50, "Stop Loss (points)")
takeProfitPoints = input(30, "Take Profit (points)")
// Calculate expiry timestamp (15:30 ET is ES settlement time)
expiryTimestamp = timestamp(expiryYear, expiryMonth, expiryDay, 15, 30, 0)
// Days since expiry (negative = days before expiry)
daysSinceExpiry = (time - expiryTimestamp) / (1000.0 * 60 * 60 * 24)
// Roll window: -7 to -2 days before expiry
inRollWindow = daysSinceExpiry >= -7 and daysSinceExpiry <= -2
// Bollinger Bands
sma = ta.sma(close, bbPeriod)
stdDev = ta.stdev(close, bbPeriod)
bbUpper = sma + bbStdDev * stdDev
bbLower = sma - bbStdDev * stdDev
// Mean-reversion signals (only in roll window)
longSignal = inRollWindow and ta.crossover(close, bbLower)
shortSignal = inRollWindow and ta.crossunder(close, bbUpper)
// Entries
strategy.entry("Long", strategy.long, when=longSignal)
strategy.entry("Short", strategy.short, when=shortSignal)
// Exits: take profit or stop loss
strategy.exit("LongClose", "Long", profit=takeProfitPoints, loss=stopLossPoints)
strategy.exit("ShortClose", "Short", profit=takeProfitPoints, loss=stopLossPoints)
// Force-close all positions after expiry to avoid rollover risk
if daysSinceExpiry > 0
strategy.close_all()
// Visual highlighting of roll window
bgcolor(inRollWindow ? color.new(color.yellow, 90) : na, title="Roll Window")
// Plot Bollinger Bands and SMA
plot(bbUpper, color=color.red, title="BB Upper")
plot(sma, color=color.blue, title="SMA(20)")
plot(bbLower, color=color.red, title="BB Lower")
How the Code Works
Timestamp and Days-to-Expiry Calculation
The code accepts the expiry date as three user inputs (year, month, day). It converts this to a Unix timestamp using timestamp(), then compares it to the current bar's time (time). The difference in milliseconds is converted to days via division by 1000 * 60 * 60 * 24. A negative value means the bar occurred before expiry; zero means at expiry; positive means after.
Roll Window Flag
The boolean inRollWindow is true only when daysSinceExpiry is between −7 and −2 (inclusive). This restricts entry signals to the 6-trading-day window immediately preceding the expiry date. Outside this window, no trades are initiated.
Bollinger Bands
The 20-period simple moving average (ta.sma) and 20-period standard deviation (ta.stdev) are calculated on each bar. The upper and lower bands are placed at SMA ± 2 × StdDev. These are standard technical inputs for mean-reversion systems.
Entry Signals
ta.crossover(close, bbLower) detects when the close price crosses above the lower band (a potential oversold bounce, hence a long entry). ta.crossunder(close, bbUpper) detects a cross below the upper band (overbought, hence a short entry). These crossovers only trigger if inRollWindow is true.
Exits and Risk Management
For each entry, the strategy specifies a take-profit target (30 points) and a stop loss (50 points) using strategy.exit(). The risk-reward ratio is 30:50, or roughly 0.6:1, which is conservative. The strategy also force-closes all open positions once daysSinceExpiry becomes positive (after expiry), preventing accidental rollovers into the next contract month.
Visual Aids
The roll window is highlighted with a light yellow background (bgcolor). The Bollinger Bands and SMA are plotted in red and blue, respectively, so a trader can visually confirm that entries occur at band crossovers during the highlighted window.
Testing It Honestly
A trader evaluating this strategy on TradingView should follow these steps:
-
Select a Single Contract and Year Begin with ES March 2025 (or the most recent completed quarter). Manually enter the expiry date (e.g., March 21, 2025). Run the backtest and record the number of trades, the win rate, and the total P&L.
-
In-Sample vs. Out-of-Sample The above test is in-sample: data up to the expiry date has already occurred, and overfitting (tuning parameters to fit historical noise) is a risk. To test honesty: after completing the in-sample test, advance to a new expiry date (e.g., June 20, 2025) without changing the Bollinger Band or stop-loss parameters. If the strategy's win rate and Sharpe ratio are similar, the edge may be real. If they collapse, overfitting is likely.
-
Realistic Costs The strategy assumes a 0.05% commission (typical for ES micro contracts) and uses fixed point-based stops and take-profits, which implicitly account for slippage of ~0.5 points per side. On a 50-point stop loss, this is negligible. However, traders should verify actual commission and slippage on their broker's ES contracts. IB, for example, charges ~$1.25 per contract per side, which is roughly 0.025% on a $5,000 notional trade.
-
Sample Size Eight to sixteen trades per year is a small sample. A winning trade or two more than expected by chance will double or triple the annual return; a losing trade or two will erase it. Only after testing across 4-8 quarters (16-64 trades) should a trader be confident. And even then, the next quarter or year may be a regime change (e.g., a different volatility or liquidity environment) in which the strategy fails.
-
Forward Testing (Paper Trading) After in-sample and out-of-sample backtests look promising, paper-trade the strategy for at least two full quarters of live expiry dates before risking real money. During paper trading, confirm that the signal triggers are actually hit at the prices the backtest expected.
Limitations
Regime Dependence This strategy assumes that roll weeks continue to exhibit the liquidity drain and mean-reversion behavior documented here. This assumption holds during normal market conditions but may break during crises. In March 2020, for example, ES experienced extreme volatility and forced selling that overrode normal roll-window dynamics. A trader should monitor realized volatility (historical or implied) and disable the strategy if volatility spikes above a threshold, or accept significantly larger drawdowns during stress periods.
Overfitting Risk The Bollinger Band period (20) and standard deviation (2.0), as well as the stop-loss (50 points) and take-profit (30 points) levels, are freely chosen. Different markets and volatility regimes may reward different parameters. Any backtested parameter choice is at risk of overfitting to the specific past data tested. A trader should not assume that parameters optimized on 2 years of data will work on the next 2 years.
Cost Sensitivity If actual commission, slippage, or bid-ask spread is higher than assumed (e.g., on a contract with lower volume), the 30-point take-profit target may be eroded entirely. Micro ES contracts are liquid; larger or less-liquid contracts (e.g., commodities) may face wider spreads. The strategy breaks even at a 40-point move (50-point stop, 30-point profit); actual trading costs must be subtracted from the 30-point potential.
Missing Evidence This paper makes no claim that this strategy is net-profitable. It describes a market mechanic (liquidity drain at expiry) and proposes a plausible trading rule (mean reversion during the drain). Readers should backtest it rigorously before using it. The strategy is untested as delivered and should be considered a hypothesis, not a validated system.
Calendar and Holiday Effects If a contract's expiry date falls on a holiday or a day with low volume (e.g., the day after Thanksgiving in the U.S.), the roll window may behave differently. The strategy does not account for calendar anomalies. A trader should manually inspect the week before expiry to ensure normal trading volumes.
Carry Cost Assumptions Contango (when the back contract is more expensive than the front) incentivizes rolling. Backwardation (back contract cheaper) disincentivizes rolling and may alter the forced-exit behavior. During backwardation, position holders may tolerate wider bid-ask spreads and less liquidity rather than roll at a loss. The strategy does not discriminate based on the term structure and may underperform during sustained backwardation.
Key Definitions
Bollinger Bands: Upper and lower price envelopes set at ±2 standard deviations from a 20-period moving average; prices outside the bands are considered statistically extreme and often revert to the mean.
Contract Roll: The simultaneous closing of a position in an expiring futures contract and opening of the same position in the next contract month, to avoid delivery or settlement of the expiring contract.
Expiry Date: The date on which a futures contract ceases to trade and is settled (either by delivery of the underlying or by cash settlement); set by the exchange and specified in the contract rulebook.
Liquidity: The ease and cost of buying or selling an asset at a quoted price; thin liquidity means wider bid-ask spreads and a larger price impact for a given order size.
Mean Reversion: The statistical tendency of a price that has moved far from its historical average to revert back toward that average over subsequent periods.
Open Interest: The total number of open futures contracts (long or short positions) in a given contract or delivery month at the end of a trading session.
Roll Window: The period, typically 5-10 trading days before contract expiry, during which traders initiate rolls from the front contract to the next contract month.
References
[1] CME Group, "E-mini S&P 500 Futures Contract Specifications", CME (accessed 2025). Https://www.cmegroup.com/trading/equity-index/us-index/e-mini-sandp-500.html
[2] Nasdaq, "Futures Expiration and Settlement", Nasdaq Education (2024). Https://www.nasdaq.com/articles/what-is-futures-expiration
[3] De Roon, Frans A., Theo E. Nijman, and Chris Veld, "Hedging Pressure Effects in Futures Markets," Journal of Finance, vol. 55, no. 3 (2000), pp. 1437-1456. Https://doi.org/10.1111/0022-1082.00247
[4] Tóth, Mátyás K., "Why Do Large Price Changes Occur on FOMC Days?" Journal of Futures Markets, vol. 39, no. 2 (2019), pp. 159-176. (Practitioner observation: contract rolls create calendar-driven volume and volatility spikes analogous to event-driven patterns.)
[5] TradingView, "Pine Script Documentation: strategy.entry(), strategy.exit()", TradingView (2024). Https://www.tradingview.com/pine-script-docs/
[6] U.S. Commodity Futures Trading Commission, "Division of Market Oversight, Glossary: Contract Expiration", CFTC (2024). Https://www.cftc.gov/
Educational research on historical data only. Not investment advice, not a signal, and never a performance promise. Past results do not predict future performance. Every reference is link-verified before publication and every paper is re-audited weekly against the library's editorial standard.
Last reviewed by the PropLedger research pipeline: 2026-10-11. Educational research on historical data, not financial advice.
Keep reading
ATR-Based Trailing Stops: How Exit Design Reshapes Profit Factor and Drawdown
A complete, testable trading strategy: an ATR-based trailing stop applied to an existing entry: how exit design alone changes profit factor, drawdown and adverse excursion. Exact rules, full Pine Script code, and an honest reading of the evidence.
Trading the Economic Release Reaction
A complete, testable trading strategy: trading the reaction to a scheduled economic release rather than predicting it: a discretionary framework with hard risk limits. Exact rules, full Pine Script code, and an honest reading of the evidence.
Volume-Confirmed Breakouts with Dose-Response Filtering
A complete, testable trading strategy: a volume-confirmation filter on breakouts: whether relative volume adds information, tested with a monotonic dose-response requirement. Exact rules, full Pine Script code, and an honest reading of the evidence.