score:0

the code is not mine but it works very well for moving averages in financial calculations.

``````var movingaverage = function(d, t, roundup) {
if (d.length >= t && d.constructor === array) {
var r = [], s = 0, f = this.decimalroundingfactor, ma;

roundup = typeof roundup === undefined? true : roundup;

for(var i=0;i<d.length;++i) {
s += isnan(d[i])? 0: d[i];
if (i < t-1) {
r.push(nan);
} else if (i+1 === t) {
ma = roundup? math.round((s/t)*f)/f: s/t;
r.push(ma);
} else {
s -= isnan(d[i-t])? 0: d[i-t];
ma = roundup? math.round((s/t)*f)/f: s/t;
r.push(ma);
}
}

return r;
} else {
throw "[error] technicalanalysis#movingaverage: not enought data! or data is not array!";
}
};
``````

score:0

this might be a bit old by now, but maybe this will help someone.

``````function sma(tindex, n, array) {
// return undefined if array is falsy, if range lookback or n exceeds array length
if (!array || (tindex - n) < 0 || n > array.length) return;
const range = array.slice((tindex - n), tindex);
const sum = range.reduce((acc, num) => acc += num, 0);
return (sum / n);
}
``````

where: tindex = "current price index", n = "lookback range", array = "dataset"

score:1

i came across the same issue. here is my example for your reference. you can set any length of sample point as you want.

``````var getaverage = function(arr, n){
var sum=0;
if(n>arr.length){
n = arr.length;
}

for(var ii=arr.length-n; ii<arr.length; ii++){
sum += arr[ii];
}
return sum/n;
}

function(acceleration, 3);``````

score:2

a more general and simple function would be this one:

``````function movingavg(array, countbefore, countafter) {
if (countafter == undefined) countafter = 0;
const result = [];
for (let i = 0; i < array.length; i++) {
const subarr = array.slice(math.max(i - countbefore, 0), math.min(i + countafter + 1, array.length));
const avg = subarr.reduce((a, b) => a + (isnan(b) ? 0 : b), 0) / subarr.length;
result.push(avg);
}
return result;
}

const myarr = [1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9];

//averages of 7 (i.e. 7 day moving average):
const avg7before = movingavg(myarr, 6); //6 before and the current
const avg7middle = movingavg(myarr, 3, 3); //3 before, 3 after, plus the current
const avg7after = movingavg(myarr, 0, 6); //6 after plus the current

console.log('original:',...myarr.map(x => x.tofixed(1)));
console.log('7 before:',...avg7before.map(x => x.tofixed(1)));
console.log('7 middle:',...avg7middle.map(x => x.tofixed(1)));
console.log('7 after: ',...avg7after.map(x => x.tofixed(1)));``````

score:12

i wrote a more general purpose function below.

to use it, simply pass an array of values, the count (or length) of the moving average, and an optional qualifier function.

for example:

`movingavg(arr, 10)` will return a 10 data point moving average of the values in the array `arr`.

`movingavg(arr, 20, function(val){ return val != 0; })` will return a 20 data point moving average of the non-zero values in the array `arr`

so with chart.js, for example, you can use it like so:

``````...
,datasets: [
{
label: "values"
,data: values
}
,{
type: "line"
,label: "20 point moving average"
,data: movingavg(values, 20, function(val){ return val != 0; })
}
]
...
``````

the function:

``````    /**
* returns an array with moving average of the input array
* @param array - the input array
* @param count - the number of elements to include in the moving average calculation
* @param qualifier - an optional function that will be called on each
*  value to determine whether it should be used
*/
function movingavg(array, count, qualifier){

// calculate average for subarray
var avg = function(array, qualifier){

var sum = 0, count = 0, val;
for (var i in array){
val = array[i];
if (!qualifier || qualifier(val)){
sum += val;
count++;
}
}

return sum / count;
};

var result = [], val;

// pad beginning of result with null values
for (var i=0; i < count-1; i++)
result.push(null);

// calculate average for each subarray and add to result
for (var i=0, len=array.length - count; i <= len; i++){

val = avg(array.slice(i, i + count), qualifier);
if (isnan(val))
result.push(null);
else
result.push(val);
}

return result;
}
``````

score:18

here's a quick example which calculates a 3-point moving average client side and plots it with highcharts:

``````var n = 100;
var somedata = [];
for (var i = 0; i < n; i++)
{
somedata.push([i,math.random() * 100]);
}

var movemean = [];
for (var i = 1; i < n-1; i++)
{
var mean = (somedata[i] + somedata[i-1] + somedata[i+1])/3.0;
movemean.push([i,mean]);
}
`````` 