计算对称加权移动平均线(SWMA)
在Pine Script语言中,我们可以用 ta.swma() 函数来计算对称加权移动平均线(Symmetrically-Weighted Moving Average, SWMA)。
SWMA的特点在于它为不同的数据点分配了不同的权重,并且这些权重是呈对称分布的。在这种权重分配模式下,最新和最旧的K线所占的权重较小,而权重最大的K线则位于计算周期长度的中间位置。
默认用法
该函数的定义如下:
ta.swma(source)
source 指的是用于计算的数值序列,也就是我们希望计算其对称加权移动平均值的数据源。
ta.swma() 函数会返回一个浮点数类型的SWMA值。
代码示例
要计算对称加权移动平均线,我们只需要为该函数提供一样东西:用于计算的数据源。让我们来看几个具体的例子。
计算收盘价的平均值是移动平均线的一个常见应用。要获取基于K线收盘价的SWMA,我们只需将 close 变量传入函数即可:
// 计算收盘价的对称加权移动平均线
closeAverage = ta.swma(close)
plot(closeAverage)
除了常规的K线价格,我们也可以基于任何其他变量来计算SWMA。例如,如果我们想计算K线中间价((high + low) / 2)的平均值,可以这么写:
// 获取K线高低价平均值的对称移动平均线
hlAverage = ta.swma(hl2)
plot(hlAverage)
ta.swma() 的应用不限于内置变量。事实上,该函数可以处理任何在每根K线上都有数值的表达式。例如,我们想计算K线之间开盘价的变化的平均值,可以这么做:
// 计算开盘价在1根K线内的变化量的平均值
openDiffAverage = ta.swma(open - open[1])
plot(openDiffAverage)
另一种用法是让 ta.swma() 来处理另一个函数的计算结果。例如,在计算出相对强弱指数 (RSI)后,如果想进一步获取该指标的对称加权移动平均线,可以这么写:
// 计算7周期RSI及其对称加权移动平均线
rsiValue = ta.rsi(close, 7)
rsiAverage = ta.swma(rsiValue)
plot(rsiValue)
plot(rsiAverage, color=color.orange)
如果我们的脚本并不需要RSI的原始值,也可以将 ta.rsi() 函数直接嵌套在 ta.swma() 函数内部。这样可以得到相同的结果,但代码更为简洁:
// 计算7周期RSI的对称加权移动平均线
rsiAverage = ta.swma(ta.rsi(close, 7))
plot(rsiAverage, color=color.orange)
ta.swma() 函数的特性
与大多数其他移动平均线不同,我们无法自定义 ta.swma() 函数的计算周期。Pine Script将其周期固定为4根K线。
同样,我们也无法控制SWMA使用的权重。TradingView将其预设为:1/6, 2/6, 2/6, 1/6。
计算逻辑
Pine Script的 ta.swma() 函数通过以下方式来计算其对称加权移动平均线:
SWMA会为计算周期内的每个数据点赋予一个特定权重,而这些权重呈对称分布。由于其周期固定为4根K线,TradingView为前两根K线赋予的权重分别为1/6和2/6,后两根K线的权重则为2/6和1/6。这样就构成了一个1/6, 2/6, 2/6, 1/6的对称权重结构。
用于实现 ta.swma() 函数功能的Pine Script等效代码如下:
pine_swma(source) =>
source[3] * 1 / 6 + source[2] * 2 / 6 +
source[1] * 2 / 6 + source[0] * 1 / 6
plot(pine_swma(close))
为了方便起见,我们通常直接使用 ta.swma() 函数,而不是这个自定义函数。而且,TradingView官方实现的内置函数可能在执行效率(速度)上更具优势。
脚本示例
接下来,我们来探讨如何在脚本中使用对称加权移动平均线。下面的指标代码计算了两条SWMA:一条基于收盘价,另一条基于K线的中点价格((high + low) / 2)。
我们会在图表上同时绘制这两条平均线,并根据它们的相对位置来着色K线。如果收盘价的平均线穿越到中点价平均线的上方,我们视其为强势信号,并用相应的颜色标记K线;反之,则视为弱势信号(并将K线标记为红色)。
完整的指标代码如下:
//@version=5
indicator(title="Symmetrically Weighted Moving Average example",
overlay=true)
// 输入选项
firstAvgData = input.source(close, title="First Average Data")
secondAvgData = input.source(hl2, title="Second Average Data")
// 计算对称加权移动平均线
firstAverage = ta.swma(firstAvgData)
secondAverage = ta.swma(secondAvgData)
// 在图表上绘制平均线
plot(firstAverage, color=color.navy)
plot(secondAverage, color=color.fuchsia)
// 决定K线颜色
swmaColour = if firstAverage > secondAverage
color.green
else if firstAverage < secondAverage
color.red
else
color.gray
barcolor(swmaColour)
代码首先通过 indicator() 函数来配置脚本。其中,title 参数为脚本命名,overlay=true 则让脚本直接叠加显示在主图的交易品种上。
接着,我们创建了两个输入项。这两个都是通过 input.source() 函数创建的数据源输入选项,用于指定两条SWMA分别使用什么数据进行计算。
有了输入数据源后,我们就可以计算这些平均线了:
// 计算对称加权移动平均线
firstAverage = ta.swma(firstAvgData)
secondAverage = ta.swma(secondAvgData)
我们两次调用了 ta.swma() 函数。第一次,函数处理 firstAvgData 这个输入变量,该变量默认指向交易品种的收盘价(close)。第二条SWMA则处理 secondAvgData 输入变量,该变量默认指向 hl2,即K线的中点价格((high + low) / 2)。
计算出平均值后,脚本继续执行其余代码。首先,通过 plot() 函数绘制这两条平均线。第一条SWMA显示为海军蓝(color.navy),另一条则为紫红色(color.fuchsia)。由于我们没有指定绘图类型,Pine Script默认会将它们绘制成常规的线图。
随后,一个级联 if 语句被用来决定K线的颜色。代码首先判断收盘价SWMA是否大于中点价SWMA,如果是,则选用绿色(color.green)。否则,继续判断收盘价平均线是否小于中点价平均线,如果是,则选用红色(color.red)。在其他情况(即两条平均线相等)下,我们最终选择灰色(color.gray)。
最后一行代码调用 barcolor() 函数,将我们选定的颜色应用到图表的K线上。
加载到图表上后,该指标会绘制出两条对称加权移动平均线。由于计算它们的价格源(收盘价和中点价)很接近,这两条线通常会靠得很近。尽管如此,图表上用红色和绿色标记的K线依然能够捕捉到价格的短期上涨和下跌趋势:
总结
ta.swma() 函数用于计算对称加权移动平均线(SWMA)。
该函数仅需要提供用于计算的数据源。它的计算周期已被TradingView预设为4根价格K线。
计算Arnaud Legoux移动平均线(ALMA)
在Pine Script语言中,我们使用 ta.alma() 函数来计算 Arnaud Legoux移动平均线(ALMA)。
默认用法
该函数的定义如下:
ta.alma(series, length, offset, sigma, floor)
series 指的是用于计算的数值序列,也就是我们希望计算其ALMA的(价格)数据源。
length 是一个整数,用于设定移动平均线的计算周期(以K线数量计)。
offset 是一个浮点数,用于在平均线的平滑度与响应度之间进行取舍。
- 要获得更平滑(但更滞后)的ALMA,应使用接近
1的offset值。 - 要获得响应更灵敏(但噪音更多)的ALMA,应使用接近
0的offset值。
sigma 是一个数值,用于控制ALMA的额外平滑度。此值越高,平均线就越平滑。
floor 是一个可选的布尔值(true/false),用于指定是否应对偏移量计算的结果进行向下取整。(在编程术语中,floor即为向下取整)。
- 若为
true,Pine Script会在计算最终ALMA值之前,先将偏移量的计算结果向下取整。 - 若为
false,则不进行取整。如果不提供此参数,false也是默认设置。
ta.alma() 函数会返回一个浮点数类型的Arnaud Legoux移动平均线值。
代码示例
要计算Arnaud Legoux移动平均线,我们需要为 ta.alma() 函数提供最多5个参数。让我们通过实践来看看如何使用它。
移动平均线的一个常见用途是计算交易品种收盘价的平均值。要获取基于收盘价的ALMA,我们可以这样使用 ta.alma() 函数:
// 计算周期为12、偏移量为0.70、sigma为7的收盘价ALMA
almaValue = ta.alma(close, 12, 0.70, 7)
plot(almaValue)
除了常规的K线价格(如收盘价),我们也可以基于任何数值序列变量来计算ALMA。例如,要计算成交量的平均值,可以这么做:
// 计算周期为20、偏移量为0.5、sigma为9的成交量ALMA
volumeAlma = ta.alma(volume, 20, 0.5, 9)
plot(volumeAlma)
ta.alma() 的应用不限于内置变量,它能够处理任何在每根K线上都有数值的表达式。比如,我们想计算过去10根K线的收盘价变化量(一种动量指标),可以这么写:
// 计算10周期收盘价变化量的30周期ALMA,偏移量为0.75,sigma为12
momentumAlma = ta.alma(close - close[10], 30, 0.75, 12)
plot(momentumAlma)
另一种用法是利用ALMA来平滑另一个函数的计算结果。假设我们想平滑一条指数移动平均线(EMA),只需将EMA的计算结果传入 ta.alma() 函数即可:
// 计算20周期EMA的10周期ALMA,偏移量为0.6,sigma为4
emaValue = ta.ema(close, 20)
almaValue = ta.alma(emaValue, 10, 0.6, 4)
plot(emaValue)
plot(almaValue, color=color.orange)
如果我们的脚本并不需要EMA的原始值,也可以将 ta.ema() 函数直接嵌套在 ta.alma() 函数内部。这样代码更为简洁,且能得到相同的结果:
// 计算20周期EMA的10周期ALMA,偏移量为0.6,sigma为4
almaValue = ta.alma(ta.ema(close, 20), 10, 0.6, 4)
plot(almaValue, color=color.orange)
计算逻辑
Arnaud Legoux移动平均线的核心思想是为不同的数据点分配不同的权重。这些权重是根据高斯分布(Gaussian distribution)来确定的。
从Pine Script代码的角度来看,ALMA的实现逻辑如下:
pine_alma(series, windowsize, offset, sigma) =>
m = offset * (windowsize - 1)
// 当floor参数为true时,m的计算方式如下
// m = math.floor(offset * (windowsize - 1))
s = windowsize / sigma
norm = 0.0
sum = 0.0
for i = 0 to windowsize - 1
weight = math.exp(-1 * math.pow(i - m, 2) / (2 * math.pow(s, 2)))
norm := norm + weight
sum := sum + series[windowsize - i - 1] * weight
sum / norm
plot(pine_alma(close, 9, 0.85, 6))
与这个自定义函数相比,内置的 ta.alma() 函数使用起来更简单。此外,如果TradingView在后台对其进行了特别优化,内置函数的执行速度也可能更快。
脚本示例
接下来,我们来看一个完整的脚本是如何使用 ta.alma() 函数的。下面的指标会绘制两条Arnaud Legoux移动平均线(ALMA):一条周期为9,另一条周期为20。
绘制出两条平均线后,我们会对它们进行比较。如果快周期ALMA位于慢周期平均线上方,并且整根K线的价格都高于慢周期平均线,那么我们会将这根K线标记为绿色。反之,如果快周期ALMA位于慢周期平均线下方,并且整根K线的价格都低于慢周期平均线,则将K线标记为红色。
完整的指标代码如下:
//@version=5
indicator(title="Arnaud Legoux Moving Average example", overlay=true)
// 输入选项
averageData = input.source(close, title="Average Data Source")
fastLength = input.int(9, title="Fast Average Length")
fastOffset = input.float(0.7, title="Fast Average Offset", step=0.1)
fastSigma = input.int(3, title="Fast Average Sigma")
slowLength = input.int(20, title="Slow Average Length")
slowOffset = input.float(0.5, title="Slow Average Offset", step=0.1)
slowSigma = input.int(2, title="Slow Average Sigma")
// 计算ALMA
fastAverage = ta.alma(averageData, fastLength, fastOffset, fastSigma)
slowAverage = ta.alma(averageData, slowLength, slowOffset, slowSigma)
// 绘制平均线
plot(fastAverage, color=color.orange, title="Fast ALMA")
plot(slowAverage, color=color.blue, linewidth=2, title="Slow ALMA")
// 根据两条ALMA确定趋势并为K线着色
almaBarColour = if fastAverage > slowAverage and low > slowAverage
#77DD77
else if fastAverage < slowAverage and high < slowAverage
#FE6F5E
else
#DCDCDC
barcolor(almaBarColour)
脚本以 indicator() 函数开始,它负责为脚本命名,并通过 overlay=true 参数将指标叠加到主图表上。
接着,我们创建了七个输入项。第一个是 input.source() 创建的数据源输入,用于指定均线所计算的数据。随后是三个用于配置快周期ALMA的输入项:两个 input.int() 整数输入,分别控制其周期和sigma值;一个 input.float() 浮点数输入,用于设置其偏移量。
最后三个输入项则用于配置慢周期ALMA,同样包括两个整数输入(用于周期和sigma)和一个浮点数输入(用于偏移量)。
接下来,我们计算这两条平均线:
// 计算ALMA
fastAverage = ta.alma(averageData, fastLength, fastOffset, fastSigma)
slowAverage = ta.alma(averageData, slowLength, slowOffset, slowSigma)
第一个 ta.alma() 调用计算的是快周期Arnaud Legoux移动平均线。我们为该函数传入了四个我们之前创建的输入变量作为参数,其默认值分别为:averageData(K线收盘价)、fastLength(9)、fastOffset(0.7)和 fastSigma(3)。
第二个 ta.alma() 调用则计算慢周期ALMA。我们同样为其传入了四个输入变量,其默认值为:averageData、slowLength(20)、slowOffset(0.5)和 slowSigma(2)。
计算出平均值后,脚本便开始执行其他代码。首先使用 plot() 函数绘制两条平均线。快周期均线显示为橙色(color.orange),而慢周期均线则显示为蓝色(color.blue)。我们没有设置绘图类型,因此它们会以默认的常规线型显示。
然后,一个级联 if 语句被用来决定K线的颜色。其首个条件判断快周期ALMA是否大于慢周期ALMA,并且 K线的最低价(low)也高于慢周期均线(这确保了整根K线都位于均线上方)。当条件成立时,我们使用十六进制颜色码 #77DD77(柔和绿)。
如果快周期均线低于慢周期均线,并且 K线的最高价(high)也低于慢周期均线,则选用 #FE6F5E(苦甜红)。若以上条件均不满足,则使用 #DCDCDC(庚斯博罗灰)作为默认颜色。
脚本的最后一行调用了 barcolor() 函数,它将我们最终选定的颜色应用到图表的K线上。
该指标加载到图表上后,会绘制出两条Arnaud Legoux移动平均线(ALMA)。当价格在均线上方形成上升趋势时,K线会变为绿色。而在下跌趋势中,我们会看到红色的K线:
总结
ta.alma() 函数用于计算Arnaud Legoux移动平均线(ALMA)。
该函数最多需要五个参数:用于计算的数据源、均线的周期(K线数)、偏移量(offset)和sigma值,以及一个可选的布尔值,用于指定是否对计算出的偏移量进行向下取整。





