HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Computing average market spread in C#

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
marketspreadaveragecomputing

Problem

My task is to compute average half spread in percentages on a stream of market. This is part of the coding assignment that I have received.

namespace CodingAssignment
{
    public interface IMarketDataFeed
    {
        string StockName { get; }
        event Action Update;
    }

    public interface IIndicator
    {
        event Action IndicatorUpdate;
    }

    /// 
    /// Computes the average half spread (ie bid to mid) in percentage on a stream of market data updates
    /// 

    public class AverageHalfSpreadIndicator
    {
        private List _lastUpdates;

        public AverageHalfSpreadIndicator(IMarketDataFeed marketDataFeed)
        {          
            marketDataFeed.Update += OnMarketDataUpdate;
        }

        private void OnMarketDataUpdate(MarketDataUpdate updates)
        {
            _lastUpdates.Add(updates);           
            if (_lastUpdates.Count == 20)           
            {               
                _lastUpdates.RemoveAt(0);           
            }

            var start = DateTime.Now;           
            var spreads = _lastUpdates.Select(x => 100 * (x.Mid - x.Bid) / x.Bid);           
            Console.WriteLine("Time to compute spreads: "+(DateTime.Now - start).TotalMilliseconds+" ms");   

            var averageSpread = spreads.Average();           
            Console.WriteLine("Total time:" + (DateTime.Now - start).TotalMilliseconds + " ms");

            IndicatorUpdate(averageSpread);
        }

        public event Action IndicatorUpdate;
    }

    public class MarketDataUpdate
    {
        public double Bid { get; set; }
        public double Ask { get; set; }
        public double Last { get; set; }

        public double Mid
        {           
            get { return (Bid + Ask) / 2; }

        }
    }
}


C# is a fairly new language for me, so there might be some best practises that I may have missed. I am also wondering how this would behave in a multi-threaded environment.

Solution

Your AverageHalfSpreadIndicator doesn't implement IIndicator. I think you just forgot to

public class AverageHalfSpreadIndicator : IIndicator


You should instantiate your _lastUpdates:

public AverageHalfSpreadIndicator(IMarketDataFeed marketDataFeed)
{
    _lastUpdates = new List();
    marketDataFeed.Update += OnMarketDataUpdate;
}


I don't like this code:

_lastUpdates.Add(updates);
if (_lastUpdates.Count == 20)
{
    _lastUpdates.RemoveAt(0);
}


I mean, it's fine, but I'd prefer to implement the _lastUpdates as a fixed sized queue. You can find many implementations on SO, for example: 1, 2, 3.

Also, your code is not thread-safe. If your code'd be called by many threads it'd break.

Don't use DateTime to measure execution time. There is a special class for this task: System.Diagnostics.Stopwatch.

var stopWatch = new Stopwatch();
stopWatch.Start();
var spreads = _lastUpdates.Select(x => 100 * (x.Mid - x.Bid) / x.Bid);
Console.WriteLine("Time to compute spreads: " + stopWatch.ElapsedMilliseconds + " ms");

var averageSpread = spreads.Average();
Console.WriteLine("Total time:" + stopWatch.ElapsedMilliseconds + " ms");
stopWatch.Stop();


This is not a big deal, but instead of encapsulating just Mid you can encapsulate whole 100 * (x.Mid - x.Bid) / x.Bidin your MarketDataUpdate.

Code Snippets

public class AverageHalfSpreadIndicator : IIndicator
public AverageHalfSpreadIndicator(IMarketDataFeed marketDataFeed)
{
    _lastUpdates = new List<MarketDataUpdate>();
    marketDataFeed.Update += OnMarketDataUpdate;
}
_lastUpdates.Add(updates);
if (_lastUpdates.Count == 20)
{
    _lastUpdates.RemoveAt(0);
}
var stopWatch = new Stopwatch();
stopWatch.Start();
var spreads = _lastUpdates.Select(x => 100 * (x.Mid - x.Bid) / x.Bid);
Console.WriteLine("Time to compute spreads: " + stopWatch.ElapsedMilliseconds + " ms");

var averageSpread = spreads.Average();
Console.WriteLine("Total time:" + stopWatch.ElapsedMilliseconds + " ms");
stopWatch.Stop();

Context

StackExchange Code Review Q#83727, answer score: 5

Revisions (0)

No revisions yet.