Reactive Framework Labs
This article is one from the “Processing Financial Data with Microsoft Reactive Framework (Reactive Extensions for .NET)” series of articles that demonstrate some basic applications of Rx framework to financial data. This article focuses on detecting running high/low values (like daily max and min) from a market data feed. Other articles in the series are:
Visual Studio 2008 solution containing full source code for all examples can be downloaded here.
Detecting Running High/Low Prices
The key operators in this implementation are “Do” and “Where”, both built into the Reactive Framework. The first one is used to produce side effect of recording the running High or Low value, and the second is used to filter incoming values that do not produce newest High or Low:
// simulate market data var rnd = new Random(); var feed = Observable.Defer(() => Observable.Return(Math.Round(30.0 + rnd.NextDouble(), 2)) .Delay(TimeSpan.FromSeconds(1 * rnd.NextDouble()))) .Repeat(); // Daily low price feed double min = double.MaxValue; var feedLo = feed .Where(p => p < min) .Do(p => min = Math.Min(min, p)) .Select(p => "New LO: " + p); // Daily high price feed double max = double.MinValue; var feedHi = feed .Where(p => p > max) .Do(p => max = Math.Max(max, p)) .Select(p => "New HI: " + p); // Combine hi and lo in one feed and subscribe to it feedLo.Merge(feedHi).Subscribe(Console.WriteLine); Console.ReadKey(true);
The first block of code is a simple market data feed simulator. It generates random prices in the $30-$31 range at random intervals of zero to one second. Market simulator itself is written using Rx (all in one statement, isn’t this cool?).
The second block of code extracts ticks from the base feed only if they represent running lowest prices received from the feed. This is achieved by composition of the following:
- base stream of prices
- “Where” clause to filter away ticks that are greater or equal to the current running minimum price
- “Do” operator to record the current minimum value; “Do” operator simply wraps underlying stream and repeats the values it receives; its power comes from being able to execute arbitrary code per each received value and thus produce side effects (recording min value in our case)
- “Select” projection is simply used here to label the values with “New LO: “ prefix for presentational purposes
The third block of code does the same for capturing running High values.
At the end we merge both feeds into one and subscribe to it.
If you run the code you should see something similar to this run:
The feed slowly but surely converges to $30 for low and $31 for high (limits of our feed generator). Once extreme values are reached, no additional ticks will come out.