python - 计算 smma(平滑移动平均值)

问题描述 投票:0回答:4

我正在尝试用 Python 编写 smma(平滑移动平均线)。我从 tradeview 中的 pine 脚本中获取公式。

smma =  0.0
smma := na(smma[1]) ? ta.sma(src, length) : (smma[1] * (length - 1) + src) / length

因此,当没有先前的 smma 值时,我们应该采用 (src,length) 的简单移动平均值。接下来的计算是根据 (smma[1] * (length - 1) + src) / length 进行的。 smmma[1] 是之前的 smma 值。

这是我的代码:

def smma(src, length):
    smma = 0.0
    dataLength = len(src)
    lookbackPeriod = dataLength - length

    #first value of smma is the sma of src and length
    #Convert list to dataframe
    df = pd.DataFrame(src, columns = ['hl2'])
    smma = df.rolling(window=length).mean()
    smma = float(smma.iloc[-1])
    log.info(f"First smma value = {smma}")

    lookbackPeriod = dataLength - length + 1 #calculate smma for the other values
    while (lookbackPeriod < dataLength):
        smma = (smma * (length - 1) + float(src[lookbackPeriod])) / length
        log.info(f"lookback = {lookbackPeriod} src[lookbackPeriod] = {src[lookbackPeriod]} smma = {smma}")
        lookbackPeriod = lookbackPeriod + 1
    return smma

周期长度为 5 的输出如下所示:

[2021-11-07 12:26:21,701] First smma value = 61842.0
[2021-11-07 12:26:21,701] lookback = 196 src[lookbackPeriod] = 61817.25 smma = 61837.05
[2021-11-07 12:26:21,701] lookback = 197 src[lookbackPeriod] = 61883.5 smma = 61846.340000000004
[2021-11-07 12:26:21,701] lookback = 198 src[lookbackPeriod] = 61867.75 smma = 61850.621999999996
[2021-11-07 12:26:21,702] lookback = 199 src[lookbackPeriod] = 61838.0 smma = 61848.0976
在我的例子中,src 是一个包含 200 个值的列表。 当我将第一个 smma 的值与 sma 进行比较时,与 Tradingview 上的值相比,它是正确的。与我在 Tradingview 上看到的相比,smma 的最终值不正确。 (在这种情况下,我将其作为源(高+低)/2,而不是收盘价,但当我将其作为 Tradingview 中的源时,它仍然无法正确显示)

有人能发现我在这里做错了什么吗?

非常感谢!

python-3.x pine-script moving-average
4个回答
3
投票
使用公式在 Python 中计算 SMMA 具有挑战性,但有一个简单的替代方案,您可以使用任何 python TA 库(例如

https://technical-analysis-library-in-python.readthedocs.io/en/latest/ta .html)并获取 EMA。 SMMA本质上是EMA,只是长度不同。您可以在交易视图中尝试插入 SMMA 和 EMA,并按照此处的 screennip 中所述更改长度。您会发现 SMMA 和 EMA 在这里重叠。

理想情况下,SMMA长度为x,将EMA长度设置为x*2-1(当然长度1除外),你会得到准确的结果。

希望这有帮助。


2
投票
最近我遇到了同样的问题 - 由我的代码计算的 SMMA 值与图表上的 TradingView 值。

问题是你可以找到各种计算 SMMA 的公式,例如:


chartmill.com
fxcorporate.com

老实说,到目前为止我无法获得准确的 TradingView 结果,但我发现

chartmill 结果最接近 TradingView。

我尝试在 Java 中实现 SMMA 作为

ta4j 库的扩展。请在下面找到我最近的结果。希望您发现它有帮助,我们将共同找到正确的实现:

public class SMMAIndicator extends RecursiveCachedIndicator<Num> { /** * N - Number of periods, over which the indicator is calculated. */ private final int barCount; private final Num n; /** * Usually ClosePriceIndicator */ private final Indicator<Num> indicator; /** * SMA to calculate 1st SMMA period per index */ private final SMAIndicator smaIndicator; public SMMAIndicator(Indicator<Num> indicator, int barCount) { super(indicator.getBarSeries()); this.barCount = barCount; this.n = numOf(barCount); this.indicator = indicator; this.smaIndicator = new SMAIndicator(indicator, barCount); } @Override public Num calculate(int index) { var i = max(0, index - barCount + 1); if (i == 0) { return smaIndicator.getValue(index); } if (i == 1) { var nMinus1 = n.minus(numOf(1)); var smma0 = getValue(index - 1); var input = indicator.getValue(index); return smma0.multipliedBy(nMinus1).plus(input).dividedBy(n); } var prevSmma = getValue(index - 1); var prevSum = prevSmma.multipliedBy(n); return prevSum.minus(prevSmma).plus(indicator.getValue(index)).dividedBy(n); } }
    

0
投票
我找到了解决方案。您只需要计算足够大的样本量即可。就我而言,计算 5 个周期的 smma 不应在 5 个数据点上运行,但在大小为 200 的数据点上我有正确的值。 因此,计算前 5 个数据点的简单移动平均值,然后开始剩余 195 个数据点的 smma 计算。 smma 的最后一个值是与 Tradingview 中的值匹配的正确值。


0
投票
此代码适用于我的

def calculate_smma(src, length): smma = pd.Series(index=src.index, dtype=float) for i in range(len(src)): if pd.isna(smma.iloc[i - 1]): smma.iloc[i] = src.iloc[:i + 1].mean() else: smma.iloc[i] = (smma.iloc[i - 1] * (length - 1) + src.iloc[i]) / length return smma
    
© www.soinside.com 2019 - 2024. All rights reserved.