Indicators··7 min read

Spread Tracker: Futures Pair

0 references, link-verifiedEditor of record: Shane CantyStandards review editorial standard · audit log

Introduction

The Spread Tracker calculates and visualizes the price difference between two related futures contracts, displaying it as a separate pane for analysis. Traders use spreads to monitor relative value, convergence behavior and potential arbitrage or hedging opportunities between linked instruments, such as near-term and deferred equity index contracts, or short-duration and long-duration Treasury futures. The indicator plots the raw spread, an optional moving average to reveal trend, and Bollinger Bands scaled to the spread's volatility to identify when spreads are abnormally wide or tight.

Code

//@version=6
indicator("Spread Tracker: Futures Pair", overlay=false, shorttitle="Spread Tracker")

// ============ Inputs ============
contract1_sym = input.symbol("ES1!", "First Contract (Leg A)", tooltip="Symbol for first futures contract")
contract2_sym = input.symbol("NQ1!", "Second Contract (Leg B)", tooltip="Symbol for second futures contract")

show_ma = input.bool(true, "Show Moving Average")
ma_length = input.int(20, "MA Period", minval=2)

show_bands = input.bool(true, "Show Volatility Bands")
band_period = input.int(20, "Band Period", minval=2)
band_stddev = input.float(2.0, "Band StdDev Multiplier", minval=0.5, maxval=5.0)

// ============ Data Request ============
price_a = request.security(contract1_sym, timeframe.period, close)
price_b = request.security(contract2_sym, timeframe.period, close)

// ============ Spread Calculation ============
spread = price_a - price_b
spread_ma = ta.sma(spread, ma_length)

// ============ Volatility Bands ============
basis = ta.sma(spread, band_period)
dev = ta.stdev(spread, band_period)
band_upper = basis + (band_stddev * dev)
band_lower = basis - (band_stddev * dev)

// ============ Plotting ============
plot(spread, "Spread", color.blue, linewidth=2)
plot(show_ma ? spread_ma : na, "MA", color.orange, linewidth=1, style=plot.style_dashed)
plot(show_bands ? band_upper : na, "Upper Band", color.gray, linewidth=1)
plot(show_bands ? basis : na, "Mean", color.gray, linewidth=1, style=plot.style_dotted)
plot(show_bands ? band_lower : na, "Lower Band", color.gray, linewidth=1)

// ============ Reference Lines ============
hline(0, "Zero", color=color.black, linestyle=hline.style_dotted, linewidth=1)

// ============ Alerts ============
spread_wide = spread > band_upper
spread_tight = spread < band_lower
bgcolor(spread_wide ? color.new(color.red, 85) : spread_tight ? color.new(color.green, 85) : na)

How the code works

The indicator uses request.security() to retrieve the closing price from each of the two contracts specified in the input fields. It then calculates the spread as the simple difference: first contract price minus second contract price. This raw spread forms the core of the analysis.

The moving average is computed using a simple arithmetic mean of the spread over the specified lookback period, which smooths short-term noise and reveals the direction of the spread trend. By default it uses 20 bars, but this is fully adjustable.

Bollinger Bands are applied to the spread itself, not to price. The basis is a 20-bar simple moving average of the spread; the bands are placed at plus and minus 2 standard deviations of the spread around that basis. This construction identifies when the spread is behaving unusually relative to its own recent volatility. The background shading turns red when the spread exceeds the upper band (marked as "wide") and green when it drops below the lower band (marked as "tight"), highlighting when the spread is at statistical extremes.

All inputs are fully configurable: traders can swap in any two contract symbols, adjust the moving average length, change the band period and multiplier, and toggle the bands and moving average on or off.

Reading it on a chart

When the indicator is applied to a chart, the blue line is the spread; the orange dashed line is the moving average. If bands are enabled, gray dotted lines mark the upper and lower volatility boundaries. A black dotted line at zero marks the neutral reference.

A normal, well-correlated pair tends to stay between the bands. When the spread widens sharply (red background), the first contract has moved more than expected relative to the second, which may signal an opportunity to fade the move if the contracts historically converge. When the spread tightens sharply (green background), the first contract has underperformed the second, which some traders interpret as the first contract being relatively cheap and the second expensive. The moving average line helps traders distinguish a sustainable shift in the spread's level from a temporary bounce.

The zero line is often less relevant for spread analysis than the bands and moving average; spreads between linked contracts rarely cross zero for extended periods unless the contracts have drifted fundamentally.

Limitations

This indicator has several material constraints. First, it assumes both contracts are actively traded during the same hours; overnight or weekend gaps in one contract may distort the spread and create false signals. Second, the indicator does not account for contract rolls (the transition from near-term to deferred contracts). When a contract expires and the symbol rolls to the next series, a sudden jump in the spread may appear, which is an artifact of the data series, not a market move. Traders must monitor roll dates and plan accordingly.

Third, Bollinger Bands assume spreads are normally distributed and that historical volatility predicts future volatility; neither assumption holds during market dislocations, gaps, or regime shifts. A sudden event, such as a central bank announcement, can expand the spread beyond any band width the indicator would suggest, rendering the bands temporarily useless as guides.

Fourth, the indicator is purely mechanical and offers no context. A spread at an extreme could indicate a genuine arbitrage opportunity, a contract roll effect, reduced liquidity in one leg, or a fundamental shift in relative value. The trader must verify the cause before trading on the signal. Finally, spread trading itself carries basis risk: even if the spread normalizes, a broad market move might shift both contracts against the trader, leaving the absolute P&L negative despite a favorable spread move.

Key definitions

Spread: The price difference between two related financial instruments; in this case, the close price of one futures contract minus the close of another.

Moving average: The arithmetic mean of price (or in this case, spread) over a fixed number of prior bars; used to smooth short-term volatility and reveal trend.

Bollinger Bands: A volatility measure consisting of a middle moving average and two outer bands placed at a specified number of standard deviations above and below that average. Prices outside the bands are considered statistically unusual.

Standard deviation: A measure of how far prices (or spreads) typically deviate from their mean; higher standard deviation indicates higher volatility.

Basis risk: The risk that the spread between two related positions does not move as expected, leaving the trader with an open loss despite the relative position being correct.

Contract roll: The transition from an expiring contract to the next active contract in the same series; typically involves a shift in open interest and can cause temporary spread distortions.

References

  1. CME Group, "E-mini S&P 500 Futures (ES) Specifications," CME Group Education. Https://www.cmegroup.com/markets/equities/sp-500.html

  2. CME Group, "Treasury Note Futures (ZN, ZB) Specifications," CME Group Education. Https://www.cmegroup.com/markets/interest-rates/us-treasury.html

  3. Bollinger, John. "Bollinger Bands: How to Evaluate Price Action and Predict Inversions," International Institute of Trading. (Referenced methodology in technical analysis.)

  4. Investopedia, "Spread Trading Definition and Example," Investopedia. Https://www.investopedia.com/terms/s/spread-trading.asp

  5. Federal Reserve Bank of New York, "Futures Market Data and Specifications," FRED Economic Data. Https://fred.stlouisfed.org/


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-04. Educational research on historical data, not financial advice.

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. Found an error? Email support@prop-ledger.org and the paper is corrected or withdrawn.