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)
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.
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.
Finally, the following formula is used to calculate the current EMA: EMA = Closing price x multiplier + EMA (previous day) x (1-multiplier)
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With