代码之家  ›  专栏  ›  技术社区  ›  Greggy

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

  •  0
  • Greggy  · 技术社区  · 3 年前

    我正在尝试用Python编程smma(平滑移动平均)。我从传统观点中的一个松木脚本中得到了这个公式。

    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的最终值是不正确的。(在这种情况下,我将其作为source(high+low)/2而不是close,但当我在Tradingview中将其作为source时,它仍然不能正确显示它)

    有人能认出我做错了什么吗?

    谢谢!

    0 回复  |  直到 3 年前
        1
  •  2
  •   adkr    3 年前

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

    问题是,你可以找到各种公式来计算SMMA,例如:
    chartmill.com
    fxcorporate.com

    老实说,到目前为止,我还不能得到确切的TradingView结果,但我发现 chartmill 最接近TradingView的结果。

    我尝试在Java中实现SMMA作为的扩展 ta4j library 。请在下面找到我的最新结果。希望您觉得它很有帮助,我们将一起找到正确的实现:

    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);
    }
    
    }
    
        2
  •  1
  •   VJKR    2 年前

    使用公式在Python中计算SMMA很有挑战性,但有一个简单的替代方案可以使用任何Python TA库(例如 https://technical-analysis-library-in-python.readthedocs.io/en/latest/ta.html )并获得EMA。SMMA本质上是EMA,但长度不同。您可以在tradingview中尝试插入SMMA和EMA,并按照这里的屏幕截图中提到的更改长度。您将观察到SMMA和EMA在这里重叠。

    enter image description here

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

    希望这能有所帮助。

        3
  •  0
  •   Greggy    3 年前

    我找到了解决办法。你只需要计算一个足够大的样本量。在我的情况下,计算周期为5的smma不应该在5个数据点上运行,但在大小为200的情况下我有正确的值。 因此,计算前5个数据点的简单移动平均值,然后开始计算其余195个数据点。smma的最后一个值是与Tradingview中的值匹配的正确值。