ExponentialMovingAverage.cs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. // N-day EMA implementation from Mirror with a few changes (struct etc.)
  2. // it calculates an exponential moving average roughly equivalent to the last n observations
  3. // https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
  4. using System;
  5. namespace Mirror
  6. {
  7. public struct ExponentialMovingAverage
  8. {
  9. readonly float alpha;
  10. bool initialized;
  11. public double Value;
  12. public double Variance;
  13. [Obsolete("Var was renamed to Variance")] // 2022-06-17
  14. public double Var => Variance;
  15. public double StandardDeviation; // absolute value, see test
  16. public ExponentialMovingAverage(int n)
  17. {
  18. // standard N-day EMA alpha calculation
  19. alpha = 2.0f / (n + 1);
  20. initialized = false;
  21. Value = 0;
  22. Variance = 0;
  23. StandardDeviation = 0;
  24. }
  25. public void Add(double newValue)
  26. {
  27. // simple algorithm for EMA described here:
  28. // https://en.wikipedia.org/wiki/Moving_average#Exponentially_weighted_moving_variance_and_standard_deviation
  29. if (initialized)
  30. {
  31. double delta = newValue - Value;
  32. Value += alpha * delta;
  33. Variance = (1 - alpha) * (Variance + alpha * delta * delta);
  34. StandardDeviation = Math.Sqrt(Variance);
  35. }
  36. else
  37. {
  38. Value = newValue;
  39. initialized = true;
  40. }
  41. }
  42. }
  43. }