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

时间:2019-02-01 03:31:31

标签: 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");
        }
    }

2 个答案:

答案 0 :(得分:1)

您的代码是一团糟,让我们从问题入手

  

我只是迷路了,似乎不知道该怎么做才能计算出   简单的移动平均线?

给出

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

如何修复其余代码?我真的不知道,但至少是一个开始

答案 1 :(得分:0)

首先是移动平均线

  

简单移动平均值是通过仅对流中最后的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;
}

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