A nautilus seashell with a perfect spiral is the product of specific DNA that coded for its existence.
Visuals in your application behave similarly; their appearance is controlled by a particular set of seemingly distant algorithms that come together in just the right way.
In this post, I will discuss how fundamental algorithms like “finding all unique pairs” allow for the construction of clear visuals easily and quickly interpreted by the user.
In doing so, my goal is to show how unrelated algorithms may be used in conjunction to produce intuitive markings on a chart.
I will discuss the following chart from PyraMetrik:
You do not have to be an expert on Treasuries (bonds) and their associated yield curve to get through this short article.
Just know a few things, for context:
Let’s walk through how elementary algorithms that involve generating all unique pairs and finding certain intervals in collections help us achieve this goal.
We’ll cover this in Three Steps.
Firstly, if we are given two collections representing respective yield values for respective bonds, we must find all intervals where the short-term yield is greater than the longer-term yield.
Supposing List 1 is the shorter-term bond and List 2 is the longer-term bond, we have the following diagram:
As you can see, the lines in red mark the intervals where List 1 elements are greater than List 2 elements.
In code, this could look like this:
The above function returns an array of “occurrence objects”, where an occurrence object simply contains the starting and ending indices of a given occurrence.
To really grasp this in terms of code, some unit tests for this function may look like this:
This is good, but remember, we have several bonds in the chart pasted at the beginning. So, this function needs to be performed for all possible, unique pairs of bonds — because inversions can happen anywhere.
This takes us to the second step.
Generating all unique pairs for a collection can be visualized like this:
Notice there are only three, unique pairs. If “red-green” is already considered as a pair, we don’t want to consider “green-red”, as that would be the same pair in the context of what we are doing here, that is, comparing two bonds of different term lengths.
Translating this into code, we’d get something like this:
As you can see, we start the inner loop at i+1; this ensures we don’t count “green-red” if “red-green” is already counted.
Moreover, to ensure that no duplicate pairs are included in the output, we make use of a seen object, and we only push into pairs if we have not yet “seen” that pair.
Note 1: “seen” is a JavaScript object that can be thought of as a hash map, where the time to check for the existence of a key is constant (O(1)).
Note 2: If the input “arr” is guaranteed to be of unique values, the “seen” object is not needed in this function.
Great — we now have the key algorithms that allow us to define where exactly to draw these rectangular boxes. As you might imagine, the rest is highly context-dependent. Put differently, how you decide to piece these algorithms together and finally draw the elements on the chart is up to your project’s requirements/libraries/implementations.
I’ll show you how I do it, but remember — this is for PyraMetrik specifically, where we use recharts for charting.
The main logic to bring the above algorithms together is as follows:
There are functions like getCloserAndFurther() and findExtremes() that determine the closer/further dated bonds and find the y-coordinates of the inversions, respectively. But again, this is out of the scope of this article and domain-specific.
Then, inside my line chart, I draw inversions using the ReferenceArea (part of recharts):
That’s it.
Now we have these distinct, grey boxes that clearly show us areas of yield curve inversion. No need to strain the eyes or waste mental bandwidth trying to spot such patterns “yourself”.
Algorithms sound everything but “visual”, and visuals sound everything but “mathematic”. But as shown here, the two are intertwined, and deeply understanding this connection clears the runway for a whole new paradigm of user experiences.
Also published here.