1

I came across a useful snippet from thread. The post is over a decade old and there hasn't been much discussion. Yet it continues to garner substantial views - it will no doubt be useful for future readers.

def ema(s, n):
    """
    returns an n period exponential moving average for
    the time series s

    s is a list ordered from oldest (index 0) to most
    recent (index -1)
    n is an integer

    returns a numeric array of the exponential
    moving average
    """
    ema = []
    j = 1

    #get n sma first and calculate the next n period ema
    sma = sum(s[:n]) / n
    multiplier = 2 / float(1 + n)
    ema.append(sma)

    #EMA(current) = ( (Price(current) - EMA(prev) ) x Multiplier) + EMA(prev)
    ema.append(( (s[n] - sma) * multiplier) + sma)

    #now calculate the rest of the values
    for i in s[n+1:]:
        tmp = ( (i - ema[j]) * multiplier) + ema[j]
        j = j + 1
        ema.append(tmp)

    return ema

The issue is EMA values are actually SMA figures being appended. How should we proceed to fix the function?

1 Answers1

1

Use a temporary array for ema calculations and and different one for returning,

def ema(s, n):
    """
    returns an n period exponential moving average for
    the time series s

    s is a list ordered from oldest (index 0) to most
    recent (index -1)
    n is an integer

    returns a numeric array of the exponential
    moving average
    """
    ema1 = []
    ema2 = []
    j = 1

    #get n sma first and calculate the next n period ema
    sma = sum(s[:n]) / n
    multiplier = 2 / float(1 + n)
    ema1.append(sma)

    #EMA(current) = ( (Price(current) - EMA(prev) ) x Multiplier) + EMA(prev)
    ema1.append(( (s[n] - sma) * multiplier) + sma)
    ema2.append(( (s[n] - sma) * multiplier) + sma)
    #now calculate the rest of the values
    for i in s[n+1:]:
        tmp = ( (i - ema1[j]) * multiplier) + ema1[j]
        j = j + 1
        ema1.append(tmp)
        ema2.append(tmp)

    return ema2
Roshin Raphel
  • 2,612
  • 4
  • 22
  • 40
  • Hi, thanks for your reply. I get a "'function' object has no attribute 'append' when running the code. Also ema1 =[ ] is repeated twice...should that be correct? I have also identified an error with the original code... s=array(s) should be removed for Python 3. I'll update my post to reflect the change – MischievousBear Jun 15 '20 at 12:24
  • 1
    This function will be correct if the s = array(s) is removed. Please accept the change. – MischievousBear Jun 15 '20 at 12:40