javascript 带移动平均线的 HTML5/JS 图表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19981713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 17:27:05  来源:igfitidea点击:

HTML5/JS Chart with Moving Average

javascriptjqueryhtmlchartshighcharts

提问by Nyxynyx

Question:How can a moving average line be calculated and plotted on a JS/HTML5 chart?

问题:如何在 JS/HTML5 图表上计算和绘制移动平均线?

The closest example I can find is this website. Looking at its JS files, I cannot identify the plotting chart library. Upon closer inspection, it appears that the moving average was not calculated on the serverside but not the clientside.

我能找到的最接近的例子是这个网站。查看其 JS 文件,我无法识别绘图图表库。仔细检查后,似乎移动平均线不是在服务器端计算的,而是在客户端计算的。

Any suggestions appreciated!

任何建议表示赞赏!

enter image description here

在此处输入图片说明

回答by Mark

Here's a quick examplewhich calculates a 3-point moving average client side and plots it with Highcharts:

这是一个计算 3 点移动平均线客户端并用 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]);
}

enter image description here

在此处输入图片说明

回答by isapir

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, 10)将返回数组中值的 10 个数据点移动平均值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

movingAvg(arr, 20, function(val){ return val != 0; })将返回数组中非零值的 20 个数据点移动平均值 arr

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

例如,对于 Chart.js,您可以像这样使用它:

...
,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;
    }

回答by BerlinaLi

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);

回答by Victor Velchev

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!";
    }
};