# Rolling Mean/SD function, for log Returns, looping code

Hi,

I take the MA & StDev functions in AB for granted.
So I thought it would be a good exercise to try and code it using looping code in afl, (well that’s why it’s there )

Unfortunately, I am having difficulties.
The afl code below is based on
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap08/mov-avg.html
( I googled moving average/SD in C/C++ – various code made no sense to me.)

I would be grateful if someone could correct my code below for rolling mean, and hence/otherwise adapt it for a rolling SD, both on log Returns. I’m sure it’s very simple.

many thanks,
Amarjit

``````
// Based on

//===============================
window = 20;

// function rolling SD's of RETURNS
// --------------------------------

function ALMA(C, window)
{

// set logRets to Null's
w = Null;

// logRets
for(i = 1; i < Barcount; i++)
{

w[i] = ln(C[i]/C[i-1]);

}

// set output and intermim vectors to Null's
outalma = Null;

// loop through data
for(i = 1; i < BarCount - Window + 1; i++)
{

a1Sum = 0;

if(i < Window)
{
outalma[i] = Null;
}

else

{

// ROLLING MEAN
for(j = i; j < i + Window - 1  ; j++)
{
alSum = a1Sum + w[j];
}

outalma[i] = alSum/Window;

}

}

return outalma;

}

ac_alma = ALMA(C, window);

//===============================
// Explore

logRet  = ln( C / Ref(C, -1) );

Filter = 1;
AddColumn(MA( logRet , window ),  "tjMA", 1.6);
AddColumn(StDev( logRet , window ),  "tjStDev", 1.6);

``````

Your primary error is that your secondary loop (the one that uses j as the loop counter) is moving forward through the data, not back. For example, if today was April 15 and the window size was 10, you should be finding the average of the bars from approximately April 2-15 (assuming some weekends in there). Instead, you are finding the average of the bars from April 15-28.

I did not fix this error and run your code to see if that resolves all issues. I assume you’re doing this just to learn how to write loops, so continuing to debug your own work will be a good exercise. • Matt

Hi,

Here’s A solution.
Unfortunately there’s a “fudge” to output the SD result.
If anyone has a more elegant method I’d be interested.

There’s a way to return multiple values, rather than parameters list
http://www.amibroker.com/kb/2014/09/21/a-function-with-multiple-return-values/

My background is in FORTRAN.

``````

// Based on

//===============================
// function muSig for rolling MEAN's & SD's of LOG RETURNS
// -------------------------------------------------------

// Set parameters
window = Param("window", 10, 2, 1000, 1);
muOrSig = ParamList( "mu Or Sig:", "mu|Sig" );

price = C;

function muSig(price, window)
{

// set logRets to Null's
w = Null;

// logRets
for(i = 1; i < Barcount; i++)
{
w[i] = ln( price[i] / price[i-1] );
}

// set outputs to Null's
res0 = Null;
res2 = Null;

// loop through the Data
for(i = 1; i < BarCount; i++)
{

// set leading output data to Null's
if(i < window)
{

res0[i] = Null;
res2[i] = Null;

}

else

{

// initialize counters to zero
alSum = 0;
res1 = 0;

// ROLLING MEAN
for(j = 0; j < window; j++)
{

// sum logRets over the window
alSum += w[i - window + j + 1];

}

// mean is res0
res0[i] = alSum/window;

// ROLLING SD POPULATION
for(j = 0; j < window; j++)
{

// sum squared deviations from mean over the window
res1 += ( w[i - window + j + 1] - res0[i] ) ^ 2;

}

// sd population is res2
res2[i] = sqrt(res1/window);

res2[window] = Null;

}

}

// choose/swap res0 for MA and
//             res2 for SD

if ( muOrSig == "mu" )
{
return1 = res0;
}

if ( muOrSig == "Sig" )
{
return1 = res2;
}

return return1;

}

// set function ready for explore
ac_muSig = muSig(C, window);

//===============================
// Explore

logRet  = ln( C / Ref(C, -1) );

Filter = 1;