4

I'm using simple moving average in Math.Net, but now that I also need to calculate EMA (exponential moving average) or any kind of weighted moving average, I don't find it in the library.

I looked over all methods under MathNet.Numerics.Statistics and beyond, but didn't find anything similar.

Is it missing in library or I need to reference some additional package?

Alex Michel
  • 416
  • 3
  • 13

3 Answers3

4

I don't see any EMA in MathNet.Numerics, however it's trivial to program. The routine below is based on the definition at Investopedia.

public double[] EMA(double[] x, int N)
{
    // x is the input series            
    // N is the notional age of the data used
    // k is the smoothing constant

    double k = 2.0 / (N + 1);
    double[] y = new double[x.Length];
    y[0] = x[0];
    for (int i = 1; i < x.Length; i++) y[i] = k * x[i] + (1 - k) * y[i - 1];

    return y;
}
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
phv3773
  • 487
  • 4
  • 10
3

Occasionally I found this package: https://daveskender.github.io/Stock.Indicators/docs/INDICATORS.html It targets to the latest .NET framework and has very detailed documents.

Mason Zhang
  • 3,423
  • 24
  • 35
0

Try this:

public IEnumerable<double> EMA(IEnumerable<double> items, int notationalAge)
{
    double k = 2.0d / (notationalAge + 1), prev = 0.0d;

    var e = items.GetEnumerator();
    if (!e.MoveNext()) yield break;

    yield return prev = e.Current;    
    while(e.MoveNext())
    {
        yield return prev = (k * e.Current) + (1 - k) * prev;
    }
}

It will still work with arrays, but also List, Queue, Stack, IReadOnlyCollection, etc.

Although it's not explicitly stated I also get the sense this is working with money, in which case it really ought to use decimal instead of double.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794