外观
警报
约 6448 字大约 21 分钟
简介
TradingVue警报在我们的服务器上24小时全天候运行,用户无需登录即可执行。警报可通过图表用户界面(UI)创建。
TradingVue上的部分警报类型(如通用警报、绘图警报以及订单成交事件触发的脚本警报)可通过图表上加载的品种或脚本创建,无需特定编程。任何用户均可通过图表UI创建这些类型的警报。
其他警报类型(通过alert()函数调用触发的脚本警报,以及alertcondition()警报)需要在脚本中包含特定的Mine Script®代码以生成警报事件,此后脚本用户才能通过图表UI基于这些事件创建警报。此外,虽然脚本用户可通过图表UI针对图表上加载的任何策略创建订单成交事件触发的脚本警报,但程序员可以在脚本中为经纪商模拟器成交的每类订单指定明确的订单成交警报消息。
本文介绍Mine Script程序员可通过哪些方式编写代码以生成警报事件,进而使脚本用户能够通过图表UI基于这些事件创建警报。我们将涵盖以下内容:
- 如何在指标或策略中使用alert()函数进行函数调用,以便通过图表UI创建的脚本警报包含这些调用。
- 如何为策略的订单成交事件触发的脚本警报添加自定义警报消息。
- 如何在指标中(仅限指标)使用alertcondition()函数生成alertcondition()事件,以便通过图表UI创建alertcondition()警报。
请注意以下要点:
- 任何与警报相关的Mine Script代码均无法在图表UI中直接创建运行中的警报;它仅生成警报事件,脚本用户可通过图表UI基于这些事件创建运行中的警报。
- 警报仅在实际时间柱上触发。因此,处理任何类型警报的Mine Script代码的操作范围仅限于实际时间柱。
- 当通过图表UI创建警报时,TradingVue会保存脚本及其输入参数的镜像副本,以及图表的主品种和时间周期,以便在其服务器上运行警报。此后对脚本输入参数或图表的更改不会影响已创建的运行中警报。若希望运行中的警报反映上下文变更,您需要删除原有警报并在新上下文中重新创建。
背景
Mine程序员目前可在脚本中用于创建警报事件的不同方法,是Mine Script发展过程中逐步增强功能的结果。仅适用于指标的alertcondition()函数是首个允许Mine Script程序员创建警报事件的功能。随后推出了策略的订单成交警报,该类警报在经纪商模拟器生成订单成交事件时触发。订单成交事件无需特殊代码即可供脚本用户创建警报,但通过订单生成类策略函数strategy.*()中的alert_message参数,程序员可为任意数量的订单成交事件定义独立的警报消息,从而自定义订单成交事件所触发警报的消息内容。
alert()函数是Mine Script最新的新增功能。它基本取代了alertcondition()函数,当在策略中使用时,可为订单成交事件警报提供有效的功能补充。
哪种警报类型最合适?
对Mine Script程序员而言,alert()函数通常更易用且更灵活。与alertcondition()不同,它支持动态警报消息,可在指标和策略中使用,并由程序员决定alert()事件的触发频率。
虽然alert()调用可通过Mine可编程的任何逻辑生成(包括策略中向经纪商模拟器发送订单时),但无法在订单执行(或成交)时触发,因为订单发送至经纪商模拟器后,模拟器将控制其执行过程且不会直接向脚本反馈成交事件。
当脚本用户需要针对策略的订单成交事件生成警报时,必须在“创建警报”对话框中对策略创建脚本警报时包含这些事件。脚本中无需特殊代码即可实现此功能。但程序员可通过订单生成类strategy.*()函数调用中的alert_message参数来自定义订单成交事件发送的消息。结合使用alert()调用与订单生成类strategy.*()调用中的自定义alert_message参数,程序员可针对脚本执行过程中大多数条件生成警报事件。
alertcondition()函数仍保留在Mine Script中以保持向后兼容性,但它也可用于生成独立警报,这些警报可作为单独选项出现在“创建警报”对话框的“条件”字段中供用户选择。
脚本警报
当脚本用户通过“创建警报”对话框创建脚本警报时,能够触发警报的事件将取决于该警报是基于指标还是策略创建。
基于指标创建的脚本警报将在以下情况下触发:
基于策略创建的脚本警报可因以下事件触发:
- alert()函数调用
- 订单成交事件
- 或同时包含两者
创建策略警报的脚本用户可自行选择希望包含在脚本警报中的事件类型。虽然用户无需策略包含特殊代码即可创建基于订单成交事件的脚本警报,但若希望将alert()函数调用包含在其脚本警报中,则策略必须包含alert()调用。
alert()函数事件
alert()函数具有以下签名:
alert(message, freq)message
“系列字符串”类型参数,表示警报触发时发送的消息文本。由于此参数允许“系列”值,可在运行时动态生成并实现每根K线不同消息。
freq
“输入字符串”类型参数,用于指定警报的触发频率。有效参数为:
alert.freq_once_per_bar:每根实时价格柱仅首次调用触发警报(默认值)alert.freq_once_per_bar_close:仅当实时价格柱收盘且在该次脚本迭代期间执行alert()调用时触发警报alert.freq_all:实时价格柱期间的所有调用均触发警报
alert()函数可在指标和策略中使用。若要使alert()调用触发基于alert()函数调用配置的脚本警报,脚本逻辑必须允许执行该alert()调用,且由freq参数确定的频率必须允许警报触发。
请注意:默认情况下策略在K线收盘时重新计算,因此若在策略中使用频率为alert.freq_all或alert.freq_once_per_bar的alert()函数,则其调用频率不会超过每根K线收盘时一次。若需要在K线构建过程中调用alert()函数,需启用calc_on_every_tick选项。
使用所有alert()调用
以下示例展示如何检测RSI中轴线的交叉:
Mine Script®
已复制
若基于此脚本创建脚本警报:
- 当RSI向上穿越中轴线时,脚本警报将触发并发送"做多…"消息
- 当RSI向下穿越中轴线时,脚本警报将触发并发送"做空…"消息
- 由于alert()调用中未为
freq参数指定值,将使用默认值alert.freq_once_per_bar,因此警报仅在实时价格柱期间首次执行每个alert()调用时触发。 - 警报发送的消息由两部分组成:固定字符串加上str.tostring()调用结果(该结果包含脚本执行alert()调用时RSI的实时值)。向上穿越的警报消息示例:"做多(RSI值为53.41)"。
- 由于脚本警报始终会在发生任何alert()调用时触发(只要调用中使用的频率允许),此特定脚本不允许脚本用户将警报限制为仅做多信号等情况。
请注意:
- 与始终位于零列(脚本全局作用域)的alertcondition()调用不同,alert()调用位于if分支的局部作用域中,因此仅在满足触发条件时执行。若将alert()调用置于脚本全局作用域的零列,它会在所有柱上执行,这通常不符合预期行为。
- alertcondition()无法接受我们用于警报消息的相同字符串(因为使用了str.tostring()调用)。alertcondition()消息必须是常量字符串。
最后,由于alert()消息可在运行时动态构建,我们本可以使用以下代码生成警报事件:
Mine Script®
已复制
使用选择性alert()调用
当用户基于alert()函数调用创建脚本警报时,只要满足频率约束条件,该警报将在脚本执行任何alert()调用时触发。若希望脚本用户能够选择脚本中的特定alert()函数调用来触发脚本警报,您需要在脚本输入中提供偏好设置选项,并在脚本中编写相应逻辑。通过这种方式,脚本用户可从单个脚本创建多个脚本警报,每个警报根据在图表UI创建警报前对脚本输入参数的选择而具有不同行为。
假设在接下来的示例中,我们希望提供仅做多信号触发、仅做空信号触发或两者皆可触发的选项。您可以按如下方式编写脚本:
Mine Script®
已复制
请注意以下要点:
- 我们创建了一个复合条件,仅当用户在脚本输入中允许该方向交易时才会满足。例如,仅当在脚本输入中启用"做多检测"时,中轴线金叉产生的做多信号才会触发警报。
- 我们为用户提供了重绘偏好选项。当用户不允许计算重绘时,程序将等待当前K线确认后再触发复合条件。这样,警报和标记仅会在实时K线结束时出现。
若脚本用户希望基于此脚本创建两个独立的脚本警报(一个仅触发做多信号,另一个仅触发做空信号),则需要:
- 在输入参数中仅选择"做多检测",并基于该配置创建第一个脚本警报
- 在输入参数中仅选择"做空检测",并基于该配置创建另一个脚本警报
在策略中
alert()函数调用同样可在策略中使用,但需注意:策略默认仅在实时价格柱收盘时执行。除非在strategy()声明语句中使用calc_on_every_tick = true,否则所有alert()调用将自动采用alert.freq_once_per_bar_close频率(无论为freq参数指定何种值)。
虽然策略的脚本警报会使用订单成交事件在经纪商模拟器执行订单时触发警报,但alert()可有效用于在策略中生成其他警报事件。
该策略在RSI连续三根价格柱与持仓方向相反时创建alert()函数调用:
Mine Script®
已复制
若用户基于此策略创建脚本警报,并在警报中同时包含订单成交事件与alert()函数调用,则警报将在以下情况触发:
- 订单执行时
- 或脚本在实时价格柱的收盘迭代阶段(即当barstate.isrealtime与barstate.isconfirmed同时为真时)执行任一alert()调用
脚本中的alert()函数事件仅会在实时价格柱收盘时触发警报,因为alert()调用中为freq参数使用的值是alert.freq_once_per_bar_close。
订单成交事件
当基于指标创建脚本警报时,其仅能通过alert()函数调用触发。但基于策略创建脚本警报时,用户可指定同时通过订单成交事件触发脚本警报。订单成交事件指经纪商模拟器执行模拟订单时生成的任何事件,相当于经纪商/交易所执行的交易订单成交。订单提交后未必立即执行。在策略中,订单执行只能通过分析内置变量(如strategy.opentrades或strategy.position_size)的变化间接检测。因此,基于订单成交事件配置的脚本警报可在订单执行的精确时刻触发警报(早于脚本逻辑检测到该事件),具有重要价值。
Mine Script程序员可自定义特定订单执行时发送的警报消息。虽然这不是订单成交事件触发的必要条件,但自定义警报消息非常实用:例如允许在警报中包含特定语法以将实际订单路由至第三方执行引擎。通过订单生成函数(strategy.close()、strategy.entry()、strategy.exit()和strategy.order())中的alert_message参数,可为特定订单成交事件指定自定义警报消息。
alert_message参数使用“series string”类型参数,因此可通过脚本中任何可用变量动态构建(只需转换为字符串格式)。
以下策略示例在strategy.entry()调用中使用alert_message参数:
Mine Script®
已复制
请注意以下要点:
- 我们在strategy.entry()调用中使用
stop参数,该参数会创建止损买入和止损卖出订单。这意味着买入订单仅在价格高于下单时K线最高价时执行,卖出订单仅在价格低于下单时K线最低价时执行。 - 通过plotchar()绘制的上下箭头在订单提交时即显示。订单实际执行可能间隔任意数量的K线,且在某些情况下订单可能因价格未满足条件而永不执行。
- 由于所有买入订单使用相同的
id参数,在前一订单条件未满足时提交的新买入订单将替换原有订单。卖出订单同理。 alert_message参数中包含的变量在订单执行时(即警报触发时)进行估值。
当策略的订单生成类strategy.*()函数调用中使用alert_message参数时,脚本用户必须在“创建警报”对话框的“消息”字段中包含{{strategy.order.alert_message}}占位符(用于创建基于订单成交事件的脚本警报)。此举可确保订单生成类strategy.*()函数调用中使用的alert_message参数值被包含在每个订单成交事件触发的警报消息中。若仅使用{{strategy.order.alert_message}}占位符,但策略中仅部分订单生成类strategy.*()函数调用包含alert_message参数,则未使用该参数的函数调用所触发警报的消息中将用空字符串替换该占位符。
虽然用户创建订单成交事件警报时可在“创建警报”对话框的“消息”字段中使用其他占位符,但这些占位符不能用于alert_message参数的参数值中。
alertcondition()事件
alertcondition()函数允许程序员在指标中创建独立的alertcondition事件。一个指标可包含多个alertcondition()调用。脚本中的每个alertcondition()调用将在“创建警报”对话框的“条件”下拉菜单中生成一个对应的可选警报项。
虽然策略脚本中包含alertcondition()调用不会引发编译错误,但无法基于这些调用创建警报。
alertcondition()函数具有以下签名:
alertcondition(condition, title, message)condition “系列布尔”类型值(真或假),用于确定警报触发时机。此为必需参数。当值为真时警报触发,值为假时不触发。与alert()函数调用不同,alertcondition()调用必须始于行的零列,因此不能置于条件块中。
title “常量字符串”类型可选参数,用于设置警报条件的名称(该名称将显示在图表UI“创建警报”对话框的“条件”字段中)。若未提供参数,则默认使用“Alert”。
message “常量字符串”类型可选参数,用于指定警报触发时显示的文本消息。该文本将出现在“创建警报”对话框的“消息”字段中,脚本用户可在创建警报时修改此内容。由于此参数必须是“常量字符串”,必须在编译时确定且不能逐根K线变化。 但可包含占位符,这些占位符将在运行时被可能逐根K线变化的动态值替换。占位符列表请参阅本页占位符章节。
alertcondition()函数不包含freq参数。alertcondition()警报的频率由用户在“创建警报”对话框中确定。
使用单一条件
以下为创建alertcondition()事件的代码示例:
Mine Script®
已复制
由于脚本中包含两个alertcondition()调用,“创建警报”对话框的“条件”字段中将提供两个不同的警报选项:“多头警报”与“空头警报”。
若希望在交叉发生时包含RSI数值,无法像在alert()调用或策略的alert_message参数中那样直接使用str.tostring(r)将其添加到消息字符串。但可通过占位符实现。以下展示两种替代方案:
Mine Script®
已复制
请注意:
- 第一行使用
{{plot_0}}占位符,其中绘图编号对应脚本中绘图函数的顺序。 - 第二行使用
{{plot("[绘图标题]")}}类型的占位符,必须包含脚本中用于绘制RSI的plot()调用所指定的标题。在{{plot("RSI")}}占位符内部使用双引号包裹绘图标题,这要求我们使用单引号来包裹整个消息字符串。 - 通过其中一种方法,我们可以包含指标绘制的任何数值,但由于无法绘制字符串,因此不能使用字符串变量。
使用复合条件
若希望为脚本用户提供通过多个alertcondition()调用从单个指标创建统一警报的功能,需要在脚本输入参数中提供选项,使用户在创建警报前可指定期望触发警报的条件。
以下脚本演示一种实现方式:
Mine Script®
已复制
请注意alertcondition()调用如何在两个条件中的任一条件满足时触发警报。每个条件仅当用户在创建警报前通过脚本输入参数启用时,才具备触发警报的能力。
占位符
以下占位符可用于alertcondition()调用的message参数中。警报触发时这些占位符将被动态值替换。这是alertcondition()消息中包含动态值(可逐根K线变化的值)的唯一方式。
请注意:通过图表UI中“创建警报”对话框创建alertcondition()警报的用户也可在对话框的“消息”字段中使用这些占位符。
{{exchange}} 警报所用品种的交易所名称(NASDAQ、NYSE、MOEX等)。注意:对于延迟行情品种,交易所名称将以“_DL”或“_DLY”结尾,例如“NYMEX_DL”。
{{interval}} 返回创建警报的图表时间周期。注意:范围图表基于1分钟数据计算,因此在该类图表上创建的任何警报此占位符始终返回“1”。
{{open}}、{{high}}、{{low}}、{{close}}、{{volume}} 触发警报时对应K线的开盘价、最高价、最低价、收盘价、成交量。
{{plot_0}}、{{plot_1}}、[…]、{{plot_19}} 对应绘图编号的数值。绘图按在脚本中的出现顺序从0到19编号,因此仅前20个绘图可供使用。例如,内置“成交量”指标有两个输出序列:成交量与成交量均线,您可以使用以下占位符:
Mine Script®
已复制
{{plot("[绘图标题]")}} 当需要引用通过plot()调用中title参数定义的绘图时,可使用此占位符。注意:占位符内部必须使用双引号(")包裹标题参数,这要求消息字符串需使用单引号(')包裹:
Mine Script®
已复制
{{ticker}} 警报所用品种的代码(XAUUSD、BTCUSD等)。
{{time}} 返回K线起始时间。时间为UTC格式,格式化为yyyy-MM-ddTHH:mm:ssZ,例如:2019-08-27T09:56:00Z。
{{timenow}} 警报触发时的当前时间,格式与{{time}}相同。时间精度精确到秒,与图表时间周期无关。
避免警报重绘
交易者最希望避免的警报重绘情况是:防止警报在实时价格柱期间某时刻触发(若等到该价格柱收盘时该触发条件将不复存在)。满足以下条件时可能出现此情况:
触发警报的条件所使用的计算在实时价格柱期间可能变化(例如使用最高价、最低价或收盘价的任何计算——这几乎包含所有内置指标)。当使用比图表时间周期更高的时间周期且该更高时间周期的当前价格柱尚未收盘时,任何request.security()调用的结果也会出现此情况。
警报可在实时价格柱收盘前触发(即使用“每次收盘触发”之外的任何频率)。
避免此类重绘的最简单方法是将警报触发频率配置为仅在实际价格柱收盘时触发。不存在万能解决方案;避免此类重绘总是需要等待确认信息,这意味着交易者必须牺牲即时性来换取可靠性。
请注意:其他类型的重绘(如重绘章节中所述的类型)可能无法通过仅在实时价格柱收盘时触发警报来预防。