The script
The daily open and the previous day's high and low, with the day starting either at the exchange's session or at an hour you choose, and an optional weekday shading. Paste it into a new indicator in the Pine Editor, then save and add it to the chart.
//@version=6
indicator("Daily open and previous day high/low", overlay = true)
anchor = input.string("Exchange session", "Day starts at", options = ["Exchange session", "Custom hour"])
startHour = input.int(0, "Custom hour (0-23)", minval = 0, maxval = 23, active = anchor == "Custom hour")
tz = input.string("UTC", "Time zone of the custom hour", options = ["UTC", "America/New_York", "Europe/London", "Asia/Tokyo"], active = anchor == "Custom hour")
shadeDay = input.string("None", "Shade a weekday", options = ["None", "Monday", "Friday"])
// A new day, two ways: the exchange's daily session, or a fixed hour in a time zone
bool exchangeNewDay = timeframe.change("D")
int shifted = time - startHour * 3600000
bool customNewDay = dayofmonth(shifted, tz) != dayofmonth(shifted[1], tz)
bool newDay = anchor == "Exchange session" ? exchangeNewDay : customNewDay
var float dayOpen = na
var float dayHigh = na
var float dayLow = na
var float prevHigh = na
var float prevLow = na
if newDay
prevHigh := dayHigh
prevLow := dayLow
dayOpen := open
dayHigh := high
dayLow := low
else
dayHigh := math.max(dayHigh, high)
dayLow := math.min(dayLow, low)
// na on the first bar of each day breaks the line between days
plot(newDay ? na : dayOpen, "Daily open", color.orange, 2, plot.style_linebr)
plot(newDay ? na : prevHigh, "Previous day high", color.teal, 1, plot.style_linebr)
plot(newDay ? na : prevLow, "Previous day low", color.red, 1, plot.style_linebr)
bool shade = (shadeDay == "Monday" and dayofweek == dayofweek.monday) or (shadeDay == "Friday" and dayofweek == dayofweek.friday)
bgcolor(shade ? color.new(color.gray, 90) : na, title = "Weekday")
aboveOpen = ta.crossover(close, dayOpen)
alertcondition(aboveOpen, "Close above the daily open", "{{ticker}} closed above the daily open")How it works
timeframe.change("D")is true on the first chart bar of each new daily bar, as the exchange defines the day. For stocks that's the session open; for futures and forex it's often the evening before the calendar day (see the pitfalls).- A custom start hour.
timeis the bar's opening time in milliseconds. SubtractingstartHour * 3600000(that many hours) and taking the day of the month in the chosen time zone gives a "trading date" that changes exactly at that hour, whatever the chart's timeframe.dayofmonth(time, timezone)handles daylight saving. - One block for the whole day. On a new day the finished day's high and low become the previous day's, and the new day starts from the current bar. On other bars the high and low only expand. Before the first full day,
dayHighisnaandmath.max(na, high)staysna, so nothing is drawn from a partial day. plot(newDay ? na : dayOpen, ..., plot.style_linebr). A plain line would draw a vertical jump from one day's level to the next;naon the first bar plusplot.style_linebrleaves a gap instead.dayofweekis the bar's weekday in the exchange's time zone, compared with constants fromdayofweek.sunday(1) todayofweek.saturday(7). For another time zone, call the function form:dayofweek(time, "Europe/London").
Pitfalls
- Comparing timeframe.period with "D". In v6
timeframe.periodreturns"1D"for the daily chart, sotimeframe.period == "D"is never true. Usetimeframe.isdaily,timeframe.isintradayand friends; convert Pine Script v5 to v6 lists this change. - Exchange day vs midnight. On futures and on forex with many data feeds, the exchange's day starts the previous evening (for forex usually 17:00 New York). A "daily open" from
timeframe.change("D")is then the evening open, not midnight's. That's why the script lets you choose the hour. - Time zones. The
hour,dayofweekanddayofmonthvariables use the exchange's time zone, not yours. Pass a time zone to the function forms (hour(time, "Europe/London")) when it matters. - On a daily or weekly chart. Every bar starts a new day there, so the open line has nothing to draw: the script is meant for intraday charts.
Variations
With request.security(). The daily open and yesterday's levels can also come from the daily timeframe. Requesting the open with lookahead_on is safe because the day's open is known from its first bar, and the previous day's values are offset by [1]:
//@version=6
indicator("Daily levels from the daily timeframe", overlay = true)
[dOpen, yHigh, yLow] = request.security(syminfo.tickerid, "D", [open, high[1], low[1]], lookahead = barmerge.lookahead_on)
plot(dOpen, "Daily open", color.orange, 2, plot.style_stepline)
plot(yHigh, "Previous day high", color.teal, 1, plot.style_stepline)
plot(yLow, "Previous day low", color.red, 1, plot.style_stepline)
It costs one data request and always follows the exchange's day. The multi-timeframe guide explains when lookahead_on is safe and when it leaks the future. For trading windows within the day (London, New York, the overlap) see the session and time filter guide.
Questions
How do I get today's open price in Pine Script?
Store the open of the first bar of the day: var float dayOpen = na, then if timeframe.change("D") set dayOpen := open. Or request it: request.security(syminfo.tickerid, "D", open, lookahead = barmerge.lookahead_on).
How do I get yesterday's high and low in Pine Script?
Track the current day's high and low in var variables and copy them to prevHigh and prevLow when a new day starts, as in this script. Or request high[1] and low[1] from the "D" timeframe with lookahead_on.
How do I check the day of the week in Pine Script?
Compare the dayofweek variable with the constants: dayofweek == dayofweek.friday. It uses the exchange's time zone; for another one, use dayofweek(time, "America/New_York").
Related pages
Every script on this page was checked with Edgoro Pine Check (Pine Script v6 rules). Pine Check is a static checker, not TradingView's compiler: TradingView compiles the script when you save it in the Pine Editor. The scripts are examples to learn from, not trading systems. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.