John Smith
John Smith

Reputation: 187

Start of X-days prior

time("D",session.regular,syminfo.timezone)

This gives me start time of current day. How do I get start of the previous trading day or 2 trading days ago?

if I do the following for SPY, it gives me 01/08's start time (Sunday/non-trading day) instead of 01/06's start time (Friday/trading day)

int backDays = 1 // how many days to go back
time("D",session.regular,syminfo.timezone) - (86400000 * backDays)

Upvotes: 0

Views: 510

Answers (1)

Bjorn Mistiaen
Bjorn Mistiaen

Reputation: 6865

//@version=5
indicator("My script")

var int n = input.int(2, 'Show startTime for this many trading days ago', 0)

var int[] startTimes    = array.new<int>()
var label myLabel       = label.new(na, na, '', color=color.white, textcolor=color.black, style=label.style_label_center)

if timeframe.change('D')
    array.unshift(startTimes, time)

if barstate.islast
    t = array.get(startTimes, n)
    label.set_xy(myLabel, bar_index, high)
    label.set_text(myLabel, str.format('StartTime {0} trading days ago was {1}', n, str.format_time(t,'yyyy-MM-dd HH:mm')))

Edit 1
In response to this comment
Answers to the questions have been put into the code as comments.

//@version=5
indicator("My script")

// Timezone list can be found at https://www.tradingcode.net/tradingview/time-zone-names/
TZ0 = "Europe/Brussels", TZ1 = "Africa/Nairobi", TZ2 = "Asia/Thimbu"
ONE_DAY = 24 * 60 * 60 * 1000

// Chart timezone cannot be detected (yet), so we'll need an input for that.
var string  tz  = input.string(TZ0, 'TimeZone', options=[TZ0,TZ1,TZ2])
var int     n   = input.int(2, 'Show startTime for this many trading days ago', 0)

var int[] startTimes    = array.new<int>()
var int[] endTimes      = array.new<int>()
var label myLabel       = label.new(na, na, '', color=color.white, textcolor=color.black, style=label.style_label_center)

f_formatTime(_timestamp) => str.format_time(_timestamp, 'yyyy-MM-dd HH:mm', tz)

if timeframe.change('D')
    array.unshift(startTimes, time)
    // We can't get the end time of the current day, because it can't be known on beforehand due to trading days with reduced hours.
    // So we work around that by taking the closing time of the last bar of the previous session, and adding 1 day to it.
    array.unshift(endTimes, time_close[1] + ONE_DAY) 

if barstate.islast
    ts = array.get(startTimes, n)
    te = array.get(endTimes, n)
    label.set_xy(myLabel, bar_index, high)
    label.set_text(myLabel, str.format('{0} trading days ago\nStartTime = {1}\nEndTime = {2}\nTimezone = {3}', n, f_formatTime(ts) , f_formatTime(te), tz))

Edit 2
In response to this comment
Indeed there seems to be an anomaly when using certain timeframes.
Solved by using session.isfirstbar and session.islastbar. Those will change depending on whether your chart is in RTH (Regular Trading Hours) or ETH (Extended Trading Hours).
If you want to use only RTH hours, even when your chart is in ETH, you can use session.isfirstbar_regular and session.islastbar_regular.

//@version=5
indicator("My script")

// Timezone list can be found at https://www.tradingcode.net/tradingview/time-zone-names/
TZ0 = "Europe/Brussels", TZ1 = "Africa/Nairobi", TZ2 = "Asia/Thimbu", TZ3 = "America/New_York"
ONE_DAY = 24 * 60 * 60 * 1000

// Chart timezone cannot be detected (yet), so we'll need an input for that.
var string  tz  = input.string(TZ0, 'TimeZone', options=[TZ0,TZ1,TZ2,TZ3])
var int     n   = input.int(2, 'Show startTime for this many trading days ago', 0)

var int[] startTimes    = array.new<int>()
var int[] endTimes      = array.new<int>()
var label myLabel       = label.new(na, na, '', color=color.white, textcolor=color.black, style=label.style_label_center)

f_formatTime(_timestamp) => str.format_time(_timestamp, 'yyyy-MM-dd HH:mm', tz)

if session.isfirstbar
    array.unshift(startTimes, time)
else if session.islastbar
    // If we're on the last bar, we're at the end of that day. Record the closing time of that bar.
    array.unshift(endTimes, time_close)

if barstate.islast
    ts = array.get(startTimes, n)
    te = array.get(endTimes, n)
    label.set_xy(myLabel, bar_index, high)
    label.set_text(myLabel, str.format('{0} trading days ago\nStartTime = {1}\nEndTime = {2}\nTimezone = {3}', n, f_formatTime(ts) , f_formatTime(te), tz))

Upvotes: 1

Related Questions