I've created a MovingAverage
class, but it is not optimized for performance at all. I care about performance a little bit because I'm using this class in trading (I collocate on exchange and so on and so on; let's talk about performance of this particular class).
How would you improve it for better performance?
interface Indicator
{
double? Value { get; }
}
public class Candle
{
public Candle(double value)
{
Minimum = value;
Maximum = value;
}
public void ValueUpdated(double value)
{
if (value < Minimum)
{
Minimum = value;
}
if (value > Maximum)
{
Maximum = value;
}
}
public double Maximum { get; private set; }
public double Minimum { get; private set; }
public double Median
{
get { return (Maximum + Minimum) / 2; }
}
}
public class MovingAverage : Indicator
{
private int _length;
public Queue<Candle> _candles;
private Candle _newestCandle;
private double _sumExceptNewest;
/**
* only median supported now
*/
public MovingAverage(int length)
{
_length = length;
_candles = new Queue<Candle>(length);
}
public void Add(double val)
{
if (_candles.Count == _length)
{
_sumExceptNewest -= _candles.Dequeue().Median;
}
if (_candles.Count > 0)
{
_sumExceptNewest += _newestCandle.Median;
}
// TODO: avoid new
_newestCandle = new Candle(val);
_candles.Enqueue(_newestCandle);
RecalculateValue();
}
public void Modify(double val)
{
if (_newestCandle == null)
{
Add(val);
}
else
{
_newestCandle.ValueUpdated(val);
RecalculateValue();
}
}
private void RecalculateValue()
{
Value = (_sumExceptNewest + _newestCandle.Median)/_candles.Count;
}
public double? Value { get; private set; }
public void CheckValueAndPrintDelta()
{
double result = 0;
foreach (var candle in _candles)
{
result += candle.Median;
}
result /= _candles.Count;
Console.WriteLine("checked MA Value = " + Value + " Should be = " + result +
" delta (1 = 100%) = " + (Value - result) / result);
}
}