I'm playing around with historical stock market analysis in Perl. One aspect deals with analyzing the accuracy of research firms past stock ratings. The most rudimentary rating scale would be Buy, Hold, Sell. However many of these firms use different terminology, some with more than 3 points on their scale.
What I have is a list of thousands of upgrade/downgrades issued by hundreds of different firms (from Yahoo Finance) that looks something like this:
Action From To
==================================================
Upgrade Add Buy
Downgrade Add Hold
Upgrade Hold Add
Downgrade Buy Outperform
Upgrade Hold Outperform
Downgrade Hold Reduce
Upgrade Add Outperform
So basically it's a list of comparisons like A > B, D < C, B > C, D < A
What I need for each research firm, taking in a long list of these comparisons, is an ordered list that looks like this:
A > B > C > D > E
I've given this problem a lot of thought and can't come up with a solution. If each upgrade/downgrade only jumped one increment, I think I could do it but I can't wrap my head around how to insert a comparison like C < A, where it jumps two increments.
Anybody have any ideas?
Update:
Thanks @ikegami. I tested with the original data and you are correct.
I also ran some data through Graph::Easy, which renders graphs.
Code:
use Graph::Easy;
my $graph = Graph::Easy->new( );
# Note that these are all in 'Upgrade' direction
$graph->add_edge ('Hold', 'Add');
$graph->add_edge ('Hold', 'Buy');
$graph->add_edge ('Hold', 'Outperform');
$graph->add_edge ('Buy', 'Outperform');
$graph->add_edge ('Reduce', 'Hold');
$graph->add_edge ('Add', 'Buy');
print $graph->as_ascii( );
Output:
+------------------------+
| v
+--------+ +------+ +-----+ +-----+ +------------+
| Reduce | --> | Hold | --> | Add | --> | Buy | --> | Outperform |
+--------+ +------+ +-----+ +-----+ +------------+
| ^
+------------------------------------+
Here's a graph with some clear ambiguities. Perhaps I can somehow use both modules (or some feature of Graph) to test for ambiguities.
+------------------------------+
| v
+--------+ +---------+ +-----+
| Reduce | --> | Neutral | --> | Buy |
+--------+ +---------+ +-----+
^ ^
| |
| |
+---------+ |
| Sell | ------+
+---------+
I don't use graphs all that often, but this code (using the
Graph
module) seems to do the job:This prints
Reduce < Hold < Add < Outperform < Buy
.