Indicators··6 min read

Futures Contract Roll & Expiry Week Shading

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

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

  1. CME Group, "Eurodollar Futures Product Specifications", CME.com (accessed 2026). Https://www.cmegroup.com/trading/interest-rates/
  2. ICE Futures U.S., "WTI Crude Oil Futures Contract Specifications", ICEMulticommodities.com (accessed 2026). Https://www.theice.com/products/174/WTI-Crude-Oil-Futures
  3. CBOE, "SPX (S&P 500 Index) Options Product Specifications", CBOE.com (accessed 2026). Https://www.cboe.com/products/
  4. 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.

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.