警报

介绍

TradingView 警报在我们的服务器上全天候运行,无需用户登录即可执行。警报是从图表用户界面 ( UI ) 创建的。您将在帮助中心的关于 TradingView 警报页面中找到了解警报如何工作以及如何从图表 UI 创建警报所需的所有信息

TradingView 上可用的某些警报类型(通用警报绘图警报和订单执行事件的脚本警报)是根据图表上加载的符号或脚本创建的,不需要特定编码。任何用户都可以从图表 UI 创建这些类型的警报。

其他类型的警报(alert() 函数调用时触发的脚本警报和alertcondition() 警报)要求脚本中存在特定的 Pine Script™ 代码来创建警报事件,然后脚本用户才能使用图表 UI 从中创建警报。此外,虽然脚本用户可以从图表 UI 上在其图表上加载的任何策略上创建在订单填写事件上触发的脚本警报,但程序员可以在其脚本中为经纪人模拟器填写的每种订单类型指定明确的订单填写警报消息。

本页介绍了 Pine Script™ 程序员编写脚本以创建警报事件的不同方式,脚本用户反过来可以从图表 UI 创建警报。我们将介绍:

  • 如何使用 alert() 函数在指标或策略中调用alert() 函数,然后将其包含在从图表 UI 创建的脚本警报中。
  • 如何添加自定义警报消息以包含在策略订单填写事件 触发的脚本警报中。
  • 如何使用 alertcondition() 函数(仅在指标中)生成alertcondition() 事件, 然后可使用这些事件从图表 UI创建alertcondition() 警报。

请记住:

  • 没有与警报相关的 Pine Script™ 代码可以在图表 UI 中创建正在运行的警报;它仅创建警报事件,然后脚本用户可以使用这些事件从图表 UI 创建正在运行的警报。
  • 警报仅在实时条形图中触发。因此,处理任何类型的警报的 Pine Script™ 代码的操作范围仅限于实时条形图。
  • 在图表 UI 中创建警报时,TradingView 会保存脚本及其输入的镜像,以及图表的主要符号和时间范围,以便在其服务器上运行警报。因此,对脚本输入或图表的后续更改不会影响之前从它们创建的正在运行的警报。如果您希望对上下文的任何更改都反映在正在运行的警报的行为中,则需要删除警报并在新上下文中创建新警报。

背景

Pine 程序员如今可以使用各种方法来在脚本中创建警报事件,这是 Pine Script™ 演变过程中不断改进的结果。alertcondition () 函数仅适用于指标,是允许 Pine Script™ 程序员创建警报事件的第一个功能。然后是策略的订单执行警报,当经纪商模拟器创建 订单执行事件时触发。订单执行事件不需要脚本用户为其创建警报的特殊代码,但通过alert_message 订单生成函数的参数,程序员可以通过为任意数量的订单履行事件定义不同的警报消息来自定义订单执行事件触发strategy.*()的警报消息。

alert () 函数是 Pine Script™ 的最新添加功能。它或多或少取代了 alertcondition() ,并且在策略中使用时,为订单填写事件警报提供了有用的补充

哪种类型的警报最好?

对于 Pine Script™ 程序员来说, alert() 函数通常更易于使用且更灵活。与 alertcondition()相反,它允许动态警报消息,适用于指标和策略,程序员可决定 alert() 事件的频率。

虽然 可以在 Pine 中可编程的任何逻辑上生成alert()调用,包括在策略中将订单发送到经纪商模拟器时,但它们不能被编码为在订单执行(或填写)时触发,因为在订单发送到经纪商模拟器后,模拟器控制其执行并且不会直接将填写事件报告回脚本。

当脚本用户想要针对策略的订单执行事件生成警报时,他必须 在“创建警报”对话框中创建针对该策略的脚本警报alert_message时包含这些事件。脚本中无需特殊代码即可让用户执行此操作。但是,程序员可以通过使用订单生成 strategy.*()函数调用中的参数来自定义订单执行事件发送的消息。通过结合使用 alert() 调用和alert_message订单生成调用中的自定义参数strategy.*(),程序员可以在脚本执行过程中发生的大多数情况下生成警报事件。

alertcondition () 函数保留在 Pine Script™ 中以实现向后兼容,但它也可以有利地用于生成可在“创建警报”对话框的“条件”字段中作为单独项目进行选择的不同警报。

脚本警报

当脚本用户使用“创建警报”对话框创建脚本警报时,能够触发警报的事件将根据警报是从指标还是策略创建的而有所不同。

在以下情况下,将触发指标创建的脚本警报

  • 该指标包含 alert() 调用。
  • 代码的逻辑允许执行特定的 alert() 调用。
  • alert()调用中指定的频率 允许触发警报。

根据策略创建的脚本警报可在alert() 函数调用订单执行事件或两者上触发。创建策略警报的脚本用户决定他希望在脚本警报中包含哪种类型的事件。虽然用户可以订单执行事件上创建脚本警报而无需策略包含特殊代码,但它必须包含 alert()调用,以便用户在其脚本警报中 包含alert() 函数调用

`alert()` 函数事件

alert () 函数具有以下签名:

alert(message, freq)

message

表示触发警报时发送的消息文本的“系列字符串”。由于此参数允许“系列”值,因此可以在运行时生成,并且每个条形图都不同,从而使其动态化。

freq

指定警报触发频率的“输入字符串”。有效参数包括:

  • alert.freq_once_per_bar:每个实时条仅第一个调用会触发警报(默认值)。
  • alert.freq_once_per_bar_close :仅当实时栏关闭并且在脚本迭代期间执行alert()调用时才会触发警报 。
  • alert.freq_all:实时栏内的所有呼叫都会触发警报。

alert()函数 可用于指标和策略。要使 alert() 调用触发在alert() 函数调用上配置的脚本警报,脚本的逻辑必须允许 alert() 调用执行,并且参数确定的频率 必须允许警报触发。freq

请注意,默认情况下,策略会在柱线收盘时重新计算,因此如果 在策略中使用 频率为或的 alert()函数,则在柱线收盘时调用该函数的次数不会超过一次。为了能够 在柱线构建过程中调用alert() 函数,您需要启用该选项。alert.freq_allalert.freq_once_per_barcalc_on_every_tick

使用所有 `alert()`调用

让我们看一个检测 RSI 中心线交叉的例子:

//@version=5
indicator("All `alert()` calls")
r = ta.rsi(close, 20)

// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Trigger an alert on crosses.
if xUp
    alert("Go long (RSI is " + str.tostring(r, "#.00)"))
else if xDn
    alert("Go short (RSI is " + str.tostring(r, "#.00)"))

plotchar(xUp, "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
plotchar(xDn, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
hline(50)
plot(r)

如果从该脚本创建了脚本警报:

  • 当 RSI 向上穿越中心线时,脚本警报将触发,并显示“做多…”消息。当 RSI 向下穿越中心线时,脚本警报将触发,并显示“做空…”消息。
  • 因为没有为alert()freq调用中的参数 指定任何参数 ,所以将使用默认值,因此警报只会在实时栏期间第一次执行每个 alert() 调用时触发。alert.freq_once_per_bar
  • 随警报发送的消息由两部分组成:一个常量字符串,然后是 str.tostring()调用的结果,该结果将包括脚本执行alert()调用 时的 RSI 值 。交叉向上的警报消息将如下所示:“做多(RSI 为 53.41)”。
  • 因为脚本警报总是在每次调用 alert()时触发,只要调用中使用的频率允许,所以这个特定的脚本不允许脚本用户将其 脚本警报限制为仅限多头。

注意:

  • 与始终位于第 0 列(在脚本的全局范围内)的 alertcondition()调用相反 , alert() 调用位于 if 分支的本地范围内,因此只有在满足触发条件时才会执行。如果将 alert() 调用放置在脚本的全局范围内的第 0 列,它将在所有条形上执行,这可能不是所需的行为。
  • 由于使用了str.tostring() 调用,alertcondition() 无法接受我们用于警报消息的相同字符串。alertcondition ( ) 消息 必须 是常量字符串。

最后,因为 alert() 消息可以在运行时动态构建,我们可以使用以下代码来生成警报事件:

// Trigger an alert on crosses.
if xUp or xDn
    firstPart = (xUp ? "Go long" : "Go short") + " (RSI is "
    alert(firstPart + str.tostring(r, "#.00)"))

使用选择性的 `alert()`调用

当用户alert() 函数调用上创建脚本警报时, 只要满足其频率限制, 脚本对 alert()函数的任何调用都会触发警报。如果您想让脚本用户选择 脚本中的哪个alert()函数调用将触发脚本警报,您需要为他们提供在脚本输入中指示其偏好的方法,并在脚本中编写适当的逻辑。这样,脚本用户将能够从单个脚本创建多个脚本警报,每个警报的行为都根据在图表 UI 中创建警报之前在脚本输入中所做的选择而有所不同。

假设,对于我们的下一个示例,我们想提供仅对多头、仅对空头或两者触发警报的选项。您可以像这样编写脚本:

//@version=5
indicator("Selective `alert()` calls")
detectLongsInput  = input.bool(true,  "Detect Longs")
detectShortsInput = input.bool(true,  "Detect Shorts")
repaintInput      = input.bool(false, "Allow Repainting")

r = ta.rsi(close, 20)
// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Only generate entries when the trade's direction is allowed in inputs.
enterLong  = detectLongsInput  and xUp and (repaintInput or barstate.isconfirmed)
enterShort = detectShortsInput and xDn and (repaintInput or barstate.isconfirmed)
// Trigger the alerts only when the compound condition is met.
if enterLong
    alert("Go long (RSI is " + str.tostring(r, "#.00)"))
else if enterShort
    alert("Go short (RSI is " + str.tostring(r, "#.00)"))

plotchar(enterLong,  "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
plotchar(enterShort, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
hline(50)
plot(r)

注意:

  • 我们创建了一个复合条件,只有当用户的选择允许在该方向入场时,该条件才会满足。只有当脚本的输入中启用了多头入场时,在中心线交叉点上的多头入场才会触发警报。
  • 我们让用户表明其重绘偏好。当他不允许计算重绘时,我们会等到柱状图确认后触发复合条件。这样,警报和标记只会出现在实时柱状图的末尾。
  • 如果此脚本的用户想要从该脚本创建两个不同的脚本警报,即一个仅在多头上触发,一个仅在空头上触发,则他需要:
    • 在输入中仅选择“检测多头”并 在脚本上创建第一个脚本警报。
    • 在输入中仅选择“检测短路”,并 在脚本上创建另一个脚本警报。

策略方面

alert() 函数调用也可用于策略,但前提是策略默认仅在 实时柱线收盘时执行。除非在strategy() 声明语句 calc_on_every_tick = true中使用 ,否则所有alert() 调用都将使用频率,而不管使用的参数是什么alert.freq_once_per_bar_closefreq

虽然策略上的脚本警报将使用订单填写事件在经纪人模拟器填写订单时触发警报,但 alert() 可有利地用于生成策略中的其他警报事件。

当 RSI 连续三个条形图与交易相反时,此策略会创建alert() 函数调用:

//@version=5
strategy("Strategy with selective `alert()` calls")
r = ta.rsi(close, 20)

// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Place orders on crosses.
if xUp
    strategy.entry("Long", strategy.long)
else if xDn
    strategy.entry("Short", strategy.short)

// Trigger an alert when RSI diverges from our trade's direction.
divInLongTrade  = strategy.position_size > 0 and ta.falling(r, 3)
divInShortTrade = strategy.position_size < 0 and ta.rising( r, 3)
if divInLongTrade 
    alert("WARNING: Falling RSI", alert.freq_once_per_bar_close)
if divInShortTrade
    alert("WARNING: Rising RSI", alert.freq_once_per_bar_close)

plotchar(xUp, "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
plotchar(xDn, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
plotchar(divInLongTrade,  "WARNING: Falling RSI", "•", location.top,    color.red,  size = size.tiny)
plotchar(divInShortTrade, "WARNING: Rising RSI",  "•", location.bottom, color.lime, size = size.tiny)
hline(50)
plot(r)

如果用户根据此策略 创建了脚本警报,并在警报中 包含订单执行事件alert() 函数调用,则每当执行订单时,或者 脚本在实时条形图的收盘迭代中执行 其中一个alert()调用时(即barstate.isrealtimebarstate.isconfirmed 均为真时),警报就会触发。脚本中的alert() 函数事件只会在实时条形图收盘时触发警报,因为 是alert()调用 中 alert.freq_once_per_bar_close用于参数的参数freq

订单执行事件

当从指标创建脚本警报时,它只能在alert() 函数调用时触发。但是,当从策略创建脚本警报时,用户可以指定订单填写事件也触发脚本警报订单填写事件是由经​​纪商模拟器生成的任何事件,会导致模拟订单被执行。它相当于经纪商/交易所填写的交易订单。订单不一定在下达时执行。在策略中,只能通过分析内置变量(如 strategies.opentradesstrategies.position_size )的变化来间接地、事后检测到订单的执行。 因此,在订单填写事件上配置的脚本警报很有用,因为它们允许在订单执行的精确时刻触发警报,在脚本的逻辑检测到它之前。

Pine Script™ 程序员可以自定义执行特定订单时发送的警报消息。虽然这不是触发 订单执行事件的先决条件,但自定义警报消息很有用,因为它们允许在警报中包含自定义语法,以便将实际订单路由到第三方执行引擎。通过可以生成订单的函数中的参数指定特定订单执行事件alert_message的自定义警报消息: strategy.close()strategy.entry()strategy.exit()strategy.order()

alert_message参数使用的参数是“系列字符串”,因此可以使用脚本可用的任何变量动态构造它,只要将其转换为字符串格式即可。

让我们看一下在strategy.entry()调用中都使用该alert_message参数 的策略

//@version=5
strategy("Strategy using `alert_message`")
r = ta.rsi(close, 20)

// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Place order on crosses using a custom alert message for each.
if xUp
    strategy.entry("Long", strategy.long, stop = high, alert_message = "Stop-buy executed (stop was " + str.tostring(high) + ")")
else if xDn
    strategy.entry("Short", strategy.short, stop = low, alert_message = "Stop-sell executed (stop was " + str.tostring(low) + ")")

plotchar(xUp, "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
plotchar(xDn, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
hline(50)
plot(r)

注意:

  • 我们stopstrategy.entry()调用中使用 参数,创建止损买入和止损卖出订单。这意味着买入订单仅在价格高于 high订单所在柱线的[低点]时执行,而卖出订单仅在价格低于订单所在柱线的[低点]时执行。
  • 我们用plotchar()绘制的向上/向下箭头 是在下 订单时绘制的。在订单实际执行之前可能会经过任意数量的条形图,在某些情况下,由于价格不满足所需条件,订单永远不会执行。
  • 因为我们id对所有买单使用相同的参数,所以在满足前一个订单条件之前下达的任何新买单都将取代该订单。卖单也是如此。
  • alert_message当订单执行时,即当警报触发时,将评估参数中包含的变量。

alert_message参数用于策略的订单生成strategy.*()函数调用时,脚本用户在创建订单执行事件脚本警报{{strategy.order.alert_message}}时,必须在“创建警报”对话框的“消息”字段中包含占位符。这是必需的,因此 订单生成函数调用中使用的参数将用于每个订单执行事件触发的警报消息中。当仅在“消息”字段中使用占位符并且参数仅出现在策略中的某些订单生成函数调用中时,空字符串将替换由任何未使用该参数的订单生成函数调用触发的警报消息中的占位符alert_messagestrategy.*(){{strategy.order.alert_message}}alert_messagestrategy.*()strategy.*()alert_message

虽然用户可以在“创建警报”对话框的“消息”字段中使用其他占位符来创建订单填写事件的警报,但它们不能在的参数中使用alert_message

`alertcondition()`事件

alertcondition()函数 允许程序员在其指标中创建单独的alertcondition 事件 。一个指标可能包含多个 alertcondition() 调用。脚本中对 alertcondition()的每次调用 都将创建一个相应的警报,可在“创建警报”对话框的“条件”下拉菜单中选择。

虽然策略脚本 中存在 alertcondition()调用不会导致编译错误,但无法从中创建警报。

alertcondition () 函数具有以下签名:

alertcondition(condition, title, message)

condition

一个“系列布尔”值(truefalse),用于确定何时触发警报。它是必需参数。当值为时, true将触发警报。当值为时,false不会触发警报。与 alert() 函数调用相反, alertcondition() 调用必须从行的零列开始,因此不能放在条件块中。

title

“const string” 可选参数,用于设置警报条件的名称,该名称将显示在图表 UI 中“创建警报”对话框的“条件”字段中。如果没有提供参数,则将使用“警报”。

message

“常量字符串”可选参数,用于指定触发警报时显示的文本消息。文本将显示在“创建警报”对话框的“消息”字段中,脚本用户可以在创建警报时从中修改它。由于此参数必须是“常量字符串”,因此必须在编译时知道它,因此不能因条而异。但是,它可以包含占位符,这些占位符将在运行时被动态值替换,这些动态值可能会因条而异。请参阅本页的 占位符部分以获取列表。

alertcondition () 函数不包含参数。alertcondition () 警报freq的频率 由用户在“创建警报”对话框中确定。

使用一个条件

以下是创建alertcondition() 事件的代码示例

//@version=5
indicator("`alertcondition()` on single condition")
r = ta.rsi(close, 20)

xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)

plot(r, "RSI")
hline(50)
plotchar(xUp, "Long",  "▲", location.bottom, color.lime, size = size.tiny)
plotchar(xDn, "Short", "▼", location.top,    color.red,  size = size.tiny)

alertcondition(xUp, "Long Alert",  "Go long")
alertcondition(xDn, "Short Alert", "Go short ")

因为我们的脚本中有两个 alertcondition() 调用,所以“创建警报”对话框的“条件”字段中将有两个不同的警报:“长警报”和“短警报”。

如果我们想在交叉发生时包含 RSI 的值,我们不能简单地message使用 将其值添加到字符串 中,就像在alert() 调用中或在策略中的参数中str.tostring(r)一样 。但是,我们可以使用占位符将其包含在内。这显示了两种替代方案:alert_message

alertcondition(xUp, "Long Alert",  "Go long. RSI is {{plot_0}}")
alertcondition(xDn, "Short Alert", 'Go short. RSI is {{plot("RSI")}}')

注意:

  • 第一行使用{{plot_0}}占位符,其中情节编号与脚本中情节的顺序相对应。
  • 第二行使用{{plot("[plot_title]")}}占位符的类型,它必须包含脚本中用于绘制 RSItitleplot() 调用。双引号用于将绘图的标题括在{{plot("RSI")}}占位符内。这要求我们使用单引号来括住message字符串。
  • 使用其中一种方法,我们可以包含指标绘制的任何数值,但由于无法绘制字符串,因此不能使用字符串变量。

使用复合条件

如果我们想让脚本用户能够使用多个 alertcondition() 调用从指标创建单个警报,我们将需要在脚本的输入中提供选项,用户可以通过这些选项在创建警报之前指示他们想要触发警报的条件。

此脚本演示了执行此操作的一种方法:

//@version=5
indicator("`alertcondition()` on multiple conditions")
detectLongsInput  = input.bool(true, "Detect Longs")
detectShortsInput = input.bool(true, "Detect Shorts")

r = ta.rsi(close, 20)
// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Only generate entries when the trade's direction is allowed in inputs.
enterLong  = detectLongsInput  and xUp
enterShort = detectShortsInput and xDn

plot(r)
plotchar(enterLong,  "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
plotchar(enterShort, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
hline(50)
// Trigger the alert when one of the conditions is met.
alertcondition(enterLong or enterShort, "Compound alert", "Entry")

请注意, alertcondition()调用是如何 在两个条件之一下触发的。每个条件只有在用户在创建警报之前在脚本的输入中启用它时才能触发警报。

占位符

这些占位符可用于alertcondition()message调用的参数 中 。当警报触发时,它们将被动态值替换。它们是在 alertcondition() 消息中包含动态值(可随条变化的值)的唯一方法。

请注意,从图表 UI 中的“创建警报”对话框创建alertcondition() 警报的用户也可以在对话框的“消息”字段中使用这些占位符。

{{exchange}}

警报中使用的代码的交易所(NASDAQ、NYSE、MOEX 等)。请注意,对于延迟代码,交易所将以“_DL”或“_DLY”结尾。例如,“NYMEX_DL”。

{{interval}}

返回创建警报的图表的时间范围。请注意,范围图是根据 1 分钟数据计算的,因此在范围图上创建的任何警报上,占位符将始终返回“1”。

{{open}},,,,,{{high}}{{low}}{{close}}{{volume}}

触发警报的条的对应值。

{{plot_0}},,{{plot_1}}[…],{{plot_19}}

相应绘图编号的值。绘图按脚本中出现的顺序从 0 到 19 编号,因此只能使用前 20 个绘图中的一个。例如,内置的“成交量”指标有两个输出系列:成交量和成交量 MA,因此您可以使用以下内容:

alertcondition(volume > ta.sma(volume,20), "Volume alert", "Volume ({{plot_0}}) > average ({{plot_1}})")

{{plot("[plot_title]")}}

当需要使用plot()title调用中使用的参数 引用绘图时,可以使用此占位符。请注意,占位符内必须使用 双引号 ( )来包裹参数。这要求使用单引号 ( ) 来包裹字符串:"title'message

//@version=5
indicator("")
r = ta.rsi(close, 14)
xUp = ta.crossover(r, 50)
plot(r, "RSI", display = display.none)
alertcondition(xUp, "xUp alert", message = 'RSI is bullish at: {{plot("RSI")}}')

{{ticker}}

警报中使用的符号的代码(AAPL、BTCUSD 等)。

{{time}}

返回条形图开始的时间。时间为 UTC,格式为yyyy-MM-ddTHH:mm:ssZ,例如:2019-08-27T09:56:00Z

{{timenow}}

警报触发的当前时间,格式与 相同 {{time}}。精度为最接近的秒,与图表的时间范围无关。

使用警报避免重绘

交易者希望通过警报避免的最常见重绘情况是,他们必须防止警报在实时柱状图的某个时间点触发,而该警报在收盘时不会触发。当满足以下条件时,可能会发生这种情况

  • 触发警报条件中使用的计算在实时柱期间可能会有所不同。例如,使用或 的任何计算都是这种情况high,其中包括几乎所有内置指标。 当较高时间范围的当前柱尚未关闭时,使用高于图表时间范围的任何request.security()调用的结果也是如此 。lowclose
  • 警报可以在实时条形图关闭之前触发,因此可以采用除“每条条形图关闭一次”之外的任何频率。

避免这种重绘的最简单方法是配置警报的触发频率,使其仅在实时条形图收盘时触发。没有万能药;避免这种重绘 总是需要等待确认的信息,这意味着交易者必须牺牲即时性来实现可靠性。

请注意,其他类型的重绘(比如我们在 重绘部分记录的重绘)可能无法通过在实时条形图关闭时触发警报来防止。

Original text
Rate this translation
Your feedback will be used to help improve Google Translate