如何将绘图占位符与TradingView的策略警报一起使用
要让策略警报的消息更具动态性,一个有效的方法是使用绘图占位符。它能把指标的当前绘图值,例如止损位或目标位,直接嵌入到订单成交的警报消息中。下面我们深入了解怎么实现。
在策略警报中使用绘图占位符
绘图占位符是被双大括号{{...}}包裹的特殊文本。当警报触发时,TradingView会自动把该占位符替换为对应绘图的当前实时数值,这是在警报消息中获取动态数字的一种方法。绘图占位符同样也适用于由指标创建的警报条件——如果你之前在指标中用过它们,会发现它们在策略中的工作方式完全相同。
两种引用绘图的方式
要在警报消息中引用一个绘图的值,主要有两种方式:
- 按编号引用(
{{plot_N}}):基于绘图在代码中的出现顺序进行引用,编号从0开始,例如第一个绘图用{{plot_0}}引用。这种方式的缺点是最多只能引用脚本中的前20个绘图(即到{{plot_19}}为止)。 - 按名称引用(
{{plot("name")}}):基于我们在代码中为绘图指定的title(标题)来引用,例如{{plot("EMA")}}。这种方式更方便,可读性更高,并且没有数量限制。
这两种方式都会把绘图的当前值插入到警报消息中。我们来看看在策略中该如何应用。
在策略脚本中,主要有两种方式使用绘图占位符:一是在创建警报窗口中手动输入绘图占位符;二是在代码中使用//@strategy_alert_message注释预设包含占位符的默认消息。我们分别看一下这两种方法的具体操作。
方法一:在创建警报窗口中手动输入
这个方法最为直接,适用于任何会绘制数据的策略,且无需修改代码。假设我们希望策略在成交时,发出像下面这样的警报消息:
新的 {{ticker}} 信号。止损位于 {{plot("SuperTrend")}}。
这个消息需要引用一个名为SuperTrend的绘图的值。如果不清楚策略中有哪些可用的绘图名称,可以打开图表的数据窗口进行查看:

在数据窗口中,找到你的策略名称,其下方列出的就是所有可供引用的绘图及其名称。明确了绘图名称后,打开创建警报窗口,先在条件中选择我们的策略,然后在消息文本框中输入设计好的、包含占位符的文本,最后点击创建即可。

之后,每当策略模拟成交一笔订单,我们收到的警报消息就会是这个样子,其中占位符已被动态替换:

方法二:用//@strategy_alert_message预设默认消息
第二种方法是在代码中通过//@strategy_alert_message这个特殊注释,为整个策略定义一个默认的警报消息。当这个注释中包含了绘图占位符时,就相当于预设了一条包含动态信息的标准警报文本,后续配置警报时更简单快捷,无需每次都手动输入。假设我们希望使用以下警报消息作为默认值:
新的 {{ticker}} 入场信号。最新价格 {{close}}。阶段高点位于 {{plot("Highest High")}},阶段低点位于 {{plot("Lowest Low")}}。
为了实现这一点,只需把下面这行代码添加到策略脚本的任意位置即可(通常放在版本声明之后):
//@version=5
//@strategy_alert_message 新的 {{ticker}} 入场信号。最新价格 {{close}}。阶段高点位于 {{plot("Highest High")}},阶段低点位于 {{plot("Lowest Low")}}。
strategy(title="在策略注释中使用绘图占位符", overlay=true)
// ... 其他策略代码
保存并加载脚本后,再打开创建警报窗口。当我们在条件中选择这个策略时,你会发现消息文本框已经自动填充了我们在代码中预设好的文本,只需直接点击创建即可:

之后,当策略成交订单时,我们收到的警报消息就会是这样,其中所有的占位符都已被替换为动态值:

完整脚本示例
以上示例中使用的完整策略代码如下:
//@version=5
//@strategy_alert_message 新的 {{ticker}} 入场信号。最新价格 {{close}}。阶段高点位于 {{plot("Highest High")}},阶段低点位于 {{plot("Lowest Low")}}。
strategy(title="在策略注释中使用绘图占位符", overlay=true)
// 计算并绘制阶段高低点
highestHigh = ta.highest(high, 20)[1]
lowestLow = ta.lowest(low, 20)[1]
plot(highestHigh, color=color.green, title="Highest High")
plot(lowestLow, color=color.red, title="Lowest Low")
// 生成突破交易订单
if high > highestHigh
strategy.entry("Enter Long", strategy.long)
if low < lowestLow
strategy.entry("Enter Short", strategy.short)
这段代码的逻辑很清晰:先通过//@strategy_alert_message预设了全局警报消息,然后计算并绘制20周期的阶段高低点,最后当价格突破这两个极值时,通过strategy.entry()提交开仓订单。该策略在图表上的效果如下:

绘图占位符的重要局限
绘图占位符有一个非常重要的缺点:它们无法在订单函数(如strategy.entry())的alert_message参数中生效。如果你尝试在那里使用绘图占位符,它只会被当成普通文本显示出来,不会被替换为动态值。这一点很可惜,因为alert_message参数是实现更精细化警报的利器,它能让我们为不同的订单(如开仓、平仓、止盈、止损)设置完全不同的警报消息。好在这个问题有更好的解决方案:alert_message参数本身就可以接受任何通过代码构建的动态字符串,我们可以把任何策略变量(包括那些已绘制的)转换为字符串,再嵌入到消息中。这样就不需要依赖绘图占位符来实现动态消息了。
小结
绘图占位符让我们可以在警报消息中包含绘图的当前值,从而实现动态通知。我们可以按编号(如{{plot_0}})或名称(如{{plot("SMA")}})来引用它们。在策略警报中,主要通过两种方式使用绘图占位符:一是在创建警报窗口中手动输入;二是通过//@strategy_alert_message注释预设默认消息。需要注意的是,绘图占位符只能引用那些被绘制到图表上的值,并且它们在功能更强大的alert_message参数中无效——在那种场景下,直接把变量转换为字符串是更好的选择。
TradingView策略警报中带有占位符的仓位和订单数据
策略警报会在每一次模拟订单成交时生成一条消息。这些消息通常千篇一律,但其实它们也可以包含策略的最新订单详情或实时头寸等动态信息。接下来我们就看看怎么实现。
什么是仓位占位符
仓位占位符(position placeholders)是一类特殊的字符串,当警报触发时,TradingView会自动把它们替换为相应的动态值。这些占位符是被双大括号{{...}}包裹的文本,例如{{strategy.position_size}}和{{strategy.order.price}}。它们被称为仓位占位符,因为专门用来返回与策略的市场头寸和最新执行的订单相关的信息。得益于此,我们的策略警报可以包含当前持仓状况和最近一笔成交订单的详细信息。其工作原理是:在一个模拟订单成交后,策略警报会立即触发,此时TradingView会找到消息中的每一个仓位占位符,并用其当时的最新值进行替换,从而在警报中动态插入订单或头寸的关键信息。
策略专用的仓位占位符
以下是策略警报中所有可用的仓位占位符:
| 占位符 | 返回值说明 |
|---|---|
{{strategy.order.action}} |
最新执行订单的动作:buy(买入)或sell(卖出)。开多仓和平空仓时为buy,开空仓和平多仓时为sell。 |
{{strategy.order.contracts}} |
最新执行订单的合约数(或股数、单位数)。 |
{{strategy.order.price}} |
最新执行订单的成交价格。 |
{{strategy.order.id}} |
最新执行订单的ID。即我们在代码中调用订单函数时设置的字符串ID。 |
{{strategy.order.comment}} |
最新执行订单的注释。即我们在订单函数中为其comment参数设置的值。 |
{{strategy.order.alert_message}} |
最新执行订单的专属警报消息。该消息通过订单函数的alert_message参数设置,仅适用于Pine脚本v4及更高版本。 |
{{strategy.position_size}} |
策略当前持仓规模。正数代表多头仓位,负数代表空头仓位,0代表空仓。其作用与内置变量strategy.position_size相同。 |
{{strategy.market_position}} |
策略当前持仓方向的文本描述:long(多头)、flat(空仓)或short(空头)。 |
{{strategy.prev_market_position}} |
策略在最近一笔订单成交前的持仓方向的文本描述。 |
{{strategy.market_position_size}} |
策略当前持仓规模的绝对值(即不区分多空)。例如,持多仓12手或持空仓12手,均返回12。 |
{{strategy.prev_market_position_size}} |
策略在最近一笔订单成交前的持仓规模的绝对值。 |
我们来看看怎么使用这些仓位占位符。
使用仓位占位符
在策略警报中,我们有三种方式来使用仓位占位符:
- 在创建警报窗口中手动输入。
- 在代码中使用
//@strategy_alert_message特殊注释来预设全局消息。 - 在代码中为具体的订单函数,使用
alert_message参数来设置专属消息。
我们来逐一探索这三种方法。
方法一:在创建警报窗口中手动输入
第一种方法最为直接,它适用于任何策略且无需修改代码。只需把策略加载到图表,然后打开创建警报窗口即可。在该窗口中,先在条件下拉菜单里选择我们的策略名称,然后在消息文本框中,输入设计好的、包含仓位占位符的文本。假设我们希望使用以下模板:
{{strategy.order.action}} {{strategy.order.contracts}}x {{ticker}} @ {{strategy.order.price}}. 当前仓位: {{strategy.market_position}} (上一状态: {{strategy.prev_market_position}}).
我们把这段文本输入到创建警报窗口的消息框中,然后点击创建按钮启用警报:

之后,当策略在实时行情中模拟成交了一笔订单,TradingView就会生成一条警报消息,其中所有的占位符都已被替换为最新的动态数据。例如:

这种方法的缺点是,所有类型的订单(开仓、平仓、反转)都会使用完全相同的消息模板。如果希望为不同订单生成不同的消息,就需要用到alert_message参数了,我们稍后讨论。
方法二:用//@strategy_alert_message预设全局消息
第二种方法是在代码中直接使用//@strategy_alert_message这个特殊注释。它的作用是为整个策略定义一个默认的警报消息:当我们在创建警报窗口中选择该策略时,这个默认消息会自动填充到消息文本框中。假设我们希望每次订单成交时,都能收到基于以下模板的警报消息:
新信号: {{strategy.order.action}} {{ticker}} at {{strategy.order.price}}。当前仓位: {{strategy.market_position}} (上一状态: {{strategy.prev_market_position}})。
要把这段文本设为策略的默认警报消息,只需把//@strategy_alert_message注释以及其后的消息文本,添加到策略代码的任意位置即可(比较好的放置位置是在版本声明和strategy()函数之间)。它在代码中看起来会是这样:
//@version=5
//@strategy_alert_message 新信号: {{strategy.order.action}} {{ticker}} at {{strategy.order.price}}。当前仓位: {{strategy.market_position}} (上一状态: {{strategy.prev_market_position}})。
strategy(title="带警报注释的仓位占位符", overlay=true)
// ... 其他策略代码
(需要注意的是,//@strategy_alert_message注释不支持多行文本,所以消息模板必须写在同一行内。)
完成代码修改并保存后,把策略加载到图表上,然后打开创建警报窗口,在条件下拉菜单中选择我们的策略。你会发现,消息文本框已经自动填充了我们在代码中通过//@strategy_alert_message预设好的文本。现在剩下的工作就只是点击创建按钮来激活警报了。

之后,一旦策略模拟成交了一笔订单,TradingView就会生成一条警报消息,其中所有的仓位占位符都已被替换为最新的动态数据,显示效果如下:

完整的脚本代码
如果你对前一个例子的策略实现细节感兴趣,可以参考下方的完整代码:
//@version=5
//@strategy_alert_message 新信号: {{strategy.order.action}} {{ticker}} at {{strategy.order.price}}。当前仓位: {{strategy.market_position}} (上一状态: {{strategy.prev_market_position}})。
strategy(title="带警报注释的仓位占位符", overlay=true)
// 计算布林带指标值
[middleLine, upperBand, lowerBand] = ta.bb(close, 20, 2.0)
// 绘制布林带
plot(upperBand, color=color.teal, title="上轨")
plot(middleLine, color=color.gray, title="中轨")
plot(lowerBand, color=color.teal, title="下轨")
// 当价格收盘突破上轨时做多
if ta.crossover(close, upperBand)
strategy.entry("Enter Long", strategy.long)
// 当价格收盘跌破下轨时做空
if ta.crossunder(close, lowerBand)
strategy.entry("Enter Short", strategy.short)
// 当价格穿越中轨时平仓
if ta.cross(close, middleLine)
strategy.close_all(comment="Exit Position")
这段代码的逻辑很清晰:先通过//@strategy_alert_message预设了全局警报消息,然后通过strategy()函数配置策略的基本信息。接着,使用ta.bb()函数计算并用plot()绘制出布林带的上、中、下三条轨道。最后,通过三个if语句定义了交易逻辑:价格上穿上轨时做多,跌破下轨时做空,穿越中轨时平掉所有持仓。该策略加载到图表上的效果如下:

关于此代码生成的警报消息,可以参考上一节中的图片。
方法三:为具体订单设置专属的alert_message
当我们需要为不同类型的订单(例如开仓、平仓、止盈、止损)生成完全不同的警报消息时,前两种方法就显得力不从心了。而这正是第三种方法——为订单函数使用alert_message参数——大显身手的地方。alert_message参数可以说是生成策略警报的最灵活、最强大的方式。让我们通过一个例子来看看如何使用它。假设我们想为入场订单和出场订单设置不同的警报消息。首先,可以用一个字符串变量来定义所有入场订单共享的警报文本,方便复用:
// 为所有新开仓的交易指定警报文本
alertEntryText = "{{strategy.order.action}} {{strategy.position_size}} " +
"{{ticker}} at {{strategy.order.price}}."
这个alertEntryText字符串变量包含了多个仓位占位符,用于显示订单动作、当前仓位大小、品种代码和成交价格。接下来,把这个变量应用于所有开仓订单。假设我们使用肯特纳通道(Keltner Channel)作为交易信号:
// 当价格上穿肯特纳通道上轨时做多
if ta.crossover(close, keltUpper)
strategy.entry("Enter Long", strategy.long,
alert_message=alertEntryText)
// 当价格下穿肯特纳通道下轨时做空
if ta.crossunder(close, keltLower)
strategy.entry("Enter Short", strategy.short,
alert_message=alertEntryText)
在上述代码中,无论是做多还是做空的strategy.entry(),我们都把alert_message参数设置为预先定义的alertEntryText变量。我们用同样的方式为出场订单设置专属的警报消息:
// 当价格穿越肯特纳通道中轨时平仓
if ta.cross(close, keltMa)
strategy.close_all(comment="Exit Position", alert_message="平掉 " +
"{{strategy.prev_market_position}} {{ticker}} 仓位,价格 " +
"{{strategy.order.price}}.")
在这个平仓逻辑中,我们直接在strategy.close_all()的alert_message参数里定义了一个新的消息字符串,其中包含了前一持仓方向、品种代码和成交价格等占位符。要让这一切生效,还需要完成最后一个、也是至关重要的一步:把策略加载到图表,打开创建警报窗口,在条件中选择我们的策略,然后在消息文本框中,必须输入{{strategy.order.alert_message}}这个特殊的占位符。它就像一个总开关,告诉TradingView忽略全局消息,去调用并显示由具体订单的alert_message参数所定义的专属消息。完成设置后,点击创建按钮:

之后,当策略模拟成交一笔订单时,我们就会看到根据订单类型而变化的、内容丰富的专属警报消息了:

完整的脚本代码
如果你对前一个例子的策略实现细节感兴趣,可以参考下方的完整代码:
//@version=5
//@strategy_alert_message {{strategy.order.alert_message}}
strategy(title="带订单消息的仓位占位符示例",
overlay=true)
// 计算并绘制肯特纳通道
[keltMa, keltUpper, keltLower] = ta.kc(close, 20, 1.75)
plot(keltUpper, color=color.blue, title="上轨")
plot(keltMa, color=color.orange, title="中轨")
plot(keltLower, color=color.blue, title="下轨")
// 为入场订单定义专属警报消息
alertEntryText = "{{strategy.order.action}} {{strategy.position_size}} " +
"{{ticker}} at {{strategy.order.price}}."
// 当价格上穿肯特纳通道上轨时做多
if ta.crossover(close, keltUpper)
strategy.entry("Enter Long", strategy.long,
alert_message=alertEntryText)
// 当价格下穿肯特纳通道下轨时做空
if ta.crossunder(close, keltLower)
strategy.entry("Enter Short", strategy.short,
alert_message=alertEntryText)
// 当价格穿越肯特纳通道中轨时平仓
if ta.cross(close, keltMa)
strategy.close_all(comment="Exit Position", alert_message="已平掉 " +
"{{strategy.prev_market_position}} {{ticker}} 仓位,价格 " +
"{{strategy.order.price}}.")
这段代码的结构清晰地展示了我们之前讨论的方法。它首先通过//@strategy_alert_message注释,把策略的全局警报消息模板设置为{{strategy.order.alert_message}},使得最终的警报会调用具体订单的专属消息。接着,代码计算并绘制了肯特纳通道的三条轨道线。然后,它定义了两个不同的消息字符串:一个用于开仓的alertEntryText,另一个则直接写在了平仓函数strategy.close_all()的alert_message参数里。最后,通过几个if语句,实现了基于通道突破的开仓和平仓逻辑,并把相应的专属警报消息与订单进行了绑定。该策略加载到图表上的效果如下:

仓位占位符的重要特性
既然已经了解了使用仓位占位符的三种方法,我们来深入探讨一下它的一些重要特性。
适用于所有订单函数。仓位占位符可以与所有用于开仓或平仓的订单函数协同工作,包括:
strategy.entry()strategy.exit()strategy.order()strategy.close()strategy.close_all()
有些占位符的名称以strategy.order开头,可能会让人误以为它们只适用于strategy.order()函数。但事实并非如此,所有仓位占位符都与上述所有订单函数兼容。
返回订单成交瞬间的值。仓位占位符返回的是订单刚刚成交那一刻的实时信息。当一个模拟订单在K线尚未收盘时成交,警报会立即触发,此时消息中的占位符会显示当时K线内部的动态数据。这个特性与策略的回测计算设置无关,它始终能提供最即时的反馈。
返回值可能与内置策略变量不同。这是一个非常关键且容易混淆的概念:仓位占位符返回的值,可能与Pine脚本中同名的内置策略变量(如strategy.position_size)的值不同。这背后的原因是时间差和事件顺序:
- 默认情况下,策略只在K线收盘时计算一次。像
strategy.position_size这样的内置变量,也只在那个时刻更新。 - 然而,订单的成交通常发生在K线内部的某个时刻。当订单成交后,警报立即触发,此时仓位占位符会返回成交那一刻的最新状态(例如成交后的持仓规模)。但此时内置变量
strategy.position_size的值,仍然是上一根K线收盘时的旧值,尚未更新。因此,仓位占位符的值比内置变量的值更新、更及时。
仅适用于策略。顾名思义,仓位占位符是策略的专属功能,不能在指标脚本中使用。不过,策略警报中同样也可以使用标准占位符和绘图占位符。
与alert_message参数完美配合。仓位占位符可以在订单函数的alert_message参数中自由使用,这让我们能构建出信息极其丰富的、针对具体订单的实时警报。如果不在alert_message的文本中使用仓位占位符,警报消息只能反映策略创建订单时的状态,等到订单真正成交时,那些信息可能已经过时了。而通过嵌入仓位占位符,我们可以确保警报消息始终包含最新、最准确的订单和头寸信息。
小结
仓位占位符是被双大括号{{...}}包裹的特殊字符串,当策略警报触发时,TradingView会自动将其替换为相应的动态值。它们专门用于提供策略的市场头寸和最新执行订单的相关信息。这些占位符的关键优势在于,它们总是在订单成交后立即返回其数据,为我们提供最及时、准确的信息。常见的仓位占位符包括{{strategy.order.price}}(成交价格)、{{strategy.position_size}}(当前持仓规模)和{{strategy.order.action}}(最新订单的买卖动作)。


