Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calculate exponential moving average in python

I have a range of dates and a measurement on each of those dates. I'd like to calculate an exponential moving average for each of the dates. Does anybody know how to do this?

I'm new to python. It doesn't appear that averages are built into the standard python library, which strikes me as a little odd. Maybe I'm not looking in the right place.

So, given the following code, how could I calculate the moving weighted average of IQ points for calendar dates?

from datetime import date days = [date(2008,1,1), date(2008,1,2), date(2008,1,7)] IQ = [110, 105, 90] 

(there's probably a better way to structure the data, any advice would be appreciated)

like image 529
Jim Avatar asked Jan 28 '09 18:01

Jim


People also ask

How does Python calculate EMA?

The first thing we will do is find the SMA of the first 5 numbers. Let's add 11.05 to our EMA list. Now we will use the EMA formula to calculate the EMA for the 6th number. Continue the process of using the EMA formula for all the numbers in the set and that is how you calculate the EMA of a stock.

What is exponential moving average in Python?

Exponential Moving Averages (EMA) is a type of Moving Averages. It helps users to filter noise and produce a smooth curve. In Moving Averages 2 are very popular. Simple Moving Average just calculates the average value by performing a mean operation on given data but it changes from interval to interval.

How do you calculate exponential moving average?

Finally, the following formula is used to calculate the current EMA: EMA = Closing price x multiplier + EMA (previous day) x (1-multiplier)

How do you calculate moving average in Python?

Method 1: Using Numpy It provides a method called numpy. cumsum() which returns the array of the cumulative sum of elements of the given array. A moving average can be calculated by dividing the cumulative sum of elements by window size.


2 Answers

EDIT: It seems that mov_average_expw() function from scikits.timeseries.lib.moving_funcs submodule from SciKits (add-on toolkits that complement SciPy) better suits the wording of your question.


To calculate an exponential smoothing of your data with a smoothing factor alpha (it is (1 - alpha) in Wikipedia's terms):

>>> alpha = 0.5 >>> assert 0 < alpha <= 1.0 >>> av = sum(alpha**n.days * iq  ...     for n, iq in map(lambda (day, iq), today=max(days): (today-day, iq),  ...         sorted(zip(days, IQ), key=lambda p: p[0], reverse=True))) 95.0 

The above is not pretty, so let's refactor it a bit:

from collections import namedtuple from operator    import itemgetter  def smooth(iq_data, alpha=1, today=None):     """Perform exponential smoothing with factor `alpha`.      Time period is a day.     Each time period the value of `iq` drops `alpha` times.     The most recent data is the most valuable one.     """     assert 0 < alpha <= 1      if alpha == 1: # no smoothing         return sum(map(itemgetter(1), iq_data))      if today is None:         today = max(map(itemgetter(0), iq_data))      return sum(alpha**((today - date).days) * iq for date, iq in iq_data)  IQData = namedtuple("IQData", "date iq")  if __name__ == "__main__":     from datetime import date      days = [date(2008,1,1), date(2008,1,2), date(2008,1,7)]     IQ = [110, 105, 90]     iqdata = list(map(IQData, days, IQ))     print("\n".join(map(str, iqdata)))      print(smooth(iqdata, alpha=0.5)) 

Example:

$ python26 smooth.py IQData(date=datetime.date(2008, 1, 1), iq=110) IQData(date=datetime.date(2008, 1, 2), iq=105) IQData(date=datetime.date(2008, 1, 7), iq=90) 95.0 
like image 149
jfs Avatar answered Sep 28 '22 03:09

jfs


I did a bit of googling and I found the following sample code (http://osdir.com/ml/python.matplotlib.general/2005-04/msg00044.html):

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     """     s = array(s)     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 
like image 43
earino Avatar answered Sep 28 '22 02:09

earino