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][1] + someData[i-1][1] + someData[i+1][1])/3.0;
moveMean.push([i,mean]);
}
Source: stackoverflow.com
Related Query
- HTML5/JS Chart with Moving Average
- Sync an html5 video with an highchart.js line chart
- Html5 line chart with a different color when out of area range
- Moving Average Line in Highcharts Scattered Chart
- Highcharts cloud issue with data source when duplicating chart
- Reload chart data via JSON with Highcharts
- Highcharts - how to have a chart with dynamic height?
- dealing with highcharts bar chart with really long category names
- JavaScript - Export Div with SVG chart + HTML as and Image
- How to save an image of the chart on the server with highcharts?
- Highcharts scatter chart with a name per point
- Highcharts / jQuery - destroy and rebuild chart with original options
- How to show a column with the value Zero in Column chart in Highcharts?
- How to create a new Highstock chart with new Highchart and not jquery?
- Highchart Area Range chart with gradient that follows the line
- how to implement moving average in highchart
- Dealing with pie chart label overlap [Highcharts]
- Highcharts : Chart with drilldown how to obtain click event of drill up button
- Highcharts export chart exportSettings with svg file
- Highcharts - best way to handle and display zero (or negative) values in a line chart series with logarithmic Y axis
- Highcharts chart with 'datetime' xAxis - use categories on drilldown
- Highcharts Column chart with drilldown, remove hyperlink like formatting from x-axis labels
- Symbol-outline with pie chart -or- custom legend symbols
- Highcharts: Updating a Pie Chart with setData()
- exporting highcharts polar chart to PDF with phantomjs
- knockoutJS dynamic chart with high charts
- HTML5 Chart library that supports pinch zooming
- Chart rendering issue with resizing <div> container
- Create Density Heatmap Chart using Jquery with array of data
- Highcharts - Scatter chart with a line connecting the dots in the series
More Query from same tag
- How can you add flags to points on a graph
- Change the zoom level for highmaps
- Highcharts backgroundColor for multiple charts is only applied to one chart
- How to include strings in series data to pull for tooltip point formatting?
- Highcharts different x-axis values
- Highchart stacked area empty spaces (negative values)
- Number of legends per page on pagination in Highcharts
- Accessing the response text for JSONP. Flattening multiple objects to text
- How we can format the box size of timeline highchart
- Highchart show results without comma for individual line
- Highcharts small size div not showing minorTickInterval
- How can i get pie chart with dynamic json data in Angular js
- How to draw single line graph using Highchart bullet graph?
- HighChart Pie Dynamic JSON in Codeigniter
- no data module with multiple series in highcharts.js
- Highstock chart not rendered when using load event
- Find special chart on highcharts
- R Highcharter: Select category from a single point
- Drilldown in Map with Vue.js
- Preprocessing of dynamically added series in HighCharts
- Unbind the Click Action on xAxis Labels In Drilldown
- Dotnet highchart visible attribute
- How to add fill color in highcharts data series
- hierarchy information while using grouped category plugin in highchart
- highcharts mapbubble display 3 times
- Set HighChart yAxis's min max to a specific series only
- Add highcharts plotband after render in R shiny/rcharts
- Set distance between labels and chart in Highcharts
- Wanted to plot only one spline at the chart load and further add other splines after loading
- Highcharts legend labels go outside canvas