Skip to main content
On this page

Detect the First Bar of Each Trading Day in Pine Script

· 6 min read
Pineify Team
Pine Script and AI trading workflow research team

The first bar of a daily period, the first bar of a regular exchange session and the first bar inside a custom clock window are different events. Choose the event your trading rule needs before selecting a Pine time function. A daily-period change does not universally mean 09:30 in New York.

Pine Script First Bar of Day

Choose the Boundary​

RequirementRelevant concept
First loaded historical barbarstate.isfirst
New daily timeframe periodtimeframe.change("1D")
Exchange regular-session first barSession-state variables, interpreted for the symbol
Custom clock windowSession membership from time() with an explicit timezone

A chart's display timezone does not redefine Pine's exchange-based time calculations. Overnight sessions can start on the preceding calendar date. Read TradingView's time concepts before treating a daily boundary as a market opening.

Daily-Period Detection and an Alert​

This complete indicator marks the first available intraday bar of a new daily period. Its alert waits for that bar to close; it is not an opening-tick notification.

//@version=6
indicator("First chart bar of a daily period", overlay = true)
if not timeframe.isintraday
runtime.error("Use an intraday chart")
bool newDailyPeriod = timeframe.change("1D")
bgcolor(newDailyPeriod ? color.new(color.blue, 85) : na)
if newDailyPeriod and barstate.isconfirmed
alert("First daily-period bar closed. Previous chart close: " + str.tostring(close[1]), alert.freq_once_per_bar_close)

timeframe.change() returns a Boolean. The alternative ta.change(time("1D")) returns a timestamp difference and needs an explicit comparison to zero when used as a Boolean in Pine v6.

The message reports the previous chart bar's close. On an extended-hours chart, that is not necessarily the previous regular session's official close. Fetch or identify the intended close separately if the strategy requires it.

Create a TradingView alert for the script's alert() calls. Alert events are realtime only; historical execution does not send a backlog of notifications. Adding barstate.isrealtime is not necessary to prevent historical delivery. The alert documentation also explains saved script/input snapshots.

A Fixed New York Opening-Range Example​

The next indicator is limited to standard five-minute charts. It collects the twelve bars opening from 09:30 through 10:25, Monday to Friday, in America/New_York. It displays levels only after all twelve bars have been observed and the window has ended.

//@version=6
indicator("New York first-hour range", overlay = true)
if not timeframe.isminutes or timeframe.multiplier != 5
runtime.error("Use a standard 5-minute chart")
string zone = "America/New_York"
int localDate = year(time, zone) * 10000 + month(time, zone) * 100 + dayofmonth(time, zone)
bool newDate = barstate.isfirst or localDate != localDate[1]
bool inWindow = not na(time(timeframe.period, "0930-1030:23456", zone))
bool startBar = inWindow and hour(time, zone) == 9 and minute(time, zone) == 30
var float rangeHigh = na
var float rangeLow = na
var int count = 0
if barstate.isconfirmed
if newDate
rangeHigh := na
rangeLow := na
count := 0
if startBar
rangeHigh := high
rangeLow := low
count := 1
else if inWindow and count > 0
rangeHigh := math.max(rangeHigh, high)
rangeLow := math.min(rangeLow, low)
count += 1
bool ready = count == 12 and not inWindow and not newDate
plot(ready ? rangeHigh : na, "Completed opening high", color = color.green, style = plot.style_linebr)
plot(ready ? rangeLow : na, "Completed opening low", color = color.red, style = plot.style_linebr)
bgcolor(startBar ? color.new(color.blue, 85) : na)

The explicit 09:30 initialization avoids treating a chart loaded halfway through the window as a complete opening range. A missing bar leaves the count below twelve, so no completed range is shown. Daily resets also avoid carrying yesterday's range into a new date before today's range is ready.

This is a clock-window example, not an exchange holiday-calendar service. It uses available chart bars, does not fill data gaps and assumes bars align to the five-minute boundaries. Do not apply it to synthetic price charts when the intended range is based on traded OHLC prices.

Session Strings and Daylight Saving​

The session belongs in the session argument of time(), after the timeframe. The timezone is a separate argument. A session string such as 0800-0900 is not a valid substitute for the timeframe argument.

Use an IANA timezone such as Europe/London or America/New_York when the rule follows that location's civil clock. A fixed GMT offset does not automatically follow daylight-saving changes. The weekdays suffix 23456 means Monday through Friday; it does not encode holidays. TradingView's session documentation explains these distinctions and the need to align windows with chart bars.

Avoid Opening-Range Lookahead​

A range is not final while its collection window is open. Do not compare an early bar with the eventual full-hour high as if that high had already been known. The example withholds completed levels until collection finishes.

For a breakout strategy, define the first eligible entry bar after the window, order type, stop, exit and re-entry policy. A close breakout and an intrabar stop-entry order are different rules. The range indicator alone has no win rate; no SPY 60% gap-fill result or ES/NQ live record is established here.

Verify the Intended Session​

Check a regular day, a weekend transition, both daylight-saving transitions, a holiday or shortened session and a chart whose history starts mid-session. Compare regular and extended-hours data. Record actual bar timestamps rather than judge alignment only from chart colors.

On daily or higher charts, an intraday first-hour range cannot be reconstructed from the chart bars alone. This example rejects the wrong timeframe instead of silently treating a daily candle as one intraday observation.

Pineify | Best Pine Script Generator

Frequently Asked Questions​

Does barstate.isfirst detect every market open?
No. It identifies the first bar in the loaded dataset.
Does a daily change always occur at midnight?
No. Daily periods follow the symbol's time and session context, including overnight sessions.
Why do alerts not appear for old signals?
TradingView alert events operate in realtime. Historical markers can be inspected without generating historical notifications.
Are twelve bars always an hour?
Only with twelve consecutive, aligned five-minute bars. The example requires that chart interval and withholds the completed range if observations are missing.
Can these examples trade an opening breakout?
They identify timing and range information. A trading strategy still needs explicit entries, exits, sizing and execution assumptions.