计算指数移动平均线(EMA)
在Pine Script中,我们使用 ta.ema() 函数来计算指数移动平均线(EMA)。
指数移动平均线会给予近期数据更多的权重(从而降低旧数据的重要性)。它使用指数加权的方式来偏重近期数据而非旧数据。这使得该平均线相比于例如简单移动平均线,能更快地对新价格做出反应。
默认语法
该函数的定义如下:
ta.ema(source, length)
source:要处理的数值序列。这是我们希望EMA在其上进行计算的数据。length:一个整数,用于设置移动平均线的周期长度(以K线数量计)。
ta.ema() 会返回一个浮点值,该值是 source 在过去 length 根K线上的指数平均值。
快速范例
所以,ta.ema() 需要两样东西:一个要处理的数值序列,以及要计算的K线数量。让我们看看这在实践中是如何运作的。
- 一个常见的任务是计算收盘价的指数移动平均线。为此,我们让该函数在
close变量上运行,像这样:// 计算10周期和50周期的指数移动平均线 (EMA) fastAverage = ta.ema(close, 10) slowAverage = ta.ema(close, 50) plot(fastAverage, color=color.navy) plot(slowAverage, color=color.fuchsia) - 除了K线价格,我们也可以计算任何数值序列的指数移动平均线。比方说,我们想要平均成交量。在这种情况下,我们可以这样做:
// 获取10周期的成交量EMA volumeAverage = ta.ema(volume, 10) plot(volumeAverage) - 从任何返回一个数据序列的数值表达式中获取平均值也是可以的。例如,如果我们想要获取单根K线收盘价差值的平均值,可以这样编码:
// 获取收盘价差值的20周期指数平均值 averageCloseDiff = ta.ema(close - close[1], 20) plot(averageCloseDiff) - 由于
ta.ema()可以处理任何数值序列,它也可以处理由其他函数计算出的数据。比方说,我们用ta.mom()函数计算动量指标。为了平滑该指标,我们在其值上调用ta.ema()。例如:// 首先计算动量,然后取其EMA值 closeMomentum = ta.mom(close, 10) avgMomentum = ta.ema(closeMomentum, 5) plot(closeMomentum) plot(avgMomentum, color=color.orange) - 如果我们不需要将动量作为一个单独的值来使用,那么为了简化代码,我们可以直接在
ta.mom()函数上调用ta.ema():// 首先计算动量,然后取其EMA值 avgMomentum = ta.ema(ta.mom(close, 10), 5) plot(avgMomentum, color=color.orange)
ta.ema() 的特性
- 指数移动平均线所使用的加权因子是呈指数级递减的。这给予了最近的K线最高的权重,而之前的K线随着时间的推移,其权重会显著降低。
ta.ema()函数可能会导致脚本重绘(repainting)。为了计算EMA,Pine Script会使用到前一根K线的数据。这使得EMA对脚本在哪一根K线开始计算非常敏感。由于TradingView的图表没有固定的时间范围,而是会根据我们打开图表的时间来决定从哪个日期开始加载数据,因此在过去的历史K线上可能会发生重绘现象。- 要看指数移动平均线是上升还是下降,我们可以比较它的当前值和前一个值。我们使用
ta.rising()函数可以判断平均线是否已连续上涨了指定数量的K线。同样地,ta.falling()函数可以判断平均线是否已连续下跌了指定数量的K线。 - 要判断一个序列是否与指数移动平均线发生交叉,我们使用
ta.cross()函数。要测试向上穿越,我们使用ta.crossover()函数;而ta.crossunder()函数则用于找出是否发生了向下穿越。
计算过程
TradingView计算指数移动平均线的公式如下:
在代码层面,以下是EMA在Pine Script中的计算方式:
pine_ema(src, length) =>
alpha = 2 / (length + 1)
sum = 0.0
sum := na(sum[1]) ?
src :
alpha * src + (1 - alpha) * nz(sum[1])
plot(pine_ema(close, 15))
当然,与这个自定义函数相比,使用内置的 ta.ema() 函数会更方便。
脚本范例
让我们看看一个完整的脚本如何使用指数移动平均线(EMA)。下方的指标会计算两条EMA:一条10周期和一条30周期的,都基于收盘价。
我们在图表上显示这些平均线,然后将K线的收盘价与这两条平均线进行比较来判断趋势。基于这个评估,我们为图表赋予特定的背景颜色。
该指标的完整代码如下:
//@version=5
indicator(title="Exponential Moving Average example", overlay=true)
// 输入选项
averageData = input.source(close, title="Average Data Source")
fastLength = input.int(10, title="Fast Average Length")
slowLength = input.int(30, title="Slow Average Length")
// 计算指数移动平均线
fastAverage = ta.ema(averageData, fastLength)
slowAverage = ta.ema(averageData, slowLength)
// 绘制平均线
plot(fastAverage, color=color.navy, title="Fast EMA")
plot(slowAverage, color=color.fuchsia, linewidth=2, title="Slow EMA")
// 用一个有色的背景显示移动平均线趋势
backgroundColor = if close > fastAverage and fastAverage > slowAverage
color.new(color.green, 85)
else if close < fastAverage and fastAverage < slowAverage
color.new(color.red, 85)
else
color.new(color.orange, 90)
bgcolor(backgroundColor, title="EMA Background")
我们以 indicator() 函数开始,用于命名该脚本并将其输出叠加显示在主图的交易品种上。
然后,我们通过三个输入项来创建自定义设置。第一个是数据源输入选项(input.source()),用于指定EMA的计算数据。另外两个设置是使用 input.int() 函数创建的整数输入,它们用于设定移动平均线的周期长度。
接下来,我们计算移动平均线:
// 计算指数移动平均线
fastAverage = ta.ema(averageData, fastLength)
slowAverage = ta.ema(averageData, slowLength)
第一个 ta.ema() 函数调用计算快速平均线。该函数处理 averageData 输入变量,该变量默认持有交易品种的收盘价。对于周期长度,我们使用 fastLength,其默认值为10。
我们以类似的方式计算较慢的平均线。我们再次调用 ta.ema() 函数,并让它在 averageData 值上运行。对于平均线的长度,我们使用 slowLength 输入变量,其初始值为30。
在计算完平均线后,脚本继续执行其他代码。这些代码首先用 plot() 函数在图表上绘制两条移动平均线。我们让快线显示为海军蓝(color.navy),慢线则使用紫红色(color.fuchsia)。由于我们没有设置绘图类型,Pine Script会默认创建常规的线图。
然后,一个级联 if 语句用于判断背景颜色的信号。当K线的收盘价(close)高于快线,且快线高于慢线时,我们使用一个通过 color.new() 设置了透明度的绿色(color.green)作为背景。
如果收盘价低于快线,且快线低于慢线时,我们则使用一个通过 color.new() 函数设置了透明度的红色(color.red)。如果这两种信号都未发生,我们使用一个透明的橙色(color.orange)作为默认背景。
代码的最后一行让 bgcolor() 函数将这些颜色之一应用到图表上。
在图表上,我们得到了两条用于快慢平均线的实线。彩色的背景告诉我们它们之间以及与K线收盘价的关系:
总结
ta.ema()函数用于计算指数移动平均线(EMA)。- 为了执行其功能,
ta.ema()需要两样东西:一个要处理的数值序列,以及要计算的K线数量。
计算加权移动平均线(WMA)
在Pine Script中,我们使用 ta.wma() 函数来计算加权移动平均线(WMA)。
加权移动平均线会给予近期数据更多的权重(并认为旧数据不那么重要)。为了达到这个效果,该平均线会将每一根K线的值乘以一个特定的加权因子。
这使得加权移动平均线与简单移动平均线不同,后者给予每个数据点相同的权重。其结果是,WMA对新价格的反应更快。
默认语法
ta.wma() 函数的定义如下:
ta.wma(source, length)
source:要处理的数值序列。这是我们计算WMA所依据的数据。length:一个整数,用于设置移动平均线的周期长度(以K线数量计)。这是平均线的回看周期。
ta.wma() 会返回一个浮点值,该值是 source 在过去 length 根K线上的加权平均值。
快速范例
所以,ta.wma() 需要我们提供两样东西:要处理的数据和周期的长度(以K线为单位)。让我们看看该如何操作。
- 移动平均线通常使用K线的收盘价进行计算。要让加权移动平均线使用该数据进行计算,我们向该函数传入
close变量,像这样:// 获取20周期和45周期的收盘价加权移动平均线 wmaFast = ta.wma(close, 20) wmaSlow = ta.wma(close, 45) plot(wmaFast, color=color.blue) plot(wmaSlow, color=color.orange) - 除了K线价格,加权移动平均线可以对任何数值序列进行计算。例如,如果我们想要平均成交量,我们可以这样做:
// 获取10周期的成交量加权平均值 wmaVolume = ta.wma(volume, 10) plot(volume, style=plot.style_histogram) plot(wmaVolume) ta.wma()函数也可以获取一个数值表达式的平均值。例如,下面的代码计算了K线收盘价与开盘价之间差值的平均值:// 获取收盘价-开盘价差异的平均值 wmaOpenClose = ta.wma(close - open, 25) plot(wmaOpenClose)- 另一个选择是在其他函数返回的数据上计算平均值。比方说,我们计算了一个简单移动平均线。为了平滑该平均线,我们计算该简单移动平均线的加权移动平均线,像这样:
// 计算SMA,然后用WMA进行平滑 smaValue = ta.sma(close, 20) wmaSmooth = ta.wma(smaValue, 5) plot(smaValue, color=color.fuchsia) plot(wmaSmooth, color=color.red) - 如果我们不需要将SMA作为一个单独的值来使用,那么为了简化代码,我们可以将
ta.sma()直接放在ta.wma()函数内部:// 计算SMA,然后用WMA进行平滑 wmaSmooth = ta.wma(ta.sma(close, 20), 5) plot(wmaSmooth, color=color.red)
ta.wma() 的特性
- 加权移动平均线所使用的加权因子呈算术级数递减。这意味着,每个数据点获得的权重是线性减少的,而不是指数级减少(像指数移动平均线那样)。
- 要检查加权移动平均线是上涨还是下跌,我们可以比较它的当前值与前一根K线。通过
ta.rising()函数,我们可以判断平均线是否已连续上涨了指定数量的K线。同样地,ta.falling()函数可以判断平均线是否已连续下跌了指定数量的K线。 - 要判断一个序列是否与加权移动平均线发生交叉,我们使用
ta.cross()函数。要寻找向上穿越,我们使用ta.crossover()函数;而ta.crossunder()函数则告诉我们是否发生了向下穿越。
计算过程
在代码层面,以下是TradingView在幕后计算加权移动平均线的方式:
pine_wma(source, length) =>
norm = 0.0
sum = 0.0
for i = 0 to length - 1
weight = (length - i) * length
norm := norm + weight
sum := sum + source[i] * weight
sum / norm
plot(pine_wma(close, 15))
与其使用这个自定义函数,我们最好还是使用内置的 ta.wma() 函数,这样做不仅工作量更少,运行效率也更高。
脚本范例
让我们看看一个脚本如何使用加权移动平均线(WMA)。下方的指标在图表上绘制了8周期和36周期的加权平均线。
为了编写WMA信号,我们比较K线的收盘价与两条移动平均线。我们认为,价格高于快线但尚未高于慢线的情况为买入信号;而价格低于快线但尚未低于慢线,则视为卖出信号。
该指标的完整代码如下:
//@version=5
indicator(title="Weighted Moving Average example", overlay=true)
// 输入项
averageData = input.source(close, title="Average Data Source")
fastLength = input.int(8, title="Fast Average Length")
slowLength = input.int(36, title="Slow Average Length")
// 计算移动平均线
fastAverage = ta.wma(averageData, fastLength)
slowAverage = ta.wma(averageData, slowLength)
// 绘制平均线
plot(fastAverage, color=color.blue, title="Fast WMA")
plot(slowAverage, color=color.orange, title="Slow WMA")
// 用绿色和红色背景高亮WMA的设置形态
wmaSignalColour = if close > fastAverage and close < slowAverage
color.new(color.green, 80)
else if close < fastAverage and close > slowAverage
color.new(color.red, 80)
bgcolor(wmaSignalColour, title="WMA Signals Background")
首先,我们使用 indicator() 函数来配置该脚本,用于命名脚本并将其显示在主图的交易品种上。
然后,我们创建了三个输入项。第一个是数据源输入选项(input.source()),用于指定加权移动平均线的计算数据。另外两个设置是整数输入(input.int()),它们用于配置移动平均线的周期长度。
接下来,我们计算加权平均线:
// 计算移动平均线
fastAverage = ta.wma(averageData, fastLength)
slowAverage = ta.wma(averageData, slowLength)
第一个 ta.wma() 调用计算快速平均线。我们让该函数处理 averageData 输入变量(默认为收盘价),周期长度则使用 fastLength,其初始值为8。
我们然后再次调用 ta.wma() 来计算慢速加权平均线。这条也运行在 averageData 价格上,但周期长度为 slowLength 根K线,其默认值为36。
在计算完平均线后,脚本继续执行其他代码。这些代码首先用 plot() 函数在图表上绘制两条平均线。我们让快线显示为蓝色(color.blue),慢线则为橙色(color.orange)。由于我们没有设置绘图类型,Pine Script会默认创建常规的线图。
然后,一个级联 if 语句用于寻找一个交易设置。当K线的收盘价高于快线,但同时也低于慢线时,我们使用一个通过 color.new() 设置了透明度的绿色(color.green)来高亮这个形态。如果K线收盘低于快线,但仍然高于慢线,我们则使用透明的红色(color.red)。
在代码的最后一行,bgcolor() 函数将该背景颜色应用到图表上。这就是加权平均线的信号显示方式。
在图表上,我们得到了两条用于快慢加权移动平均线的实线。彩色的背景显示了K线的收盘价与这些平均线的比较情况:
总结
ta.wma()函数用于计算加权移动平均线(WMA)。- 要获取该平均值,我们向
ta.wma()提供一个要处理的数值序列,以及一个要计算的K线数量。





