时间
介绍
四个参考
在 Pine Script™ 中使用日期和时间值时,有四种不同的参考发挥作用:
- UTC 时区:Pine Script™ 中时间值的本机格式是Unix 时间(以毫秒为单位) 。Unix 时间是自1970 年 1 月 1 日 Unix 纪元以来经过的时间。请参阅此处了解 当前 Unix 时间(以秒为单位),并参阅此处了解有关Unix 时间的更多信息。Unix 时间的值称为时间戳。Unix 时间戳始终以 UTC(或“GMT”或“GMT+0”)时区表示。它们是从固定参考(即 Unix 纪元)测量的,并且不会因时区而变化。一些内置函数使用 UTC 时区作为参考。
- 交易所时区:交易者的第二项与时间相关的关键参考是交易工具交易所的时区。一些内置功能(如 小时 返回值)默认采用交易所的时区。
timezone
参数:某些函数通常会返回交易所时区的值,例如 hour() 包含一个timezone
参数,该参数允许您将函数的结果调整为另一个时区。其他函数(如 time()) 同时包含session
和timezone
参数。在这些情况下,timezone
参数适用于如何session
解释参数 — 而不是函数返回的时间值。- 图表的时区:这是用户使用“图表设置/符号/时区”字段从图表中选择的时区。此设置仅影响图表上日期和时间的显示。它不会影响 Pine 脚本的行为,并且它们对此设置没有可见性。
在讨论变量或函数时,我们会注意它们是否返回 UTC 或交易所时区的日期或时间。脚本无法查看用户图表上的时区设置。
时间内置
Pine Script™ 具有内置变量,可以:
- 从当前柱(UTC 时区)获取时间戳信息: time 和 time_close
- 获取当前交易日开始的时间戳信息(UTC时区): time_tradingday
- 以一秒为增量获取当前时间(UTC 时区): timenow
- 从栏目中检索日历和时间值(交换时区): 年、 月、 周、 月日、 星期、 时、 分 、 秒
- 使用syminfo.timezone返回图表符号的交易所的时区
还有一些内置函数可以:
- 使用time() 和 time_close()返回其他时间范围内的条形图时间戳 ,无需调用 request.security ()
- 从任何时间戳中检索日历和时间值,可以用时区偏移: year()、 month()、 weekofyear()、 dayofmonth()、 dayofweek()、 hour()、 minute() 和 second()
- 使用timestamp()创建时间戳
- 使用str.format()将时间戳转换为格式化的日期/时间字符串以供显示
- 输入数据和时间值。请参阅输入部分 。
- 使用会话信息。
时区
TradingViewers 可以更改用于在其图表上显示条形时间的时区。Pine 脚本无法查看此设置。虽然有一个
syminfo.timezone
变量可以返回交易图表工具的交易所的时区,但没有等效 chart.timezone
变量。
在图表上显示时间时,这显示了为用户提供一种调整脚本时间值以适应其图表时间值的方法。这样,您显示的时间就可以与交易者在其图表上使用的时区相匹配:
//@version=5
indicator("Time zone control")
MS_IN_1H = 1000 * 60 * 60
TOOLTIP01 = "Enter your time zone's offset (+ or −), including a decimal fraction if needed."
hoursOffsetInput = input.float(0.0, "Timezone offset (in hours)", minval = -12.0, maxval = 14.0, step = 0.5, tooltip = TOOLTIP01)
printTable(txt) =>
var table t = table.new(position.middle_right, 1, 1)
table.cell(t, 0, 0, txt, text_halign = text.align_right, bgcolor = color.yellow)
msOffsetInput = hoursOffsetInput * MS_IN_1H
printTable(
str.format("Last bar''s open time UTC: {0,date,HH:mm:ss yyyy.MM.dd}", time) +
str.format("\nLast bar''s close time UTC: {0,date,HH:mm:ss yyyy.MM.dd}", time_close) +
str.format("\n\nLast bar''s open time EXCHANGE: {0,date,HH:mm:ss yyyy.MM.dd}", time(timeframe.period, syminfo.session, syminfo.timezone)) +
str.format("\nLast bar''s close time EXCHANGE: {0,date,HH:mm:ss yyyy.MM.dd}", time_close(timeframe.period, syminfo.session, syminfo.timezone)) +
str.format("\n\nLast bar''s open time OFFSET ({0}): {1,date,HH:mm:ss yyyy.MM.dd}", hoursOffsetInput, time + msOffsetInput) +
str.format("\nLast bar''s close time OFFSET ({0}): {1,date,HH:mm:ss yyyy.MM.dd}", hoursOffsetInput, time_close + msOffsetInput) +
str.format("\n\nCurrent time OFFSET ({0}): {1,date,HH:mm:ss yyyy.MM.dd}", hoursOffsetInput, timenow + msOffsetInput))
注意:
- 我们使用 将以小时表示的用户偏移量转换为毫秒
msOffsetInput
。然后,我们将该偏移量添加到 UTC 格式的时间戳,然后将其转换为显示格式,例如time + msOffsetInput
和timenow + msOffsetInput
。 - 我们使用工具提示向用户提供说明。
- 我们提供
minval
和maxval
值来保护输入字段,以及step
0.5 的值,以便当他们使用字段的向上/向下箭头时,他们可以直观地知道可以使用分数。 - str.format () 函数格式化我们的时间值,即最后一根柱线的时间和当前时间。
一些通常返回交易所时区值的函数提供了通过参数使其结果适应另一个时区的方法
timezone
。此脚本说明了如何使用
hour()执行此操作:
//@version=5
indicator('`hour(time, "GMT+0")` in orange')
color BLUE_LIGHT = #0000FF30
plot(hour, "", BLUE_LIGHT, 8)
plot(hour(time, syminfo.timezone))
plot(hour(time, "GMT+0"),"UTC", color.orange)
注意:
- hour
变量和
hour()
函数通常返回交易所时区的值。因此,和
的蓝色图重叠。因此,如果需要交易所的小时数,使用带有函数形式是多余的。
hour
hour(time, syminfo.timezone)
syminfo.timezone
- 但是,绘制的橙色线
hour(time, "GMT+0")
返回的是 UTC 或“GMT+0”时间的小时数,在这种情况下比交易所的时间少四个小时,因为 MSFT 在时区为 UTC-4 的纳斯达克进行交易。
时区字符串
time()、
timestamp()、
hour()timezone
等函数中
用于参数的参数可以采用不同的格式,您可以在IANA 时区数据库名称
参考页面中找到这些格式。可以使用该页面表格中的“TZ 数据库名称”、“UTC 偏移 ±hh:mm ”和“UTC DST 偏移 ±hh:mm ”列中的内容。
为了表达与 UTC 相差 +5.5 小时的偏移量,参考页面中的这些字符串都是等效的:
"GMT+05:30"
"Asia/Calcutta"
"Asia/Colombo"
"Asia/Kolkata"
非分数偏移可以用以下"GMT+5"
形式表示。
"GMT+5.5"
是不允许的。
时间变量
`time` 和`time_close`
让我们首先绘制 time 和 time_close,即条形图开启和关闭时间的 Unix 时间戳(以毫秒为单位):
//@version=5
indicator("`time` and `time_close` values on bars")
plot(time, "`time`")
plot(time_close, "`time_close`")
注意:
- time 和 time_close变量返回UNIX 时间 中的时间戳,该时间戳与用户在图表上选择的时区无关。在这种情况下, 图表的时区设置是交易所时区,因此无论图表上的符号是什么,其交易所时区都将用于显示图表光标上的日期和时间值。纳斯达克的时区是 UTC-4,但这只会影响图表的日期/时间值显示;它不会影响脚本绘制的值。
- 刻度中显示的图表的最后 时间 值是从 1970 年 1 月 1 日 UTC 00:00:00 到该条形图的开盘时间经过的毫秒数。它对应于 2021 年 9 月 27 日 17:30。但是,由于图表使用 UTC-4 时区(纳斯达克的时区),因此它显示 13:30 的时间,比 UTC 时间早四个小时。
- 因为我们使用的是 1H 图,所以最后一根柱线上两个值之间的差值就是一小时内的毫秒数 (1000 * 60 * 60 = 3,600,000)。
`time_tradingday`
当交易品种在隔夜时段进行交易,而这些时段的开始和结束时间在不同日历日时, time_tradingday 非常有用。例如,这种情况发生在外汇市场中,交易时段可以在周日 17:00 开始,在周一 17:00 结束。
此变量在 1D 及以下时间范围内使用时,以UNIX 时间返回交易日开始的时间 。在高于 1D 的时间范围内使用时,它将返回柱状图中最后一个交易日的开始时间(例如,在 1W 时,它将返回一周中最后一个交易日的开始时间)。
`timenow`
timenow返回UNIX 时间 中的当前时间。它不仅在实时工作,而且在脚本在历史条上执行时也工作。实时情况下,您的脚本只有在执行 feed 更新时才会感知到变化。当没有更新发生时,脚本处于空闲状态,因此无法更新其显示。有关更多信息,请参阅 Pine Script™执行模型页面 。
此脚本使用timenow 和 time_close的值 来计算日内柱的实时倒计时。与图表上的倒计时相反,只有当 feed 更新导致脚本执行另一次迭代时,此倒计时才会更新:
//@version=5
indicator("", "", true)
printTable(txt) =>
var table t = table.new(position.middle_right, 1, 1)
table.cell(t, 0, 0, txt, text_halign = text.align_right, bgcolor = color.yellow)
printTable(str.format("{0,time,HH:mm:ss.SSS}", time_close - timenow))
日历日期和时间
日历日期和时间变量(例如 年、 月、 年周、 月日、 星期几、 时、 分 和 秒) 可用于测试特定的日期或时间,也可以作为 timestamp()的参数。
在测试特定日期或时间时,需要考虑脚本在无法检测到测试条件的时间范围内执行的可能性,或者不存在具有特定要求的条形图的情况。例如,假设我们想要检测每月的第一个交易日。此脚本显示了 当使用周线图或每月 1 日没有交易时,仅使用dayofmonth将不起作用:
//@version=5
indicator("", "", true)
firstDayIncorrect = dayofmonth == 1
firstDay = ta.change(time("M"))
plotchar(firstDayIncorrect, "firstDayIncorrect", "•", location.top, size = size.small)
bgcolor(firstDay ? color.silver : na)
注意:
- 使用
ta.change(time("M"))
更为强大,因为它适用于所有月份(#1 和 #2),显示为银色背景,而dayofmonth == 1
当 9 月的第一个交易日发生在 2 号时,使用检测到的蓝点不起作用(#1)。 - 此
dayofmonth == 1
条件将适用true
于每月第一天的所有条形图内,但ta.change(time("M"))
仅限true
于第一天。
如果您希望脚本仅显示 2020 年及以后的年份,则可以使用:
//@version=5
indicator("", "", true)
plot(year >= 2020 ? close : na, linewidth = 3)
`syminfo.timezone()`
syminfo.timezone
返回图表符号交易所的时区。当timezone
函数中有参数可用时,它会很有帮助,并且您想要明确说明您正在使用交易所的时区。它通常是多余的,因为当没有提供参数时timezone
,会假定交易所的时区。
时间函数
`time()` 和`time_close()`
time () 和 time_close() 函数具有以下签名:
他们接受了三种论点:
timeframe
session
"hhmm-hhmm[:days]"
,其中部分是可选的。有关更多信息,请参阅会话[:days]
页面。
timezone
session
一个可选值,用于限定使用时的参数。
请参阅 参考手册中的time() 和 time_close()条目以了解更多信息。
time () 函数最常用于:
- 测试某个条形图是否处于特定时间段内,这将需要使用参数
session
。在这些情况下,图表的时间范围通常用作第一个参数。当以这种方式使用该函数时,我们依赖于这样一个事实 :当条形图不属于参数中指定的时间段时,timeframe.period
它将返回 nasession
。 - 通过使用更高时间范围作为参数来检测比图表更高时间范围的变化
timeframe
。当将函数用于此目的时,我们会寻找返回值的变化,这意味着更高时间范围的条形图已发生变化。这通常需要使用 ta.change() 进行测试,例如,ta.change(time("D"))
当出现新的更高时间范围的条形图时,将返回时间变化,因此在条件表达式中使用时,表达式的结果将转换为“bool”值。“bool”结果将是true
发生变化时和false
没有变化时的结果。
会话测试
让我们看第一种情况的例子,我们想要确定某个条形图的开始时间是否属于 11:00 至 13:00 之间的时间段:
//@version=5
indicator("Session bars", "", true)
inSession = not na(time(timeframe.period, "1100-1300"))
bgcolor(inSession ? color.silver : na)
注意:
- 我们使用
time(timeframe.period, "1100-1300")
,其含义是:“检查图表的时间范围,看当前柱的开盘时间是否在 11:00 至 13:00 之间(含)。如果柱处于会话中,则函数返回其开盘时间。如果不是,则函数返回 na。 - 我们感兴趣的是识别time()
不返回
na 的情况,
因为这意味着该条处于会话中,因此我们测试
。当time()的实际返回值
不是
na
not na(...)
时,我们不使用它 ;我们只关心它是否返回 na 。
测试更高时间范围内的变化
检测更高时间范围内的变化通常很有帮助。例如,您可能希望在日内图表上检测交易日的变化。对于这些情况,您可以使用time("D")
返回 1D 条的开盘时间的事实,即使图表处于日内时间范围内(例如 1H):
//@version=5
indicator("", "", true)
bool newDay = ta.change(time("D"))
bgcolor(newDay ? color.silver : na)
newExchangeDay = ta.change(dayofmonth)
plotchar(newExchangeDay, "newExchangeDay", "🠇", location.top, size = size.small)
注意:
- 该
newDay
变量检测 1D 柱的开盘时间变化,因此它遵循图表符号的惯例,即使用 17:00 至 17:00 的隔夜时段。当新时段开始时,它会更改值。 - 因为
newExchangeDay
检测 日历日中日期的变化 ,所以当图表上的日期变化时它也会变化。 - 两种变化检测方法仅在图表上有无交易日时才会一致。例如,这里的星期日,两种检测方法都会检测到变化,因为日历日从最后一个交易日(星期五)变为新一周的第一个日历日,即星期日,也就是星期一的隔夜交易时段从 17:00 开始。
日历日期和时间
日历日期和时间函数(例如 year()、 month()、 weekofyear()、 dayofmonth()、 dayofweek()、 hour()、 minute() 和 second() )可用于测试特定日期或时间。它们都具有与此处显示的dayofmonth() 类似的签名 :
这将绘制 2021 年 1 月 1 日 00:00 时间位于其time 和 time_close 值之间的柱状图的开盘日期 :
//@version=5
indicator("")
exchangeDay = dayofmonth(timestamp("2021-01-01"))
plot(exchangeDay)
该值将为 31 日或 1 日,具体取决于图表符号上的会话开始的日历日。对于使用 UTC 时区的交易所全天候交易的符号,日期将为 1 日。对于在 UTC-4 交易所交易的符号,日期将为 31 日。
`时间戳()`
timestamp () 函数有几个不同的签名:
前两者之间的唯一区别是timezone
参数。其默认值为
syminfo.timezone。有关有效值,请参阅本页的时区字符串部分。
第三种形式用作input.time()defval
中的值
。
有关更多信息,请参阅参考手册中的timestamp()条目。
timestamp() 可用于生成特定日期的时间戳。要生成 2021 年 1 月 1 日的时间戳,请使用以下任一方法:
//@version=5
indicator("")
yearBeginning1 = timestamp("2021-01-01")
yearBeginning2 = timestamp(2021, 1, 1, 0, 0)
printTable(txt) => var table t = table.new(position.middle_right, 1, 1), table.cell(t, 0, 0, txt, bgcolor = color.yellow)
printTable(str.format("yearBeginning1: {0,date,yyyy.MM.dd hh:mm}\nyearBeginning2: {1,date,yyyy.MM.dd hh:mm}", yearBeginning1, yearBeginning1))
您可以在
timestamp()
参数中使用偏移量。在这里,我们从为其参数提供的值中减去 2,day
以获取两天前图表最后一根柱线的日期/时间。请注意,由于各种工具上的柱线对齐方式不同,图表上标识的柱线可能并不总是正好是 48 小时后,尽管函数的返回值是正确的:
//@version=5
indicator("")
twoDaysAgo = timestamp(year, month, dayofmonth - 2, hour, minute)
printTable(txt) => var table t = table.new(position.middle_right, 1, 1), table.cell(t, 0, 0, txt, bgcolor = color.yellow)
printTable(str.format("{0,date,yyyy.MM.dd hh:mm}", twoDaysAgo))
格式化日期和时间
可以使用str.format()格式化时间戳 。以下是各种格式的示例:
//@version=5
indicator("", "", true)
print(txt, styl) =>
var alignment = styl == label.style_label_right ? text.align_right : text.align_left
var lbl = label.new(na, na, "", xloc.bar_index, yloc.price, color(na), styl, color.black, size.large, alignment)
if barstate.islast
label.set_xy(lbl, bar_index, hl2[1])
label.set_text(lbl, txt)
var string format =
"{0,date,yyyy.MM.dd hh:mm:ss}\n" +
"{1,date,short}\n" +
"{2,date,medium}\n" +
"{3,date,long}\n" +
"{4,date,full}\n" +
"{5,date,h a z (zzzz)}\n" +
"{6,time,short}\n" +
"{7,time,medium}\n" +
"{8,date,'Month 'MM, 'Week' ww, 'Day 'DD}\n" +
"{9,time,full}\n" +
"{10,time,hh:mm:ss}\n" +
"{11,time,HH:mm:ss}\n" +
"{12,time,HH:mm:ss} Left in bar\n"
print(format, label.style_label_right)
print(str.format(format,
time, time, time, time, time, time, time,
timenow, timenow, timenow, timenow,
timenow - time, time_close - timenow), label.style_label_left)