Futures Contract Roll & Expiry Week Shading
A chart overlay indicator that highlights the roll period (when traders typically close expiring contracts) and expiry week for futures contracts. Futures traders need to know when their active contracts near expiration so they can roll positions (sell the near contract, buy the next) or exit entirely. This indicator shades both the roll preparation window and the final expiry week, reducing the risk of holding a contract into illiquidity or settlement.
//@version=6
indicator('Futures Contract Roll & Expiry Week Shading', overlay=true)
// Expiry date inputs
expiryMonth = input.int(defval=12, title='Expiry Month', minval=1, maxval=12)
expiryYear = input.int(defval=2026, title='Expiry Year', minval=2000)
expiryDay = input.int(defval=15, title='Expiry Day of Month', minval=1, maxval=31)
// Roll zone configuration
rollDaysAhead = input.int(defval=7, title='Roll Zone Width (days)', minval=1, maxval=30)
expiryWeekWidth = input.int(defval=7, title='Expiry Week Width (days)', minval=1, maxval=14)
// Visual settings
rollColor = input.color(defval=color.new(color.orange, 85), title='Roll Zone Background')
expiryColor = input.color(defval=color.new(color.red, 85), title='Expiry Week Background')
showInfo = input.bool(defval=true, title='Show Info Label')
// Calculate expiry timestamp
// Clamp day to max 28 to avoid invalid dates in shorter months
expiryDayValid = math.min(expiryDay, 28)
expiryTimestamp = timestamp(expiryYear, expiryMonth, expiryDayValid)
// Roll period starts N days before expiry; expiry week is separate highlight
rollStartTimestamp = expiryTimestamp - (rollDaysAhead * 24 * 60 * 60 * 1000)
expiryWeekStart = expiryTimestamp - (expiryWeekWidth * 24 * 60 * 60 * 1000)
// Determine zones for current bar
inRollZone = time >= rollStartTimestamp and time < expiryWeekStart
inExpiryWeek = time >= expiryWeekStart and time < expiryTimestamp
beforeRoll = time < rollStartTimestamp
afterExpiry = time >= expiryTimestamp
// Apply zone shading
bgcolor(inExpiryWeek ? expiryColor : inRollZone ? rollColor : na, title='Zone Background')
// Info label shown once when entering roll zone
if showInfo and inRollZone and not inExpiryWeek
var lastLabelTime = time
if time > lastLabelTime
label.new(bar_index, high * 1.001, 'ROLL PERIOD',
color=color.orange, textcolor=color.white,
style=label.style_label_left, size=size.small)
lastLabelTime := time
// Info label for expiry week
if showInfo and inExpiryWeek
var lastExpiryLabel = time
if time > lastExpiryLabel
label.new(bar_index, high * 1.001, 'EXPIRY WEEK',
color=color.red, textcolor=color.white,
style=label.style_label_left, size=size.small)
lastExpiryLabel := time
How the code works
The indicator takes three inputs to identify the contract's expiry date: month, year, and day. These are combined into a single timestamp using Pine Script's timestamp() function. The code then calculates two key zones:
Roll zone: begins rollDaysAhead days before expiry and runs until the expiry week begins. This gives traders a visual window for planning and executing their roll trade.
Expiry week: the final expiryWeekWidth days before contract expiry, shaded more distinctly in red to signal imminent settlement or forced liquidation.
On each bar, the code compares the current time against these boundaries. If the bar falls within the roll zone, the background turns orange; if it falls within the expiry week, the background turns red. The bgcolor() function applies the shading without consuming chart space. The optional labels appear once per zone (using var to persist state) to reduce visual clutter while confirming zone entry.
Reading it on a chart
An orange shade indicates the roll period is beginning. For a contract expiring on the 15th with a 7-day roll window, orange appears starting around the 8th. This is when volume typically migrates from the near contract to the next, and when spreads widen. A trader managing a near-contract position should finalize their exit or roll by this point.
Red shading signals the final expiry week. Holding through this period risks automatic liquidation, cash settlement at unfavorable rates, or assignment. In the red zone, rolling (or exiting) is urgent.
The width inputs allow for market-specific tuning. Highly liquid contracts (e.g., ES, NQ, crude oil) may tolerate a shorter roll window; less liquid contracts or those with gapped overnight sessions may benefit from a wider one.
Limitations
This indicator assumes a static expiry day each month (e.g., the 15th). Many futures contracts expire on the third Friday, which varies year to year (typically the 15th–21st). Users must either update the expiry day manually for each contract month or accept approximation. No intra-month contract rolls or cycle switches are handled; each input assumes a single contract month.
The indicator does not account for liquidity conditions, holiday closures, or early settlement periods set by the exchange. Some contracts settle before the official expiry date, and some exchanges halt trading in the final minutes or hours. Also, shading applies only to the chart of the instrument it is applied to; traders on contracts in different symbols (e.g., rolling from Dec to Jan on different tickers) will need separate indicator instances.
The indicator is non-repainting: zones are determined solely from historical time values and will not change on realtime bar updates. However, once the contract rolls or settles, the indicator will no longer highlight the expired contract; it shows the zone for the next contract month as specified in inputs. If those inputs are not updated, the indicator becomes silent after expiry.
Key definitions
Contract expiry: the date on which a futures contract ceases trading and settles to cash or physical delivery, set by the exchange in the contract specification.
Roll period: the window (typically 1-3 weeks before expiry) during which most traders exit the near contract and enter the next available contract month to maintain a continuous position.
Liquidity migration: the shift in trading volume and open interest from the expiring contract to the next, which typically causes spreads to widen and individual prices to behave erratically.
Settlement: the act of closing the contract either via cash payment (financial futures) or physical delivery (commodities), occurring on or shortly after the expiry date.
Repainting: the behavior of an indicator recalculating past values based on new information, which can cause alerts or signals to fire retroactively and mislead backtesting results.
References
- CME Group, "Eurodollar Futures Product Specifications", CME.com (accessed 2026). Https://www.cmegroup.com/trading/interest-rates/
- ICE Futures U.S., "WTI Crude Oil Futures Contract Specifications", ICEMulticommodities.com (accessed 2026). Https://www.theice.com/products/174/WTI-Crude-Oil-Futures
- CBOE, "SPX (S&P 500 Index) Options Product Specifications", CBOE.com (accessed 2026). Https://www.cboe.com/products/
- Investopedia, "Futures Contract: Definition, Example, and Purpose", Investopedia (accessed 2026). Https://www.investopedia.com/terms/f/futures.asp
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-26. Educational research on historical data, not financial advice.
Keep reading
Premium/Discount Zones from Rolling Range Midpoint
Free open-source Pine Script indicator: premium and discount zones from a rolling range midpoint. Full code and a plain-English walkthrough.
Session Open Anchored Move
Free open-source Pine Script indicator: session open anchored move measure (points and ATR multiples). Full code and a plain-English walkthrough.
Inside Bar and Outside Bar Highlighter
Free open-source Pine Script indicator: inside bar and outside bar highlighter. Full code and a plain-English walkthrough.