When building financial applications, often products involve complex forms with lots of fields. When the user selects a value other fields are defaulted, schedules and trade summaries are generated as well as other changes. There are multiple ways to solve this problem each having it’s ups and downs.

Today we are open sourcing an experimental library to solve this issue. We have not used this library in production yet and still has some work to be done, but we wanted to put it out there to get feedback before going much further.

Using Rx to solve the problem

At Adaptive we use Reactive Extensions (Rx) a lot and used Rx to deal with this issue as well. Our code would look something like this:

Reactive UI also takes this approach. While this works great for a few rules it can become hard to maintain over time because rules start overlapping and you get a cascade of changes with some fields having their values recalculated multiple times.

To illustrate the problem lets talk about a simple example, Mortgage calculation. To calculate how much each payment is I need the loan amount, interest rate, length of loan and the payment frequency.

Lets say I am building a simple mortgage calculator app and my loan schedule is calculated server side, when I change my loan amount it will default the payment amount. If my schedule is recalculated when any of the fields change then I will make two server calls, one for loan amount then again when the payment amount is recalculated.

At this point you need to understand that whenever length, interest rate, amount or frequency changes then payment amount will always be updated, so your schedule only listens to changes on payment amounts. This is a maintenance nightmare when dependencies change because it is so easy to break the dependency chain.

Introducing ReactGraph

This is actually a solved problem. Excel deals with these sort of problems all the time, formulas which rely on values from other formulas.

What we need is a graph which understands all the dependencies.

Simple Loans Graph

Once we have a graph we can see what the fallout will be from any change that happens. When amount is changed, it will trigger both the calculate which will update payments and update schedule (server side call). When update payments finishes it will update the payments fields which triggers update schedule again.

The graph makes this fallout clear and once we have a graph there are some well known algorithms which solves this for us. ReactGraph uses a breadth first topological sort which turns the graph into a ordered list of what properties need to be updated in what order. After running the algo we get:

  1. CalculatePayments()
  2. Payments
  3. CalculateSchedule()
  4. Schedule

The code

ReactGraph has a pluggable notification model, by default it listens to INotifyPropertyChanged notifications. As a side note it also supports nested properties .From(() => CalculatePayments(Mortgage.Amount, Mortgage.InterestRate, Mortgage.LoanLength, Mortgage.PaymentFrequency), ex => { });, if any value in the chain is changed it will unsubscribe/resubscribe to all needed objects.

The plan is to support asynchronous values over time, like Rx observable streams which can yield multiple values essentially making a live formula.

Visualisation

The change propogation stuff is great, but what makes ReactGraph really useful is the ability to visualise your graph! Just install the ReactGraph.Visualisation package from NuGet and you get a .ToDotFormat() extension method which will dump your graph into GraphViz Dot Format which you can put into an online viewer.

Another cool feature is the ability to log change propagation. If you check out our ReactGraphViewer project you can point it at the ReactGraph log file, and you will be able to step through each change propagation which has the path highlighted in green. If an error occurs the path which cannot be updated will be shown in red.

Change tracking

Summary

This is a quick overview of our new open source library ReactGraph.

We have not used this library in production yet but have spiked using it instead of the Rx approach talked about at the start of the post and found a massive reduction in the amount and complexity of the code.

Let us know what you think, try it out and if you like it contribute to the library. There is plenty of work to do, our performance tests show it is pretty slow in comparison to doing it yourself. If you have ideas to make this library even more awesome then just post on issue on GitHub.

ReactGraph on GitHub