Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate Exponential Moving Average on a Queue in C#

Tags:

c#

average

I have a simple class for calculating the moving average of values I add to it. I use it like this:

MovingAverage ma = new MovingAverage();
ma.push(value1);
ma.push(value2);
... 
Console.Writeline(average.Average);

//the class
public class MovingAverage
{
    public int Period = 5;
    private Queue<double> Quotes = new Queue<double>();

    public void Push(double quote)
    {
        if (Quotes.Count == Period)
            Quotes.Dequeue();
        Quotes.Enqueue(quote);

    }
    public void Clear()
    {
        Quotes.Clear();
    }
    public double Average { get { if (Quotes.Count == 0) return 0; return Quotes.Average(); } }
    public double ExponentialMovingAverage
    {
        get
        {
            ???
        }
    }
}

I would like to extend this class to also return the ExponentialMovingAverage. How would you write return the Exponential Average of the Queued items in Quotes?

I realize you will need to add an Alpha property to the class but I'm not sure how to complete the math for the calculation.

like image 772
Joshua Avatar asked Dec 09 '11 18:12

Joshua


People also ask

How do you calculate Exponential Moving Average?

Finally, the following formula is used to calculate the current EMA: EMA = Closing price x multiplier + EMA (previous day) x (1-multiplier)

How do you use a 20 EMA indicator?

A common trading strategy utilizing EMAs is to trade based on the position of a shorter-term EMA in relation to a longer-term EMA. For example, traders are bullish when the 20 EMA crosses above the 50 EMA or remains above the 50 EMA, and only turn bearish if the 20 EMA falls below the 50 EMA.

Why is 200 EMA important?

The 200-day moving average is represented as a line on charts and represents the average price over the past 200 days (or 40 weeks). The moving average can give traders a sense regarding whether the trend is up or down, while also identifying potential support or resistance areas.

What is Exponential Moving Average in deep learning?

Exponential Moving Average (EMA) is similar to Simple Moving Average (SMA), measuring trend direction over a period of time. However, whereas SMA simply calculates an average of price data, EMA applies more weight to data that is more current.


3 Answers

How about with LINQ:

return Quotes.DefaultIfEmpty()
             .Aggregate((ema, nextQuote) => alpha * nextQuote + (1 - alpha) * ema);

I would point out that for real-time financial data, this is highly inefficient. A much better way would be to cache the previous EMA value and update it on a new quote with the above (constant-time) recurrence-formula.

like image 162
Ani Avatar answered Sep 19 '22 04:09

Ani


Do do not need a queue for an Exponential Moving Average because you only need to keep track of the previous EMA.

public class ExponentialMovingAverageIndicator
{
    private bool _isInitialized;
    private readonly int _lookback;
    private readonly double _weightingMultiplier;
    private double _previousAverage;

    public double Average { get; private set; }
    public double Slope { get; private set; }

    public ExponentialMovingAverageIndicator(int lookback)
    {
        _lookback = lookback;
        _weightingMultiplier = 2.0/(lookback + 1);
    }

    public void AddDataPoint(double dataPoint)
    {
        if (!_isInitialized)
        {
            Average = dataPoint;
            Slope = 0;
            _previousAverage = Average;
            _isInitialized = true;
            return;
        }

        Average = ((dataPoint - _previousAverage)*_weightingMultiplier) + _previousAverage;
        Slope = Average - _previousAverage;

        //update previous average
        _previousAverage = Average;
    }
}
like image 26
Matt Avatar answered Sep 19 '22 04:09

Matt


Here's a minimal version of @MattWolf's answer with a slightly different API, and using C# 7.

public sealed class FloatExponentialMovingAverageCalculator
{
    private readonly float _alpha;
    private float _lastAverage = float.NaN;

    public FloatExponentialMovingAverageCalculator(int lookBack) => _alpha = 2f / (lookBack + 1);

    public float NextValue(float value) => _lastAverage = float.IsNaN(_lastAverage)
        ? value
        : (value - _lastAverage)*_alpha + _lastAverage;
}
like image 31
Drew Noakes Avatar answered Sep 22 '22 04:09

Drew Noakes