Trend Day vs Range Day Classifier
Trend day and range day classification helps traders identify the character of a session early by comparing the opening range to the previous day's price action and volatility context. On a trend day, the market breaks decisively out of the prior range and sustains the directional move; on a range day, price stays contained within a narrow band. This indicator uses early session heuristics (opening range breakout magnitude and size) to issue a preliminary classification, allowing traders to orient their approach before the full session unfolds.
//@version=6
indicator("Trend vs Range Day Classifier", overlay=true)
// ============ INPUTS ============
earlySessionHours = input.int(2, title="Early Session (Hours)", minval=1, maxval=8)
breakoutThresholdPct = input.float(0.5, title="Breakout Threshold (%)", minval=0.1, maxval=2)
atrLookback = input.int(20, title="ATR Lookback Period", minval=5)
showPrevRange = input.bool(true, title="Show Previous Day Range")
// ============ DAILY DATA ============
prevDayHigh = request.security(syminfo.tickerid, "D", high[1])
prevDayLow = request.security(syminfo.tickerid, "D", low[1])
prevDayRange = prevDayHigh - prevDayLow
dayStartTime = request.security(syminfo.tickerid, "D", time)
// ============ EARLY SESSION DETECTION ============
millisecondsSinceOpen = time - dayStartTime
hoursSinceOpen = millisecondsSinceOpen / (1000.0 * 60.0 * 60.0)
isInEarlySession = hoursSinceOpen >= 0 and hoursSinceOpen <= earlySessionHours
// ============ OPENING RANGE TRACKING ============
var float orHigh = na
var float orLow = na
var int lastSessionId = na
currentSessionId = int(dayStartTime / 86400000)
// Reset on new session
if currentSessionId != lastSessionId
orHigh := high
orLow := low
lastSessionId := currentSessionId
// Update OR during early session
if isInEarlySession
orHigh := math.max(orHigh, high)
orLow := math.min(orLow, low)
orRange = orHigh - orLow
// ============ VOLATILITY BASELINE ============
avgDailyRange = ta.sma(prevDayRange, atrLookback)
// ============ TREND VS RANGE CLASSIFICATION ============
breakoutAboveThreshold = (orHigh > prevDayHigh) and ((orHigh - prevDayHigh) > (prevDayRange * breakoutThresholdPct / 100))
breakoutBelowThreshold = (orLow < prevDayLow) and ((prevDayLow - orLow) > (prevDayRange * breakoutThresholdPct / 100))
isTrendDay = (breakoutAboveThreshold or breakoutBelowThreshold)
isRangeDay = (not isTrendDay) and (orRange < avgDailyRange * 0.6)
// ============ VISUALIZATION ============
// Previous day's range
if showPrevRange
plot(prevDayHigh, title="Prev Day High", color=color.gray, linewidth=1, style=plot.style_dashed)
plot(prevDayLow, title="Prev Day Low", color=color.gray, linewidth=1, style=plot.style_dashed)
// Background color coding
bgColor = isTrendDay ? color.new(color.lime, 85) : (isRangeDay ? color.new(color.orange, 85) : color.new(color.gray, 95))
bgcolor(bgColor, title="Session Type")
// Classification label (last bar only)
if barstate.islast
classificationLabel = isTrendDay ? "TREND DAY" : (isRangeDay ? "RANGE DAY" : "UNDEFINED")
classificationColor = isTrendDay ? color.lime : (isRangeDay ? color.orange : color.gray)
label.new(bar_index, high * 1.005, classificationLabel, color=classificationColor, textcolor=color.white, style=label.style_label_down, size=size.normal)
How the code works
The indicator opens by capturing the previous day's high and low (via request.security() on daily timeframe) and calculates the prior range. It then determines the session start time and, for each bar, calculates how many hours have elapsed since market open.
During the early session window (default: first 2 hours), the code tracks the highest high and lowest low reached, forming the opening range (OR). It uses a session identifier (int(dayStartTime / 86400000)) to reset the OR variables each new trading day, preventing data bleed between sessions.
The classification logic applies two tests. First, it checks whether the opening range has broken above the previous day's high or below the previous day's low by at least the breakout threshold (default 0.5% of the previous day's range). If yes, the day is marked as trending. Second, if no breakout occurred, it compares the opening range size to a 20-bar simple moving average of prior daily ranges. If the OR is smaller than 60% of that average, the day is classified as ranging; otherwise, it remains undefined.
The visualization overlays the previous day's high and low as dashed gray lines, colors the chart background (lime for trend, orange for range, gray for undefined), and places a label on the final bar with the classification.
Reading it on a chart
When using this indicator on any intraday timeframe (1, 5, 15, or 60 minute), watch the background color and the label. A lime background during the first few hours signals the opening range is breaking out of yesterday's range by more than the threshold, suggesting directional momentum is present early. An orange background means the opening range is small relative to historical volatility and price is staying within yesterday's band, which typically precedes a consolidation day.
The gray dashed lines mark yesterday's extremes; they serve as reference anchors. If price breaks through both in the first two hours, the indicator will show a TREND DAY label. If price hugs between them with a contained opening range, look for RANGE DAY.
Note that the classification is issued early in the session and may be preliminary; intraday reversals or late-session volatility can override the early signal. Traders often use this classification to guide position sizing or entry/exit discipline rather than as a standalone trade signal.
Limitations
This classifier relies on early session behavior to predict the entire day's character. In reality, a market that starts as a range day can break out violently in the afternoon, and a trending morning can reverse into a range or consolidation by close. The opening range alone is insufficient to guarantee the full session's profile, especially in longer or lower-volatility markets where multi-hour breakouts are common.
The threshold parameters (early session hours, breakout percentage, range multiplier) are arbitrary and must be tuned to the specific instrument and timeframe. US equity markets, futures contracts, and forex spot have different session structures and volatility profiles; settings optimal for one may misclassify another.
The indicator also assumes a defined market open time, which works for equities and centralized futures but may be ambiguous or irrelevant for crypto, bonds, or overnight markets that trade nearly 24/7. Users on those instruments must adjust the session boundary manually or define it via a custom session input.
Finally, the opening range is calculated on the chart's current timeframe. Switching between 1-minute, 5-minute, and 60-minute charts will produce slightly different OR boundaries and thus different classifications, since the bars do not align perfectly across timeframes.
Key definitions
Opening Range (OR): The highest high and lowest low recorded during the first N hours of a trading session, used to gauge early directional intent and containment.
Breakout: A move above the previous session's high or below the previous session's low, signaling potential rejection of prior support or resistance.
Trend Day: A session on which price breaks out of the previous range by a meaningful amount (threshold-based) during early hours and sustains directional pressure.
Range Day: A session on which the opening range remains small relative to average daily volatility and price stays largely within the previous session's boundaries.
Average Daily Range: A moving average of the prior N days' high-to-low ranges, used as a volatility baseline to contextualize the size of the opening range.
References
- CME Group, "FX Trading Hours and Specifications," CME Education, accessed 2026. https://www.cmegroup.com/trading/fx/
- NYSE, "Market Hours," New York Stock Exchange Education Centre, accessed 2026. https://www.nyse.com/publicdocs/nyse/trading/Trading_Hours.pdf
- Wilder, J. W., "New Concepts in Technical Trading Systems", Trend Research (1978).
- Kaufman, P. J., "New Trading Systems and Methods", 6th ed., Wiley (2019).
- TradingView, "Pine Script Reference Manual: request.security()", https://www.tradingview.com/pine-script-reference/
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-09-27. Educational research on historical data, not financial advice.
Keep reading
Consecutive Close Counter with Streak Statistics
Free open-source Pine Script indicator: consecutive close counter with streak statistics table. Full code and a plain-English walkthrough.
Futures Contract Roll and Expiry Week Shading
Free open-source Pine Script indicator: contract roll and expiry week shading for futures. Full code and a plain-English walkthrough.
Value Area and Point of Control
Free open-source Pine Script indicator: value area and point of control from session volume. Full code and a plain-English walkthrough.