Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Exponential Moving Average without For Loop

576 views
Skip to first unread message

happydude

unread,
Nov 17, 2009, 4:08:19 PM11/17/09
to
Hello, I am trying to find the rolling 30 day EMA for a time series without using a for loop (I have a lot of data).

As an example/test this is something like what I want (below) but I'm finding that my end result is not really close to how it should look. When I put it together in Excel or with a for loop it comes out correctly but I am in the dark if I this is using filter correctly below.

Can anyone help?

todaysClose = cumsum(randn(100,1));
daysBack = 30;
alpha = 2 / (daysBack + 1); %calculate smoothing factor "alpha"

%prepare a coefficient for the filter function
coefficient = repmat(alpha,1,daysBack).^(1:daysBack);
coefficient = coefficient/sum(coefficient);

EMA = filter(coefficient, 1, todaysClose);


P.S. this was one of the posts I looked up http://groups.google.com/group/comp.soft-sys.matlab/tree/browse_frm/thread/7b5c0b3146432dd9/58e9d04b885a576a?rnum=11&_done=/group/comp.soft-sys.matlab/browse_frm/thread/7b5c0b3146432dd9/48bdf7f81cd8f197%3Ftvc%3D1%26#doc_a1c5b8de7a7c428a

this is also where I got the above filter code
http://groups.google.com/group/comp.soft-sys.matlab/browse_thread/thread/1d8d10d5b835550d?tvc=2&q=exponential+moving+average+filter

Matthew Whitaker

unread,
Nov 17, 2009, 5:49:01 PM11/17/09
to
try this code:

todaysClose = cumsum(randn(100,1));
daysBack = 30;
alpha = 2 / (daysBack + 1); %calculate smoothing factor "alpha"
coefficient = repmat(1-alpha,1,daysBack).^(1:daysBack); %note 1-alpha
EMA = filter(coefficient, sum(coefficient), todaysClose);
plot(todaysClose)
hold on
plot(EMA,'r')

Hope this helps
Matt W


"happydude " <anony...@hotmail.com> wrote in message <hdv3c3$5um$1...@fred.mathworks.com>...

happydude

unread,
Nov 18, 2009, 4:20:25 PM11/18/09
to
thanks for this. Seems quite close but still can be quite different from the traditional EMA as used in finance.

from a limited number of simulations it seems to be quite different from the EMA for about 60 datapoints or so ...

any ideas why this might happen?

nb - the traditional EMA uses an SMA as an initial value because the EMA formula calls for an initial EMA value.. how does the Filter function get around this?

Matthew Whitaker

unread,
Nov 18, 2009, 7:15:17 PM11/18/09
to
"happydude " <anony...@hotmail.com> wrote in message <he1oep$fs6$1...@fred.mathworks.com>...

The answer is that filter does not get around it.
For the first 30 points the filter will go off the leading edge of the todaysClose vector. Those 'values' past the edge are set to 0. This will distort at least the first 30 points of your EMA.
You can see the effect by having a constant close price.

todaysClose = ones(100,1)*100;


daysBack = 30;
alpha = 2 / (daysBack + 1); %calculate smoothing factor "alpha"
coefficient = repmat(1-alpha,1,daysBack).^(1:daysBack); %note 1-alpha
EMA = filter(coefficient, sum(coefficient), todaysClose);
plot(todaysClose)
hold on
plot(EMA,'r')

You could pad the leading edge of the array by replicating the first value out daysBack values and then strip it off. That might help.
So:


todaysClose = cumsum(randn(100,1));
daysBack = 30;

pad = repmat(todaysClose(1),daysBack,1);
todaysClose = [pad;todaysClose];


alpha = 2 / (daysBack + 1); %calculate smoothing factor "alpha"
coefficient = repmat(1-alpha,1,daysBack).^(1:daysBack); %note 1-alpha
EMA = filter(coefficient, sum(coefficient), todaysClose);

EMA = EMA(31:end); %remove the pad
plot(todaysClose(31:end))

happydude

unread,
Nov 19, 2009, 9:31:18 AM11/19/09
to
thanks i'll give it a shot :)

Bwana

unread,
Jul 12, 2010, 3:10:27 PM7/12/10
to
"happydude " <anony...@hotmail.com> wrote in message <he3krm$glm$1...@fred.mathworks.com>...

> thanks i'll give it a shot :)

all built in: http://www.mathworks.com/access/helpdesk/help/toolbox/finance/tsmovavg.html

david

unread,
Mar 14, 2011, 11:50:08 AM3/14/11
to
"Bwana " <bwana....@gmail.com> wrote in message <i1fpb3$noh$1...@fred.mathworks.com>...

> "happydude " <anony...@hotmail.com> wrote in message <he3krm$glm$1...@fred.mathworks.com>...
> > thanks i'll give it a shot :)
>
> all built in: http://www.mathworks.com/access/helpdesk/help/toolbox/finance/tsmovavg.html

Anyone know why the filter function described above gives a different output to that of the built in movavg function?

TideMan

unread,
Mar 14, 2011, 2:59:44 PM3/14/11
to
On Mar 15, 4:50 am, "david " <davidtr...@gmail.com> wrote:
> "Bwana " <bwana.muku...@gmail.com> wrote in message <i1fpb3$no...@fred.mathworks.com>...
> > "happydude " <anonymou...@hotmail.com> wrote in message <he3krm$gl...@fred.mathworks.com>...

> > > thanks i'll give it a shot :)
>
> > all built in:http://www.mathworks.com/access/helpdesk/help/toolbox/finance/tsmovav...

>
> Anyone know why the filter function described above gives a different output to that of the built in movavg function?

My guess is that it's because you've screwed up.
But you haven't shown us your code, so how could we know?

Stefano Sampietro

unread,
Apr 13, 2015, 11:25:45 AM4/13/15
to
Hello, the second parameter of the filter function should be (1/alpha-1) instead of sum(coefficient) maybe? If you expand the recursive formula of the EMA, you will find that term.

P.S. (1/alpha-1) is the value to which the sum of "coefficient" converges... why using an approxim value instead of the right one? Or am I missing something?

thx

"Matthew Whitaker" <mattlw...@REMOVEgmail.com> wrote in message <hdv98t$dcd$1...@fred.mathworks.com>...

Maria Puy Arrastia

unread,
Jun 15, 2016, 4:01:08 PM6/15/16
to
"happydude" wrote in message <hdv3c3$5um$1...@fred.mathworks.com>...
Notice that the coefficients for past data are not right. The formula is:
Price(t)*alpha+Price(t-1)*alpha*(1-alpha)+Price(t-2)*alpha*(1-alpha)^2+.......+Price(t-daysBack)*(1-alpha)^daysBack

I would use:

coefficient=[1 repmat((1-k),1,N).^(1:N)].*[repmat(k,1,N) 1];
0 new messages