繁体   English   中英

如何在 C# 中计算简单移动平均线?

[英]How to calculate Simple Moving Average in C#?

我只是丢失,似乎不知道做计算简单移动平均线是什么?

这是文件中用于计算简单移动平均线的方法之一。

        public async Task<decimal?> UpdateAsync(decimal? value, CancellationToken cancelToken)
        {
            await Task.Run(() =>
            {
                var av = default(decimal?);

                if (_av.Count - 1 >= _p)
                {

                }
                else
                {
                    av = value;
                }

                _av.Add(av);

                return av;
            }, cancelToken).ConfigureAwait(false);

            throw new Exception("major issue");
        }
    }

让我们从问题开始:

我只是丢失,似乎不知道做计算简单移动平均线是什么?

给定的

public static class Extensions
{
   public static IEnumerable<decimal> MovingAvg(this IEnumerable<decimal> source, int period)
   {
      var buffer = new Queue<decimal>();

      foreach (var value in source)
      {
         buffer.Enqueue(value);

         // sume the buffer for the average at any given time
         yield return buffer.Sum() / buffer.Count;

         // Dequeue when needed 
         if (buffer.Count == period)
            buffer.Dequeue();
      }
   }
}

用法

static  void Main(string[] args)
{
   var input = new decimal[] { 1, 2, 2, 4, 5, 6, 6, 6, 9, 10, 11, 12, 13, 14, 15 };
   var result = input.MovingAvg(2);
   Console.WriteLine(string.Join(", ",result));
}

输出

1, 1.5, 2, 3, 4.5, 5.5, 6, 6, 7.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5

那么首先什么是移动平均线

简单移动平均是一种通过仅对流中的最后 P 个数字求平均值来计算数字流平均值的方法,其中 P 称为周期。

接下来是我想象中要实现的移动平均线的代码。 可以使用LINQ但是在我们添加一个数字之后的每一步,我都希望更新我的平均值。

我的代码被大量评论,所以请阅读评论。

public class MovingAverageCalculator {

    /// <summary>
    /// Maximum number of numbers this moving average calculator can hold.
    /// </summary>
    private readonly int maxElementCount;

    /// <summary>
    /// Numbers which will be used for calculating moving average.
    /// </summary>
    private readonly int[] currentElements;

    /// <summary>
    /// At which index the next number will be added.
    /// </summary>
    private int currentIndex;

    /// <summary>
    /// How many elements are there currently in this moving average calculator.
    /// </summary>
    private int currentElementCount;

    /// <summary>
    /// Current total of all the numbers that are being managed by this moving average calculator
    /// </summary>
    private double currentTotal;

    /// <summary>
    /// Current Average of all the numbers.
    /// </summary>
    private double currentAvg;

    /// <summary>
    /// An object which can calcauclate moving average of given numbers.
    /// </summary>
    /// <param name="period">Maximum number elements</param>
    public MovingAverageCalculator(int period) {
        maxElementCount = period;
        currentElements = new int[maxElementCount];
        currentIndex = 0;
        currentTotal = 0;
        currentAvg = 0;
    }

    /// <summary>
    /// Adds an item to the moving average series then updates the average.
    /// </summary>
    /// <param name="number">Number to add.</param>
    public void AddElement(int number){
        // You can only have at most maximum elements in your moving average series.
        currentElementCount = Math.Min(++currentElementCount, maxElementCount);
        // IF your current index reached the maximum allowable number then you must reset
        if (currentIndex == maxElementCount){
            currentIndex = 0;
        }
        // Copy the current index number to the local variable
        var temp = currentElements[currentIndex];
        // Substract the value from the current total because it will be replaced by the added number.
        currentTotal -= temp;
        // Add the number to the current index
        currentElements[currentIndex] = number;
        // Increase the total by the added number.
        currentTotal += number;
        // Increase index
        currentIndex++;
        // Calculate average
        currentAvg = (double)currentTotal / currentElementCount;
    }

    /// <summary>
    /// Gets the current average
    /// </summary>
    /// <returns>Average</returns>
    public double GetAverage() => currentAvg;
}

最后,我检查了你的代码,但对我来说没有意义

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM