平均真实波幅指标(ATR)
解读价格波动性,并将这一风险衡量标准融入我们的交易计划,是一项重要的交易技能。衡量价格波动性的方法之一是使用平均真实波幅(Average True Range, ATR)。接下来,让我们看看如何在TradingView Pine中编写这个指标。
使用平均真实波幅(ATR)追踪价格波动
平均真实波幅(ATR)用于追踪市场的波动性。该指标由J.威尔斯·威尔德(J. Welles Wilder)开发,并在其1978年出版的《技术交易系统新概念》一书中分享。尽管这个指标诞生于线上交易普及之前的年代,但时至今日,它依然广受欢迎且非常实用。
威尔德最初是针对商品期货和日线价格设计出ATR的。由于商品市场通常波动剧烈,且可能出现相当大的开盘跳空,一个仅观察K线最高价与最低价之差的波动率公式,并不能恰当地捕捉其真实的价格波动。平均真实波幅通过将价格跳空也纳入考量,从而捕捉到了那部分缺失的波动性,这使其成为一个更真实、更准确的波动率衡量标准。
顾名思义,ATR关注的是平均真实波幅(true range)。所谓真实波幅,是指从以下三项测量中取出的最大值:
- 当前K线的最高价与最低价之间的距离。
- 当前K线的最高价与前一根K线收盘价之间距离的绝对值(用于衡量向上跳空)。
- 当前K线的最低价与前一根K线收盘价之间距离的绝对值(用于衡量向下跳空)。
通过这种方式,真实波幅衡量的始终是两个价格点之间的最大距离,从而全面反映波动性。并且因为我们取的是绝对值,所以真实波幅总是正数。为了平滑单根K线带来的影响,ATR默认会将过去14根K线的真实波幅进行平均。
下面是我们如何获得平均真实波幅的值:
由于ATR的计算依赖于前值,因此它通常从图表的第15根K线才开始有值。在此之后,之前的ATR值虽然仍有微小的影响,但随着指标处理的价格数据增多,这种影响会变得越来越小。
如何使用平均真实波幅进行交易
ATR是一个波动率指标,在从短线日内交易到长线投资的多种场景中都非常有用。其本质上,ATR揭示了我们的交易品种在每根K线内通常会波动多少。在我们的交易中,有多种方式可以利用这一信息。
第一种方法是将ATR的值推断到未来。这能让我们粗略估算在特定时间段内可能的价格波动范围。它也有助于设定合理的预期,这样我们就不会因为不切实际的乐观而恐慌或得意忘形。
假设一个交易品种的日均波幅(Daily ATR)是34个点。当今天的价格已经波动了28个点时,那么当天剩下的交易机会就很少了。除非有重大新闻或基本面变化,今天大概率不会是那种价格远超其平均波动范围的日子。相反,价格的波动很可能会停滞甚至反转。如果你持有一个日内仓位,一个高胜率的决策是在市场波动达到其日均波幅的80%时离场。这样我们就不会为了最后几个点的利润而承担过高风险,并在此过程中蒙受损失。
另一种使用ATR的方法是估算价格在特定时间段内的潜在波幅。这样,我们就能将止盈和止损订单建立在价格波动性的基础上,而不是凭空猜测。例如,如果一支股票在1分钟图上的ATR是$0.05,那么它至少需要5分钟才可能上涨$0.25——如果中间出现一两根回调的K线,则需要更长时间。这种思维方式能让我们对什么可能发生、什么不可能发生形成更合理的预期。
ATR也可以告诉我们趋势的强度。显著的上涨和下跌通常伴随着ATR的上升,尤其是在趋势加速时。而缺乏广泛市场参与的行情通常ATR值很低。因此,一个上升且高企的ATR表明市场处于趋势之中,而一个低迷且下降的ATR则指示市场处于盘整区间。
平均真实波幅还有助于设置止损订单。当我们将止损设置在正常市场波动范围之外时,它们就不太可能因为噪音而被触发。由于ATR衡量的是价格波动性,将止损设为ATR的某个倍数,可以降低因随机价格波动而被平仓的可能性。此外,当止损基于ATR时,它们也会根据当前的价格波动性自动进行调整。
ATR能提供的最后一种帮助是验证突破。通常很难判断什么是有效的突破。但我们可以要求突破的幅度至少达到一个ATR的距离,才将其视为有效突破。这样我们就能减少交易假突破的次数,并且只在价格已经从突破点移动了相当大的距离后才入场买卖。
将平均真实波幅(ATR)指标编写为TradingView脚本
现在我们了解了平均真实波幅如何辅助交易,让我们把注意力转向编写这个指标脚本。以下是我们在本文中将要实现的功能:
- 我们当然会计算ATR并在图表上绘制它。但我们也会引入它的移动平均线,以帮助识别波动性的趋势。我们将通过一个输入选项来选择这条移动平均线应该使用的平滑类型。
- 由于ATR衡量的是绝对的价格变化,我们无法在不同交易品种之间直接比较ATR值。为了解决这个问题,我们的脚本将提供一个选项,让用户可以选择以百分比、跳动点数或货币价值来显示ATR。我们将通过一个下拉菜单输入选项来实现此功能。
- 当平均真实波幅与其移动平均线发生交叉、连续2根K线上升或下降、或达到一个新的20周期高点或低点时,我们将生成TradingView警报。这样,即使我们没有盯着市场,也能收到波动性变化的通知。
既然我们明确了ATR脚本需要具备的功能,就让我们来构思如何实现所需的代码。
用于平均真实波幅(ATR) TradingView指标的模板
现在,我们需要将上述功能转化为TradingView代码。一个有效的方法是使用模板。这能将编写一个完整指标的艰巨任务分解成更小、更易于管理的部分。而且,当我们已经有了一些结构时,它能帮助我们更容易地开始。
这是我们将用于平均真实波幅(ATR)指标的模板:
//@version=5
// 步骤一:脚本设置
// 步骤二:计算指标数值
// 步骤三:确定指标信号
// 步骤四:输出指标数据
// 步骤五:创建指标警报
如果你想跟着本文一起操作,只需在TradingView的Pine编辑器中创建一个新的指标脚本,并粘贴以上模板。
为了让你对我们即将编写的代码有个直观的印象,下图是最终完成的指标在图表上的样子:
现在,就让我们开始动手编写ATR指标吧。
步骤一:定义指标设置和输入选项
我们从指标的属性开始。为此,我们像这样使用 indicator() 函数:
//@version=5
// 步骤一:脚本设置
indicator(title="Average True Range", shorttitle="ATR", overlay=false)
这里我们使用 indicator() 的 title 参数为我们的脚本命名,shorttitle 参数则定义了脚本的缩写名称。通过将 overlay 参数设为 false,我们的脚本将在主图表下方的一个子图中显示。
接着,我们创建几个输入选项,以便能轻松地配置指标的各项设置:
// ATR输入选项
atrType = input.string("Regular", title="ATR Type",
options=["Regular", "Percentage", "Ticks", "Currency"])
atrLen = input.int(14, title="ATR Length")
atrSmooth = input.string("RMA", title="Smoothing Type",
options=["EMA", "RMA", "SMA", "WMA"])
posSize = input.int(1, title="Position Size (For Currency ATR)")
我们在这里使用 input.string() 和 input.int() 函数创建了几个输入项。每次,我们都将函数返回的结果存储在一个变量中。这样,我们后续便可以通过该变量在脚本中使用输入的当前值。
第一个输入选项是一个带有文本值的下拉菜单(input.string()),我们将其命名为“ATR Type”。通过 input.string() 函数的 options 参数,我们定义了该菜单中的所有选项:“Regular”(常规值)、“Percentage”(百分比)、“Ticks”(跳动点数)和“Currency”(货币价值)。该输入的默认值为“Regular”。我们稍后将用它来决定要绘制哪种类型的ATR值。
接下来是一个名为“ATR Length”的数值输入选项(input.int())。这个设置定义了平均真实波幅的计算周期,我们在这里使用默认值14。
然后,input.string() 创建了另一个下拉菜单输入选项,名为“Smoothing Type”,其字符串选项值为“EMA”、“RMA”、“SMA”和“WMA”。我们将使用这个设置来决定如何平滑真实波幅值。
我们创建的最后一个设置名为“Position Size (For Currency ATR)”。当我们的脚本以货币价值计算平均真实波幅时,我们将使用这个整数输入选项来表示头寸规模。这样,我们就可以看到例如交易10手合约存在多大的波动风险,或者10,000单位的欧元/美元有多大的风险。
我们还创建了另外三个输入选项:
// 要禁用ATR的移动平均线,请将其周期设为1
maLength = input.int(21, title="MA Length", minval=1)
colourMA = input.bool(true, title="Colour MA Line?")
highlight = input.bool(false, title="Highlight ATR Signals?")
我们在这里创建的“MA Length”输入项用于设置ATR的移动平均线的周期。我们为这个选项设置了默认值21,最小值为1。在脚本的后续部分,我们将编写代码,当此选项的值为1时自动禁用移动平均线,这使我们的脚本更具灵活性。
接下来,input.bool() 函数创建了一个名为“Colour MA Line?”(为MA线上色?)的布尔型输入选项。我们默认启用此复选框(true)。这个设置用于配置脚本是否为移动平均线上色。
最后一个输入项的标题是“Highlight ATR Signals?”(高亮显示ATR信号?)。稍后在脚本中,我们将通过这个布尔型输入来决定是否在图表上显示平均真实波幅的波动性信号。
步骤二:计算指标数值
在第二步中,我们编写计算平均真实波幅的代码。这一步包含三项任务:首先,我们创建一个函数,它能根据特定的移动平均线平滑类型返回ATR;然后,我们使用该函数来计算由“ATR Type”输入选项所指定类型的ATR值;之后,我们再计算平均真实波幅自身的移动平均线。
所以,首先我们创建一个返回平均真实波幅值的自定义函数:
// 步骤二:计算指标数值
// 根据输入选项设置的平滑类型
// 计算平均真实波幅的自定义函数
AvgTrueRange() =>
if atrSmooth == "EMA"
ta.ema(ta.tr, atrLen)
else if atrSmooth == "RMA"
ta.rma(ta.tr, atrLen)
else if atrSmooth == "SMA"
ta.sma(ta.tr, atrLen)
else
ta.wma(ta.tr, atrLen)
这个函数返回经由四种移动平均线类型之一平滑后的真实波幅。具体使用哪一种,取决于我们之前创建的 atrSmooth 输入变量。
首先,一个if语句会判断该选项是否被设为“EMA”。如果是,我们就对K线的真实波幅(ta.tr)使用 ta.ema() 函数进行计算。均线的周期我们使用 atrLen,即我们之前默认设为14的输入变量。
如果 atrSmooth 的值不是“EMA”,我们会检查它是否等于“RMA”。如果是,我们就用 ta.rma() 函数来计算平均真实波幅。否则,另一个if语句会检查 atrSmooth 是否匹配“SMA”。如果为真,我们就使用 ta.sma() 函数来计算ATR。
如果以上情况都不是,我们默认使用加权移动平均线(WMA)。为此,我们调用TradingView的 ta.wma() 函数,让它在 ta.tr 数据上以 atrLen 为周期进行计算。
现在,要获取平均真实波幅的值,我们只需调用 AvgTrueRange() 函数即可。函数内部的代码会评估“Smoothing Type”输入选项,并以正确的方式计算出平均真实波幅。有了这个函数,我们就不必在后续代码中重复编写平滑移动平均线的逻辑了,正如我们接下来将看到的。
接下来,我们来计算实际的平均真实波幅值本身:
// 根据'ATR Type'输入选项
// 计算平均真实波幅值
atrValue = if atrType == "Regular"
AvgTrueRange()
else if atrType == "Percentage"
(AvgTrueRange() / close) * 100
else if atrType == "Ticks"
AvgTrueRange() / syminfo.mintick
else
// 计算带两位小数的ATR货币价值
math.round(AvgTrueRange() * syminfo.pointvalue * posSize * 100) / 100
我们在这里创建的 atrValue 变量会得到4个可能的值之一。为了得出这个值,我们通过一系列 if 语句来评估“ATR Type”输入选项。然后,我们使用刚才创建的 AvgTrueRange() 函数来得出ATR的基础值。
第一个 if 关键字评估输入选项是否被设为“Regular”。如果是,我们就简单地调用 AvgTrueRange()。该函数的结果随后被赋给 atrValue 变量。如果“ATR Type”的设置是其他值,下一个 if 语句会判断该值是否是“Percentage”。在这种情况下,我们将ATR计算为当前品种收盘价(close)的百分比。
再下一个 if 关键字判断 atrType 输入变量是否等于“Ticks”。如果是,我们将平均真实波幅除以 syminfo.mintick。这个内置变量返回当前图表交易品种的最小价格变动单位。例如,对于股票,syminfo.mintick 返回0.01。这意味着当ATR为0.50时,以跳动点数表示的平均真实波幅为50(0.50 / 0.01)。
如果最后一个 if 条件也不成立,那么最后的 else 代码块会以货币价值来计算ATR。这段代码将 AvgTrueRange() 的结果乘以 syminfo.pointvalue 和 posSize。syminfo.pointvalue 变量返回图表品种价格每变动一个完整点所代表的货币价值。posSize 则是我们“Position Size (For Currency ATR)”输入选项的变量。
为了让以货币表示的平均真实波幅在图表上更美观地显示,我们先将其乘以100,然后使用 math.round() 函数四舍五入到最近的整数,最后再除以100,这样我们就得到了保留两位小数的货币价值。
下一段代码计算ATR的移动平均线:
// 计算ATR的移动平均线,前提是输入的周期 > 1
atrMA = maLength > 1 ? ta.ema(atrValue, maLength) : na
这个 atrMA 变量通过TradingView的条件运算符(?:)来有条件地获取其值。其目的是根据“MA Length”输入选项来启用或禁用ATR的移动平均线。
当该输入值大于1时,我们使用 ta.ema() 函数来计算移动平均线。我们让该函数处理我们刚刚计算出的ATR值(atrValue),并使用 maLength 输入变量作为计算EMA的周期。
当 maLength 不大于1时,我们让条件运算符返回 na 值。这使得 atrMA 的值不会出现在图表上。这之所以有效,是因为在脚本的后续部分,我们使用 plot() 来绘制 atrMA 的值,而该函数不会绘制NaN值。因此,只有当我们在 atrMA 变量中放入一个实际的数值时,该移动平均线才会显示在图表上。
步骤三:确定指标的基于波动率的信号
但在绘制指标值之前,我们首先要确定一些平均真实波幅的信号。这样我们就可以在图表上高亮显示特定的市场状况,或者在发生异常情况时生成TradingView警报。
我们的平均真实波幅脚本将寻找以下6种情况:
// 步骤三:确定指标信号
risingMA = atrMA > atrMA[1] and atrMA[1] > atrMA[2]
fallingMA = atrMA < atrMA[1] and atrMA[1] < atrMA[2]
atrCrossover = ta.crossover(atrValue, atrMA)
atrCrossunder = ta.crossunder(atrValue, atrMA)
highAtr = atrValue > ta.highest(atrValue, 20)[1]
lowAtr = atrValue < ta.lowest(atrValue, 20)[1]
前两个条件判断ATR的移动平均线是否连续两根K线上升或下降。对于 risingMA 变量,我们判断当前的均线值(atrMA)是否大于前一根K线的值(atrMA[1]),并且前一根K线的值是否也高于更前一根(atrMA[2])。当这两个条件同时满足时,risingMA 变量的值为 true,否则为 false。
为了判断ATR的均线是否连续两根K线下降,我们判断 atrMA 是否小于前一根K线(atrMA[1]),并且前一根是否也小于更前一根(atrMA[1] < atrMA[2])。当这两个条件都满足时,fallingMA 的值为 true(否则为 false)。
第二对信号判断平均真实波幅是否与其移动平均线发生交叉。我们使用 ta.crossover() 函数来判断平均真实波幅(atrValue)是否上穿了其移动平均线(atrMA)。如果确实发生了,ta.crossover() 返回 true(否则返回 false)。
我们使用 ta.crossunder() 函数来判断ATR是否下穿了其移动平均线。如果是,ta.crossunder() 返回 true。我们将这两个函数的结果分别存储在 atrCrossover 和 atrCrossunder 变量中,以供后续使用。
然后,我们判断平均真实波幅是否达到了我们所认为的高或低的水平。对于高值,我们调用 ta.highest() 函数,并将 atrValue 和 20 作为参数传入,这会得到过去20根K线的最高ATR值。为了查看近期的低ATR值,我们执行 ta.lowest() 函数。
我们使用历史引用运算符([])将这两个函数都向过去偏移一根K线,从而得到之前20根K线的最高和最低ATR值。然后我们判断当前的ATR是高于还是低于这些值。如果是,highAtr 或 lowAtr 变量的值就为 true(否则为 false)。
步骤四:绘制指标的数据与信号
在第四步中我们要做几件事:首先绘制平均真实波幅,然后显示它的移动平均线,之后用彩色背景高亮显示不寻常的ATR读数。
为了绘制平均真实波幅,我们使用TradingView的 plot() 函数:
// 步骤四:输出指标数据
plot(atrValue, color=color.orange, title="ATR")
我们在这里创建的是一个基本的线图。通过函数的第一个参数,我们显示了之前计算出的ATR值(atrValue)。对于绘图的颜色,我们使用橙色(color.orange)。通过 title 参数,我们将该绘图命名为“ATR”。这个名称会显示在图表的数据窗口和指标的设置窗口中。
然后,我们显示ATR的移动平均线:
// 显示ATR的移动平均线
maColour = not colourMA ? color.teal :
risingMA ? color.green :
fallingMA ? color.red :
color.teal
plot(atrMA, color=maColour, title="ATR EMA")
这里,我们首先确定要给移动平均线使用哪种颜色。为此,我们创建了 maColour 变量,并将其设为三种可能的颜色之一:color.teal、color.green 或 color.red。该变量具体得到哪种颜色,取决于我们用同样数量的条件运算符(?:)所评估的条件。
当 colourMA 输入变量为 false 时,即“Colour MA Line?”输入选项被禁用,我们使用默认的 color.teal 颜色。否则,第二个条件运算符会检查 risingMA 变量是否为 true,这种情况发生在移动平均线连续两根K线上涨时,此时我们使用 color.green 作为绘图颜色。
若不满足,第三个条件运算符会判断 fallingMA 是否为 true,这种情况发生在ATR移动平均线连续两根K线下跌时,我们将为此场景使用 color.red。当移动平均线既没有连续上涨也没有连续下跌时,这最后一个条件运算符也默认使用 color.teal。
要实际绘制移动平均线,我们调用 plot() 函数,将其第一个参数设为 atrMA,颜色参数 color 设为我们刚才确定的 maColour 变量。通过 title 参数,我们为该绘图指定一个描述性的名称。由于我们没有定义绘图类型,TradingView默认会创建一个标准的线图。
接下来,我们高亮显示有ATR信号发生的K线:
// 高亮ATR信号
bgColour = (atrCrossover or atrCrossunder) ? color.new(color.orange, 80) :
highAtr ? color.new(color.red, 80) :
lowAtr ? color.new(color.green, 80) :
na
bgcolor(highlight ? bgColour : na)
我们首先创建 bgColour 变量来存储背景的信号颜色。具体使用哪种颜色取决于由TradingView条件运算符(?:)处理的三个表达式。第一个条件运算符判断ATR是否与其移动平均线发生交叉(即 atrCrossover 或 atrCrossunder 为 true)。对于这种情况,我们使用橙色(color.orange),并通过 color.new() 函数为其设置透明度。
否则,我们检查ATR是否达到了20周期的最高点(highAtr),如果是,我们将使用一个透明的红色(color.red)。再否则,我们检查 lowAtr,当平均真实波幅跌至20周期最低点时,该值为 true,我们为此情况使用带有透明度的绿色(color.green)。
如果以上条件都不成立,我们的 bgColour 变量就会得到 na 值,这样图表的背景就不会被应用任何颜色。通过这种方式,我们只在发生值得注意的事情时才为背景着色。
要实际为图表背景上色,我们调用 bgcolor() 函数。我们通过条件运算符(?:)来设置其第一个参数。当 highlight 为 true 时,我们使用 bgColour 变量的值;否则,我们使用 na 来关闭任何背景色。(highlight 变量来自我们之前创建的“Highlight ATR Signals?”输入选项。)
步骤五:为TradingView指标添加警报条件
在第五步也是最后一步中,我们为平均真实波幅脚本添加一些警报。为此,我们对想要创建的每种警报都调用一次 alertcondition() 函数。代码如下:
// 步骤五:创建指标警报
// 基于ATR移动平均线的警报
alertcondition(condition=risingMA,
title="Rising ATR",
message="The Average True Range's average increased 2 bars in a row")
alertcondition(condition=fallingMA,
title="Declining ATR",
message="The Average True Range's average decreased 2 bars in a row")
// ATR与其移动平均线交叉的警报
alertcondition(condition=atrCrossover,
title="ATR Crossover",
message="The Average True Range crossed above its EMA")
alertcondition(condition=atrCrossunder,
title="ATR Crossunder",
message="The Average True Range crossed under its EMA")
// ATR达到近期高点或低点的警报
alertcondition(condition=highAtr,
title="ATR New High",
message="The Average True Range crossed its 20-bar high")
alertcondition(condition=lowAtr,
title="ATR New Low",
message="The Average True Range crossed its 20-bar low")
虽然这段代码执行了6次 alertcondition() 函数,但每次调用的逻辑都非常相似。因此,我们只讨论其中一个来了解全部6个是如何工作的:
alertcondition(condition=risingMA,
title="Rising ATR",
message="The Average True Range's average increased 2 bars in a row")
这里我们用三个参数调用 alertcondition() 函数。第一个参数 condition 需要一个布尔值来指定警报何时触发,我们为此使用了 risingMA 变量。根据我们之前的定义,当ATR的移动平均线连续两根K线上涨时,其值为 true。当均线没有连续上涨两根K线时,该变量为 false,警报便不会激活。
通过 title 参数,我们为警报命名。这个名称会出现在“创建警报”窗口中,帮助我们将不同的脚本警报区分开来。message 参数则定义了默认的警报消息。当警报触发时,这段文字会显示在弹出窗口中,或者根据警报设置显示在电子邮件或短信中。
请注意,在任何警报可以触发之前,你都需要先手动启用并配置它们。
在TradingView中绘制平均真实波幅(ATR)指标
现在我们已经将平均真实波幅编写成一个TradingView脚本,让我们看看它在图表上的实际表现。ATR的一个特性是它能显示价格波动性随时间的变化。有时,ATR甚至会呈现出清晰且可预测的模式,就像我们在这张欧元/美元30分钟图上看到的那样:
平均真实波幅不仅能显示波动性(以及交易风险)何时增加,这个指标还能预示价格趋势的强度。在下图中,ATR随着上升趋势的发展而增加。但当平均真实波幅开始横盘整理(并最终跌破其移动平均线)时,趋势也随之失去了其上涨动能:
我们为脚本赋予的另一个功能是能够以交易品种的跳动点来显示ATR。下图就是一个例子。在这里我们可以看到,在一次急剧抛售期间,E-mini S&P 500期货的日均波幅超过了200个跳动点:
在代码中,我们还通过高亮背景色来让我们能轻松发现波动性何时增加、减少或达到近期高点或低点。下图就是这些高亮效果的一个例子。
在这张比特币(BTC/USD)30分钟图上的两次价格飙升之前,都有几根K线的平均真实波幅持续创下20周期新低。事后看来,这些低波动时期之后都伴随着强劲的价格飙升:
完整代码:适用于TradingView的平均真实波幅(ATR)指标
我们在本文中创建的平均真实波幅脚本的完整代码如下。关于代码的细节和解释,请参阅上文的讨论。
//@version=5
// 步骤一:脚本设置
indicator(title="Average True Range", shorttitle="ATR", overlay=false)
// ATR输入选项
atrType = input.string("Regular", title="ATR Type",
options=["Regular", "Percentage", "Ticks", "Currency"])
atrLen = input.int(14, title="ATR Length")
atrSmooth = input.string("RMA", title="Smoothing Type",
options=["EMA", "RMA", "SMA", "WMA"])
posSize = input.int(1, title="Position Size (For Currency ATR)")
// 要禁用ATR的移动平均线,请将其周期设为1
maLength = input.int(21, title="MA Length", minval=1)
colourMA = input.bool(true, title="Colour MA Line?")
highlight = input.bool(false, title="Highlight ATR Signals?")
// 步骤二:计算指标数值
// 根据输入选项设置的平滑类型
// 计算平均真实波幅的自定义函数
AvgTrueRange() =>
if atrSmooth == "EMA"
ta.ema(ta.tr, atrLen)
else if atrSmooth == "RMA"
ta.rma(ta.tr, atrLen)
else if atrSmooth == "SMA"
ta.sma(ta.tr, atrLen)
else
ta.wma(ta.tr, atrLen)
// 根据'ATR Type'输入选项
// 计算平均真实波幅值
atrValue = if atrType == "Regular"
AvgTrueRange()
else if atrType == "Percentage"
(AvgTrueRange() / close) * 100
else if atrType == "Ticks"
AvgTrueRange() / syminfo.mintick
else
// 计算带两位小数的ATR货币价值
math.round(AvgTrueRange() * syminfo.pointvalue * posSize * 100) / 100
// 计算ATR的移动平均线,前提是输入的周期 > 1
atrMA = maLength > 1 ? ta.ema(atrValue, maLength) : na
// 步骤三:确定指标信号
risingMA = atrMA > atrMA[1] and atrMA[1] > atrMA[2]
fallingMA = atrMA < atrMA[1] and atrMA[1] < atrMA[2]
atrCrossover = ta.crossover(atrValue, atrMA)
atrCrossunder = ta.crossunder(atrValue, atrMA)
highAtr = atrValue > ta.highest(atrValue, 20)[1]
lowAtr = atrValue < ta.lowest(atrValue, 20)[1]
// 步骤四:输出指标数据
plot(atrValue, color=color.orange, title="ATR")
// 显示ATR的移动平均线
maColour = not colourMA ? color.teal :
risingMA ? color.green :
fallingMA ? color.red :
color.teal
plot(atrMA, color=maColour, title="ATR EMA")
// 高亮ATR信号
bgColour = (atrCrossover or atrCrossunder) ? color.new(color.orange, 80) :
highAtr ? color.new(color.red, 80) :
lowAtr ? color.new(color.green, 80) :
na
bgcolor(highlight ? bgColour : na)
// 步骤五:创建指标警报
// 基于ATR移动平均线的警报
alertcondition(condition=risingMA,
title="Rising ATR",
message="The Average True Range's average increased 2 bars in a row")
alertcondition(condition=fallingMA,
title="Declining ATR",
message="The Average True Range's average decreased 2 bars in a row")
// ATR与其移动平均线交叉的警报
alertcondition(condition=atrCrossover,
title="ATR Crossover",
message="The Average True Range crossed above its EMA")
alertcondition(condition=atrCrossunder,
title="ATR Crossunder",
message="The Average True Range crossed under its EMA")
// ATR达到近期高点或低点的警报
alertcondition(condition=highAtr,
title="ATR New High",
message="The Average True Range crossed its 20-bar high")
alertcondition(condition=lowAtr,
title="ATR New Low",
message="The Average True Range crossed its 20-bar low")








