保持敬畏之心
交易是一场持久战

Pine Script(112):判断季度周期、1小时上下与日线及以上周期

#Pine Script入门教学

判断脚本是否运行在季度时间周期上

目前,Pine Script 还没有一个内置变量能直接指明,脚本当前是否运行在一个完整的季度级别的时间周期上,例如3个月、6个月、9个月、12个月等等。

然而,获取这个信息可能很有帮助。例如,我们可能要求图表必须是季度图,以便与后台加载的财务数据相匹配;或者我们想在季度图上,使用与年线图上不同的脚本参数。

为了实现这些功能,Pine Script 必须能判断当前是否运行在季度图上。接下来就让我们看看如何用代码实现这个判断。


自定义函数

要判断一个 TradingView 脚本是否运行在完整的季度时间周期上,我们需要结合两个时间周期变量:

  1. timeframe.ismonthly 变量必须为 true。这是因为 TradingView 使用月度数据来构建季度图,所以这个要求必须首先满足。
  2. 其次,timeframe.multiplier 变量的数值必须是 3 的倍数。这个变量返回时间周期的数值。当它的值不是3、6、9、12等月份时,那么该图表就不是一个完整的季度图。

为了方便代码复用,我们将这两个变量组合成一个自定义函数,它看起来是这样的:

// IsQuarterlyTF() 函数用于判断脚本的时间周期是否为一个
// 完整的季度(3M, 6M, 9M, 12M等)。如果是,则返回'true',否则返回'false'。
// 注意:该函数适用于所有图表类型,包括基于价格的图表。
IsQuarterlyTF() =>
	timeframe.ismonthly and timeframe.multiplier % 3 == 0

这个 IsQuarterlyTF() 函数在脚本运行在季度时间周期上时会返回 true。而在其他的月度图(例如4个月和11个月图)、以及周线日线和所有日内时间周期上,它都会返回 false

在函数内部,我们首先检查 timeframe.ismonthly。这个变量只在图表是由月度数据构成时才返回 true,否则返回 false

但并非所有月度图都是季度图,这就需要用到第二部分的代码。timeframe.multiplier 变量可以获取图表的时间周期数值。由于我们寻找的是完整的季度,我们使用模数运算符 (%) 来测试 timeframe.multiplier 是否能被 3 整除。

因此,我们将“图表使用月度数据” (timeframe.ismonthly) 和“其周期是3的倍数”这两个条件通过 and 运算符组合起来。这使得该函数只对完整的季度时间周期返回 true,而对任何其他时间周期,包括分钟图小时图年线图,都返回 false


函数特性

IsQuarterlyTF() 函数具有以下几个有趣的特性:

  • 该函数同样适用于基于价格的图表(如平均K线图、砖块图等)。这似乎有些反直觉,但 TradingView 在构建它们时,仍然会基于一个具有特定时间间隔的底层数据。这个底层数据的时间间隔,正是 timeframe.ismonthlytimeframe.multiplier 变量所检查的。
    • 因此,对于平均K线图 (Heikin Ashi)砖块图 (Renko)折线图 (Line Break)卡吉图 (Kagi)点数图 (Point & Figure),该函数会基于其图表的底层时间周期来返回 truefalse
  • 然而,对于等量图 (Range),该函数总是返回 false。这是因为无论我们如何选择范围,TradingView 都是使用1分钟数据来构建等量图的,因此它们永远不会使用到季度数据。
  • IsQuarterlyTF() 不仅可以判断当前图表的时间周期,我们还可以将这个函数传递给 request.security() 函数。这样做可以让我们判断,在后台加载的那个数据是否在季度数据上进行计算。

函数应用示例

要使用自定义的 IsQuarterlyTF() 函数,我们首先将其复制粘贴到我们的 TradingView 脚本中。然后有几种方法可以使用它。

场景一:判断是否为季度图

我们可以测试 IsQuarterlyTF() 是否返回 true 来判断图表是否为季度图。如果是,就可以(举例来说)创建一个文本标签:

// 测试图表是否使用了完整的季度时间周期(3M, 6M, 9M等)
if IsQuarterlyTF()
	label.new(bar_index, high, text="This chart has a whole quarter time frame")

场景二:判断是否不是季度图

另一个选项是,测试时间周期不是季度图。这会包括非3倍数的月度图,以及周线、日线和所有日内时间周期。

为此,我们只需在函数前加上 not 运算符即可。它会反转函数的布尔结果:

// 测试图表是否不是一个完整的季度时间周期
if not IsQuarterlyTF()
	label.new(bar_index, close, text="This isn't a quarterly time frame")

除了 if 语句,switch 语句和条件运算符 (?:) 也可以使用 IsQuarterlyTF()。实际上,任何 Pine Script 接受布尔值的地方,我们都可以使用该函数。

场景三:根据条件设置背景色

假设我们想在季度图上,为图表背景设置一个特定的紫色。我们可以这样使用 bgcolor() 函数:

// 当时间周期是一个完整的季度时,将背景设为紫色
bgcolor(IsQuarterlyTF() ? color.new(color.purple, 90) : na)

完整示例脚本

让我们通过一个完整的脚本来看看如何应用 IsQuarterlyTF() 函数。下方的指标会绘制一个文本框,用以说明当前图表是否为季度时间周期。当我们更改图表的时间周期时,这个文本框的内容也会随之改变。

该指标的完整代码如下:

//@version=5
indicator(title="Quarterly time frame", overlay=true)

// IsQuarterlyTF() 函数用于判断脚本的时间周期是否为一个
// 完整的季度(3M, 6M, 9M, 12M等)。如果是,则返回'true',否则返回'false'。
// 注意:该函数适用于所有图表类型,包括基于价格的图表。
IsQuarterlyTF() =>
	timeframe.ismonthly and timeframe.multiplier % 3 == 0

// 在最后一根已确认的历史K线上,检查图表是否使用了季度
// 时间周期,并在一个文本框中报告这个结果。
if barstate.islastconfirmedhistory
    boxText = if IsQuarterlyTF()
        "This chart uses a full quarter time frame"
    else
        "This chart isn't a quarterly time frame chart"

    box.new(bar_index + 3, close * 1.05, bar_index + 23, close * 0.95, 
         bgcolor=#DBD7D2, border_color=color.orange, text=boxText, 
         text_size=size.large, text_wrap=text.wrap_auto)

代码解析

我们首先调用 indicator() 函数,这会为脚本命名,并使其叠加显示在主图的交易品种上。

然后,我们包含了上文讨论过的 IsQuarterlyTF() 自定义函数。

接下来,一个 if 语句评估 barstate.islastconfirmedhistory 变量。该变量只在图表的最后一根已确认的历史K线上才为 true。这个检查确保了 if 语句内的代码只执行一次。在这根K线上,我们做了两件事:

首先,一个 if/else 语句用于决定文本框的显示内容。我们判断的条件就是 IsQuarterlyTF() 函数。当该函数返回 true 时,我们使用的文本会说明图表是一个完整的季度周期;否则,else 部分的文本则会说明它不是一个季度图。我们将选定的文本存入 boxText 变量,以备后用。

然后,box.new() 函数创建了实际的文本框。它的左上角坐标被设在未来3根K线、比当前收盘价高5%的位置 (bar_index + 3, close * 1.05)。其右下角坐标则在再往后30根K线、比收盘价低5%的位置。

文本框的背景色我们使用 #DBD7D2,即 timberwolf grey(一种灰褐色)的十六进制颜色代码,边框则使用橘色 (color.orange)。其文本内容就是我们刚才创建的 boxText 变量,并以大号字体 (size.large) 显示。我们还让 TradingView 自动换行文本框内的文字 (text.wrap_auto)。

让我们看看脚本在图表上的实际效果。在一个季度时间周期上,脚本会如实地告诉我们关于图的信息:

在一个非完整季度的时间周期上,脚本也会通过它的文本框指明这一点:


内容总结

要判断一个时间周期是否为完整的季度(3个月、6个月、9个月等),我们需要结合两个条件:

  1. timeframe.ismonthly 变量必须为 true,因为 TradingView 使用月度数据来构建季度时间周期。
  2. 并且,timeframe.multiplier 变量的数值需要是 3 的倍数,因为三个月构成一个季度。我们通过模数运算符 (%) 来进行这个判断。

判断时间周期高于还是低于1小时

TradingView 脚本可以运行在任何时间周期上。有时,如果能知道当前图表的分辨率是高于还是低于某个特定的时间周期阈值,将会非常有帮助。

例如,我们可能有一个交易思路,它在高时间周期上表现不佳;或者我们不想在一个非常低的时间周期上生成警报。

创建这样一个过滤器的一种方法,就是判断脚本当前的时间周期是否在1小时之上(或之下)。接下来就让我们看看如何实现。


自定义函数

要知道一个脚本是否运行在1小时或更高的时间周期上,我们首先获取当前时间周期的总时长,然后将其与1小时的总时长进行比较。

实现这一点的一个快捷方法是使用 Pine Script 的 timeframe.in_seconds() 函数。这个函数有两种用法:不带参数时,它返回当前图表时间周期的总秒数;带有一个时间周期字符串参数时,它则返回该时间周期的总秒数。由于两种情况下我们得到的都是秒数,这使得它们非常适合进行比较。

为了方便代码复用,让我们创建一个自定义函数,用于测试脚本是否运行在1小时或更高的时间周期上:

// IsHourOrHigherTF() 函数用于判断脚本的时间周期是否为
// 1小时或更高。如果是,则返回'true',否则返回'false'。
// 注意:该函数也适用于非标准图表(如平均K线图和
// 砖块图),它们也是基于具有特定分辨率的数据构建的。
IsHourOrHigherTF() =>
	timeframe.in_seconds() >= timeframe.in_seconds("60")

这个 IsHourOrHigherTF() 自定义函数,当脚本运行在1小时或更高的时间周期上时,会返回 true;而对于低于1小时的时间周期,我们则会得到一个 false 值。

在函数内部,我们将当前脚本的时间周期与1小时的时间周期进行比较。我们通过调用不带参数的 timeframe.in_seconds() 函数来获取前者。而1小时时间周期的总秒数,我们则通过向同一个函数传入 "60" 这个时间周期字符串来获取。

当当前时间周期的总秒数大于或等于 (>=) 1小时时间周期的总秒数时,IsHourOrHigherTF() 函数便会返回 true;对于低于1小时的时间周期,该函数则返回 false


函数特性

IsHourOrHigherTF() 函数具有以下几个值得了解的特性:

  • 该函数适用于任何基于时间的图表,无论是30秒、15分钟、5天还是12个月的图表。
  • 并且该函数也适用于基于价格的图表。虽然这些图表(如平均K线图、砖块图等)没有固定的时间间隔,但 TradingView 在构建它们时,仍然会基于一个具有特定时间间隔的底层数据。这个底层数据的时间间隔,正是 IsHourOrHigherTF() 所捕捉的。
  • 等量图 (Range) 上,该函数总是返回 false。这是因为 TradingView 使用1分钟数据来构建所有的等量图,无论我们设置的范围(range)是多少。
  • 当我们将 IsHourOrHigherTF() 传递给 request.security() 函数时,可以判断在后台加载的那个数据是否在高于或低于1小时的时间周期上进行计算。

函数应用示例

在我们将 IsHourOrHigherTF() 函数复制粘贴到脚本中后,便可以通过多种方式来使用它。

场景一:判断是否为小时或以上周期

要判断脚本是否运行在高于1小时的时间周期上,我们可以测试该函数的返回值是否为 true。如果是,就可以创建一个文本标签来显示这个信息:

// 判断脚本的时间周期是否为60分钟或更高,
// 如果是,则创建一个标签。
if IsHourOrHigherTF()
	label.new(bar_index, high, text="Time frame is 1 hour or higher!")

场景二:判断是否不是小时或以上周期

要找出时间周期不是1小时或更高的情况,我们可以在 IsHourOrHigherTF() 函数前加上 not 逻辑运算符,就像这样:

// 测试脚本是否没有运行在小时或更高的时间周期上。
// 这个 'not' 测试在所有低于1小时的时间周期上都为true。
if not IsHourOrHigherTF()
	label.new(bar_index, high, text="Time frame is less than 1 hour.")

当然,我们也可以将 IsHourOrHigherTF() 函数与 switch 语句和条件运算符 (?:) 结合使用。

场景三:根据条件设置背景色

例如,假设我们想在时间周期为1小时及以上时,将背景设为橘色;而在低于1小时的时间周期上,则使用蓝色背景。在这种情况下,我们可以将 IsHourOrHigherTF()bgcolor() 函数这样结合起来:

// 当图表的时间周期为1小时或更高时,使其背景为橘色,
// 否则使用蓝色。
bgcolor(IsHourOrHigherTF() ? color.new(color.orange, 90) : 
	 color.new(color.blue, 90))

完整示例脚本

让我们通过一个完整的脚本来看看如何应用 IsHourOrHigherTF() 函数。下方的指标会创建一个文本标签,用以说明当前图表是否使用了高于1小时的时间周期。当我们更改图表的时间周期时,这个标签的信息也会随之更新。

该指标的完整代码如下:

//@version=5
indicator(title="Time frame above/under 1 hour", overlay=true)

// IsHourOrHigherTF() 函数用于判断脚本的时间周期是否为
// 1小时或更高。如果是,则返回'true',否则返回'false'。
// 注意:该函数也适用于非标准图表(如平均K线图和
// 砖块图),它们也是基于具有特定分辨率的数据构建的。
IsHourOrHigherTF() =>
	timeframe.in_seconds() >= timeframe.in_seconds("60")

// 在图表的最后一根已确认的历史K线上,测试图表的时间周期
// 是否高于1小时(并在一个标签中显示结果)。
if barstate.islastconfirmedhistory
    labelText = if IsHourOrHigherTF()
        "This chart's time frame is\none hour or higher!"
    else
        "This chart has a\ntime frame below 1 hour."

    label.new(bar_index + 3, hl2, style=label.style_label_left,
         color=#E6E6FA, size=size.large, text=labelText)

代码解析

我们首先使用 indicator() 函数,这会为脚本命名并将其放置在主图的交易品种之上。

然后,我们包含了上文讨论过的 IsHourOrHigherTF() 自定义函数。

之后,一个 if 语句检查 barstate.islastconfirmedhistory。该变量只在图表的最后一根已确认的历史K线上才为 true。当脚本运行到该K线时,我们做两件事:

首先,我们创建标签的文本。为此,一个 if/else 语句会判断 IsHourOrHigherTF() 函数的返回值。当函数返回 true 时,我们创建一段字符串,说明图表的时间周期是一小时或更高。否则,当函数返回 false 时,我们知道时间周期在1小时以下,并相应地设置字符串的文本。

然后,label.new() 函数创建这个文本标签。这个绘图对象会显示在未来三根K线的位置 (bar_index + 3),其价格坐标则位于K线的中点 (hl2)。它的箭头指向左边 (label.style_label_left)。对于背景,我们使用 #E6E6FA,即薰衣草蓝的十六进制颜色值。size.large 使文本标签比常规尺寸更大。我们用之前创建的 labelText 变量来设置标签的文本。

让我们看看该指标在图表上的实际效果。在一个2小时的日内时间周期上,该脚本显示:

当我们把图表切换到一个15分钟的时间周期时,该指标显示:


内容总结

  • timeframe.in_seconds() 函数可以告诉我们脚本当前时间周期的总秒数。
  • 当我们将这个时长与某个阈值进行比较时,就能判断出时间周期是在该水平之上还是之下。
  • 对于1小时或更高的图表,其总秒数必须大于或等于 timeframe.in_seconds("60") 所返回的值。

判断脚本是否运行在日线及以上时间周期

TradingView 脚本可以运行在多种时间周期上。然而,一些交易思路在特定的时间周期上表现最佳,而其他时间周期则可能完全不适用。例如,一个快速的剥头皮策略,在日线图上就行不通。

但要做出这种区分,我们的代码必须能判断出当前图表的时间周期是否为日线或更高。接下来,就让我们在 Pine Script 中实现这个功能。


自定义函数

要判断一个脚本是否使用1天或更高的时间周期,我们首先检查脚本当前的时间周期,然后将其与1天的时长进行比较。当脚本使用的K线时长等于或高于1天时,我们就能确定它运行在日线或以上的时间周期。

为了进行这种比较,我们使用 timeframe.in_seconds() 函数。这个函数有两种用法:它可以返回当前脚本所运行时间周期的总秒数,也可以返回任何指定时间周期的总秒数。由于两种情况下我们得到的都是秒数,这使得它们非常适合进行比较。

为了方便代码复用,让我们创建一个自定义函数,用于测试脚本是否运行在1天或更高的时间周期上:

// IsDayOrHigherTF() 函数用于检查脚本的时间周期是否为1天或更高。
// 如果是,则返回'true',对于更低的时间周期则返回'false'。
// 注意:该函数适用于所有图表类型,包括非标准图表(如
// 平均K线图和折线图)。
IsDayOrHigherTF() =>
    timeframe.in_seconds() >= timeframe.in_seconds("D")

这个 IsDayOrHigherTF() 自定义函数会返回以下两个值之一:如果脚本在1天或更高的时间周期上计算,该函数返回 true;如果时间周期低于1天,我们则会得到一个 false 值。

函数的代码将当前脚本的时间周期与1天时间周期的时长进行了比较。对于前者,我们调用不带参数的 timeframe.in_seconds() 函数。要获取后者的值,我们则向同一个函数传入 "D" 这个时间周期字符串参数,它会返回一个日线时间周期的总秒数。

然后,我们判断当前脚本的时间周期是否大于或等于 (>=) 一个日线时间周期。如果脚本确实运行在1天或更高的周期上,表达式返回 true。否则,对于低于1天的时间周期,该函数则返回 false


函数特性

IsDayOrHigherTF() 函数具有以下几个值得了解的特性:

  • 该函数适用于任何基于时间的图表,例如15秒、30分钟、8小时、7天和6个月。
  • 它也适用于基于价格的图表(如平均K线图、砖块图等)。尽管我们没有为这些图表配置固定的时间间隔,但 TradingView 在构建它们时,仍然会基于一个具有特定时间间隔的底层数据。这个底层数据的时间间隔,正是 IsDayOrHigherTF() 函数所检查的。
  • 等量图 (Range) 上,IsDayOrHigherTF() 总是返回 false。这是因为 TradingView 使用1分钟数据来构建所有的等量图。
  • 除了判断当前图表,我们也可以将这个函数传递给 request.security() 函数,从而判断在后台加载的数据是否在日线或更高的时间周期上进行计算。

函数应用示例

在我们将 IsDayOrHigherTF() 函数复制粘贴到脚本中后,便可以通过多种方式来使用它。

场景一:判断是否为日线或以上周期

要测试脚本是否运行在日线或更高的图表上,我们可以判断该函数是否返回 true。如果是,就可以创建一个文本标签来显示这个信息:

// 判断脚本的时间周期是否为1天或更高
if IsDayOrHigherTF()
	label.new(bar_index, high, text="Time frame is 1 day or higher!")

场景二:判断是否不是日线或以上周期

另一个选项是,明确地测试时间周期不是日线或更高。为此,我们只需在函数前加上 not 逻辑运算符即可:

// 验证时间周期不是一天或更高(即低于1天)
if not IsDayOrHigherTF()
	label.new(bar_index, hl2, text="Time frame is less than 1 day")

当然,我们也可以将该函数与 switch 语句和条件运算符 (?:) 结合使用。

场景三:根据条件设置背景色

假设我们想在图表的时间周期为1天或更高时,为背景设置颜色。我们可以这样调用 bgcolor() 函数:

// 当时间周期是一天或更高时,将图表背景设为紫红色
bgcolor(IsDayOrHigherTF() ? color.new(color.fuchsia, 90) : na)

完整示例脚本

让我们通过一个完整的脚本来看看如何应用 IsDayOrHigherTF() 函数。下方的指标会通过一个文本标签,告诉我们当前图表的时间周期是否为1天或更高。当我们更改图表的时间周期时,这个标签的文本也会随之改变。

该指标的完整代码如下:

//@version=5
indicator(title="Time frame above/under 1 day", overlay=true)

// IsDayOrHigherTF() 函数用于检查脚本的时间周期是否为1天或更高。
// 如果是,则返回'true',对于更低的时间周期则返回'false'。
// 注意:该函数适用于所有图表类型,包括非标准图表(如
// 平均K线图和折线图)。
IsDayOrHigherTF() =>
    timeframe.in_seconds() >= timeframe.in_seconds("D")

// 在最后一根已确认的历史K线上,判断时间周期是否为一天
// 或更高,并在一个标签中显示结果。
if barstate.islastconfirmedhistory
    labelText = if IsDayOrHigherTF()
        "This chart has a time frame of\n1 day or higher."
    else
        "This chart's time frame is\nless than 1 day."

    label.new(bar_index + 3, close, style=label.style_label_left,
         color=#FFFFED, size=size.large, text=labelText)

代码解析

我们首先使用 indicator() 函数,这会为脚本命名并将其叠加在主图上。

接着,我们包含了 IsDayOrHigherTF() 自定义函数。然后,一个 if 语句检查 barstate.islastconfirmedhistory 变量。该变量只在图表的最后一根已确认的历史K线上才为 true,这是一种确保 if 语句内的代码只执行一次的便捷方法。在这个 if 语句内部,我们做了两件事:

首先,我们创建了 labelText 变量。它的值由一个 if/else 语句来设定。判断的条件就是 IsDayOrHigherTF() 函数。当该函数返回 true 时,变量的文本会说明脚本使用的是1天或更高的时间周期;否则,else 部分的代码会告诉我们时间周期低于1天。

最后,我们使用 label.new() 函数来创建文本标签。这个标签会显示在未来三根K线的位置 (bar_index + 3),其价格坐标则与收盘价 (close) 对齐。它的箭头指向左边 (label.style_label_left),背景色为 #FFFFED(淡黄色的十六进制颜色代码)。标签的文本就是我们之前创建的 labelText 变量,并以大号字体 (size.large) 显示。

当我们在一个4小时的日内图表上运行该指标时,它会正确地指出时间周期低于1天:

如果我们把图表切换到日线,该脚本会告诉我们时间周期是1天或更高:


内容总结

  • 要判断代码是否在日线级别的数据上运行,我们首先使用 timeframe.in_seconds() 函数获取其当前时间周期的总秒数。
  • 然后,使用同一个函数来找出一条日线K线所包含的总秒数。
  • 当脚本的时间周期时长,大于或等于1天的时长时,它使用的就是一个日线或更高的图表分辨率。
赞(0)
未经允许不得转载:图道交易 » Pine Script(112):判断季度周期、1小时上下与日线及以上周期
分享到

评论 抢沙发

登录

找回密码

注册