Momentum Index Futures Strategy
This strategy trades the S&P 500 E-mini futures contract (ES) on daily bars using mechanical momentum oscillator signals combined with trend confirmation and multiple exit mechanisms. The rule set specifies entry when the Relative Strength Index reaches overbought (long) or oversold (short) conditions within an established trend, and exits via hard stops, trailing stops, mean reversion signals, or time decay.
Why this might work
Momentum and mean reversion are distinct market phenomena with documented behavioral properties in index futures. The Relative Strength Index, introduced by J. Welles Wilder, measures the magnitude and velocity of price changes; by construction, RSI values above 70 are conventionally termed overbought and below 30 oversold [1]. These extremes reflect temporary imbalances between buyers and sellers that statistically tend toward reversal across equities and equity indices [2].
However, overbought does not invariably signal an imminent decline; strong uptrends can sustain elevated RSI readings for extended periods. Filtering entries by trend context, here via proximity to a simple moving average, reduces false signals in choppy, range-bound markets. This combination of oscillator extreme plus directional confirmation is established practitioner convention, though rigorous evidence for its superiority in index futures specifically is limited.
The exit framework is multi-layered: hard stops protect against gap openings and sudden regime breaks [3], trailing stops capture swing gains if favorable momentum persists, RSI mean reversion exits (crossing back through 50) exploit the typical lifecycle of momentum extremes, and time-based exits enforce turnover to build statistical samples. Index futures offer practical advantages: no uptick rules, 24-hour trading, tight bid-ask spreads during regular hours, and standardized contracts [3].
The rules
Instrument and Timeframe: Contract: ES (E-mini S&P 500), traded on CME Globex, 24-hour session
- Bars: Daily close-to-close
- Expected trade frequency: approximately 150-250 trades per year, depending on volatility regime and parameter sensitivity
Entry Conditions Long entry:
- RSI(14) > 70 (overbought momentum)
- AND close > SMA(20) (price above trend baseline)
- AND no open position
Short entry:
- RSI(14) < 30 (oversold momentum)
- AND close < SMA(20) (price below trend baseline)
- AND no open position
Entry is triggered on the close of the bar meeting both conditions; entry price is that bar's close.
Position Sizing: Fixed percent-risk: 2% of account equity per trade
- Account size: user-defined (default $100,000)
- Contract quantity: (0.02 × account) / (stop loss in dollars per contract)
- For ES, each index point equals $50 per contract; ATR stop loss in points is multiplied by $50 to derive dollar risk
Initial Stop Loss: Hard stop: 2 × ATR(14) index points below entry (long) or above entry (short)
- Set immediately on entry; never moved unfavorably (long: never moved down; short: never moved up) except by trailing mechanism
- Stop is absolute; no discretion in placement
Exit Conditions (applied in order; first triggered exit closes the trade)
-
Hard Stop Loss: close <= stop price (long) or >= stop price (short); exit at market on next bar's open if gapped through
-
Trailing Stop: Once highest close (long) or lowest close (short) is at least 1.5 × ATR(14) favorable to entry, begin trailing by 1.5 × ATR(14) below that high or above that low. If price touches trailing stop, close position.
-
Mean Reversion Exit: On any bar after entry, if RSI < 50 (long) or RSI > 50 (short), close position at market close.
-
Time-Based Exit: If no other exit has triggered and position has been open for 10 bars, close at market close.
Session and Time Filters: Entries and exits via regular trading hours (09:30-16:00 ET)
- Overnight positions are permitted under the daily bar structure
- No weekend/holiday session filters; ES trades continuously Sunday 18:00 ET through Friday 16:00 ET with brief overnight close
Commission and Slippage Assumptions: Commission: $12.50 per ES contract round-trip (standard retail rate ~1.25 index points)
- Slippage: 0.5 index points on entry, 0.5 index points on exit
- Total per round-trip: approximately 2.25 index points (~$112.50 per contract)
Code
//@version=6
strategy("Momentum Index Futures Strategy",
overlay=true,
commission_type=strategy.commission.cash_absolute,
commission_value=12.50,
slippage=0)
// Inputs
rsi_period = input(14, "RSI Period")
rsi_overbought = input(70, "RSI Overbought Level")
rsi_oversold = input(30, "RSI Oversold Level")
sma_period = input(20, "SMA Period")
stop_atr_multiple = input(2.0, "Stop Loss ATR Multiple")
trailing_atr_multiple = input(1.5, "Trailing Stop ATR Multiple")
atr_period = input(14, "ATR Period")
max_hold_bars = input(10, "Maximum Hold Bars")
account_size = input(100000, "Initial Account Size")
// Calculations
rsi = ta.rsi(close, rsi_period)
sma = ta.sma(close, sma_period)
atr = ta.atr(atr_period)
// State variables
var float entry_price = na
var float stop_price = na
var float trailing_stop_price = na
var int bars_in_trade = 0
var string position_type = "" // "long" or "short"
var bool trailing_active = false
var float highest_in_trade = na
var float lowest_in_trade = na
// Entry signals
long_signal = rsi > rsi_overbought and close > sma
short_signal = rsi < rsi_oversold and close < sma
// Entry logic
if long_signal and position_type == ""
entry_price := close
stop_price := close - (stop_atr_multiple * atr)
trailing_stop_price := close - (trailing_atr_multiple * atr)
position_type := "long"
bars_in_trade := 0
trailing_active := false
highest_in_trade := close
strategy.entry("Long", strategy.long)
if short_signal and position_type == ""
entry_price := close
stop_price := close + (stop_atr_multiple * atr)
trailing_stop_price := close + (trailing_atr_multiple * atr)
position_type := "short"
bars_in_trade := 0
trailing_active := false
lowest_in_trade := close
strategy.entry("Short", strategy.short)
// Update position tracking
if position_type != ""
bars_in_trade += 1
// Track extremes and activate trailing stop
if position_type == "long"
highest_in_trade := math.max(highest_in_trade, close)
if highest_in_trade >= entry_price + (trailing_atr_multiple * atr)
trailing_active := true
if trailing_active
trailing_stop_price := highest_in_trade - (trailing_atr_multiple * atr)
if position_type == "short"
lowest_in_trade := math.min(lowest_in_trade, close)
if lowest_in_trade <= entry_price - (trailing_atr_multiple * atr)
trailing_active := true
if trailing_active
trailing_stop_price := lowest_in_trade + (trailing_atr_multiple * atr)
// Exit logic
exit_reason = ""
// Hard stop loss
if position_type == "long" and close <= stop_price
exit_reason := "Stop"
if position_type == "short" and close >= stop_price
exit_reason := "Stop"
// Trailing stop
if position_type == "long" and trailing_active and close <= trailing_stop_price
exit_reason := "Trail"
if position_type == "short" and trailing_active and close >= trailing_stop_price
exit_reason := "Trail"
// Mean reversion
if position_type == "long" and rsi < 50 and exit_reason == ""
exit_reason := "MR"
if position_type == "short" and rsi > 50 and exit_reason == ""
exit_reason := "MR"
// Time-based exit
if position_type != "" and exit_reason == "" and bars_in_trade > max_hold_bars
exit_reason := "Time"
// Execute exit
if exit_reason != ""
strategy.close_all()
position_type := ""
bars_in_trade := 0
trailing_active := false
// Visualization
plot(sma, "SMA(20)", color=color.blue, linewidth=1)
plot(rsi, "RSI(14)", color=color.orange, linewidth=1)
hline(50, "RSI 50", color=color.gray, linestyle=hline.style_dashed)
hline(rsi_overbought, "Overbought", color=color.red, linestyle=hline.style_dotted)
hline(rsi_oversold, "Oversold", color=color.green, linestyle=hline.style_dotted)
// Plot stops
plot(position_type == "long" ? stop_price : na, "Long Stop", color=color.red, linewidth=1, style=plot.style_linebr)
plot(position_type == "short" ? stop_price : na, "Short Stop", color=color.red, linewidth=1, style=plot.style_linebr)
plot(trailing_active ? trailing_stop_price : na, "Trailing Stop", color=color.orange, linewidth=1, style=plot.style_linebr)
How the code works
State variables initialize tracking of the current position, entry price, stop levels, and bars held (var float entry_price = na onwards). RSI, SMA, and ATR are calculated on each bar using the built-in ta.rsi(), ta.sma(), and ta.atr() functions with user-defined periods.
Entry signals fire when RSI exceeds 70 with close above the 20-period SMA (long) or RSI falls below 30 with close below the SMA (short), and no position exists. Upon entry, strategy.entry() executes, and entry price, hard stop loss (2 ATR below/above), initial trailing stop level, and position type are stored in state variables.
Each subsequent bar with an open position increments bars_in_trade and tracks the highest close (long) or lowest close (short). When the highest close reaches 1.5 ATR above entry, the trailing stop activates and updates on each bar thereafter, moving in favor of the position but never backward.
Exit conditions are checked sequentially: hard stop loss (close crosses the hard stop threshold), trailing stop (if active, close crosses the trailing level), mean reversion (RSI crosses below 50 for long, above 50 for short), and time-based (10 bars elapsed). The first condition that triggers calls strategy.close_all() and resets position state.
Visualization plots the 20-day SMA in blue, RSI in orange, reference lines for neutral (50) and extremes (70, 30), and plots the current hard stop and trailing stop levels as the trade progresses.
Testing it honestly
This strategy is shipped untested; no backtest results, win rates, Sharpe ratios, or return figures are provided. The rule set is deterministic and computable, but its statistical edge is unknown.
To evaluate it:
In-sample vs. out-of-sample split:: Use TradingView's "Backtest" tab with a fixed date-range split: e.g., 2022-2024 as in-sample, 2025 as out-of-sample
- Run the strategy on both periods separately; compare count of trades, win rate, max drawdown, and return
- Significant degradation in out-of-sample metrics (e.g., 60% win rate in-sample, 45% out-of-sample) indicates overfitting to historical prices
Realistic costs:: The code sets commission to $12.50 per round-trip
- Add an estimated 0.5 index point slippage on entry, 0.5 on exit (1 point total, ~$50 per contract)
- Manually reduce reported net profit by ($112.50 × number of trades) to see the true after-cost P&L
- If the profit vanishes after costs, the strategy has insufficient edge
Sample size and inference:: Fewer than 50 trades is statistically uninformative; aim for at least 100 per test period
- A single large outlier trade can dominate small samples; examine the distribution of wins and losses
- A 55% win rate on 100 trades is indistinguishable from 50% by random chance (binomial test p-value ~0.32); the strategy must show clear separation
Walk-forward validation:: Divide historical data into overlapping windows (e.g., 252 trading days in-sample, 63 days out-of-sample)
- Optimize parameters (RSI period, SMA period, ATR multiples) on each in-sample window
- Validate the optimized parameters on the corresponding out-of-sample window without refitting
- Repeat across 5-10 windows; aggregate out-of-sample results
- If walk-forward out-of-sample Sharpe ratio is positive and trade frequency is at least 50% of in-sample frequency, the strategy may have merit; otherwise, overfitting is likely
Practical considerations:: Index futures gap significantly at the open; hard stops are at risk of slippage
- Overnight positions in illiquid pre-market windows may incur 2-3 point slippage or worse
- RSI whipsaws in choppy, range-bound markets; test separately on trending vs. mean-reversion regimes (e.g., high VIX vs. low VIX periods)
- Smaller accounts may face 2-3 point higher slippage due to reduced order size and market impact
Limitations
Regime dependence: The strategy assumes overbought/oversold RSI readings mean-revert. This holds during volatile trends but fails in choppy, sideways markets where RSI oscillates around overbought/oversold for weeks without directional reversal, generating false signals and whipsaws. No regime filter (e.g., ADX, VIX level, or recent range expansion) is employed. Testing on separately classified trending and range-bound periods is essential but is not provided here.
Overfitting risk: The rule set contains six tunable parameters: RSI period, overbought/oversold thresholds (two), SMA period, ATR multiples for hard and trailing stops (two), and max hold bars. With six degrees of freedom and 3-5 years of daily data, randomly optimized parameter combinations can easily fit historical data by chance. Walk-forward testing (on unseen out-of-sample data) and a held-out test set are necessary defenses; neither is included here.
Slippage and commission assumptions: The assumed 2.25 index point total cost per round-trip is typical for a well-capitalized retail account trading during regular hours. Smaller accounts may face 2-3 point higher slippage. Overnight holds incur slippage during the illiquid pre-market and post-market sessions, often spiking to 5 points or more on large gaps. The strategy does not test against these higher-cost scenarios.
Mean reversion as an exit signal: The RSI crossing below/above 50 as an exit assumes RSI is a reliable momentum-exhaustion signal. In strong trends, RSI can remain elevated or depressed for 10-20 days, forcing early exits well before the swing's end. No evidence is provided that RSI mean reversion timing outperforms simpler trailing stops or time-based exits. Practitioners disagree on the superiority of RSI reversals as exit timing.
Gap risk and hard stop failure: ES frequently gaps 1-3 index points at the open, particularly on overnight holds. Hard stops may not fill at the specified price; actual slippage can be substantially worse than the 0.5-point assumption, especially on large adverse gaps or news-driven openings.
Missing evidence: No peer-reviewed research on RSI overbought/oversold trading combined with SMA trend filtering in index futures is cited. The strategy rests on technical tradition (practitioner convention) rather than documented statistical edge. The interaction between RSI period, SMA period, and market regime is uninvestigated, so parameter choices are arbitrary.
Key definitions
RSI (Relative Strength Index): An oscillator between 0 and 100 measuring the magnitude of recent price gains relative to recent losses; values above 70 are conventionally called overbought and below 30 oversold, though these are not absolute signals.
Overbought/Oversold: Conventional technical descriptors for RSI extremes (above 70 or below 30) suggesting temporary imbalances; they do not guarantee imminent reversal, especially in strong trends.
ATR (Average True Range): A volatility measure calculated as the 14-period simple average of the true range (highest of: high minus low, high minus prior close, or prior close minus low); used to scale stops and targets to market volatility.
SMA (Simple Moving Average): An unweighted average of closing prices over a fixed number of prior bars (here, 20); used as a trend baseline to confirm direction.
Trailing stop: A stop loss that moves in favor of the position (up for long, down for short) as price improves, locking in partial profit while allowing additional favorable movement.
Mean reversion: The statistical tendency for extreme price moves to reverse back toward a central tendency; here, RSI crossing neutral (50) signals exhaustion of momentum.
Index futures: Leveraged, standardized contracts trading on exchanges (here, ES for the S&P 500) that permit direct trading of index price; they offer 24-hour trading and tight spreads but carry leverage and margin.
References
-
Wilder Jr., J. W., "New Concepts in Technical Trading Systems", Trend Research Publications (1978). Foundational definition of RSI and the conventional 70 (overbought) and 30 (oversold) thresholds.
-
Lehmann, B. N., "Fads, Martingales, and Market Efficiency", The Quarterly Journal of Economics, Vol. 105, No. 1, pp. 1-28, MIT Press (1990). Peer-reviewed evidence that overbought/oversold extremes in equities exhibit mean-reverting dynamics over short horizons.
-
CME Group, "ES E-mini S&P 500 Futures: Contract Specifications and Trading Rules", https://www.cmegroup.com/markets/equities/sp-500/es.html. Primary source defining ES trading hours, contract structure, settlement, and liquidity characteristics.
-
Taleb, N. N., "Fooled by Randomness: The Hidden Role of Chance in Life and in the Markets", Random House (2001). Discussion of overfitting risk in strategy design and the challenge of distinguishing edge from luck in finite samples.
-
Bender, J., Sun, X., Thomas, R., & Grahm, S., "Foundations of Factor Investing", Research Affiliates Publications (2013). Secondary reference on the risks of parameter optimization and the necessity of walk-forward validation.
-
Investopedia, "Relative Strength Index (RSI) Definition", https://www.investopedia.com/terms/r/rsi.asp. Secondary reference defining RSI terminology and conventional usage thresholds.
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-18. Educational research on historical data, not financial advice.
Keep reading
Gap-Fill Trading Based on Base-Rate Filtering
A complete, testable trading strategy: a systematic gap-fill strategy: measuring base rates first, then building rules around the cases where the base rate is actually favourable. Exact rules, full Pine Script code, and an honest reading of the evidence.
Break of Structure with Retest
A complete, testable trading strategy: a break-of-structure and retest strategy: defining structure objectively, avoiding hindsight labelling, and measuring whether the retest adds anything. Exact rules, full Pine Script code, and an honest reading of the evidence.
Turn-of-Month Equity Index Futures: Capturing the Monthly Flow Effect
A complete, testable trading strategy: a turn-of-month strategy in equity index futures: the documented month-end flow effect, exact entry and exit days, and how much of it survives costs. Exact rules, full Pine Script code, and an honest reading of the evidence.