How do you rank stocks based on correlation with other holdings

I want to rank stocks so that my model buys the ones that have lower correlation with other high ranked stocks. Is this possible?i

In other words, check the correlation of each potential holding with each of the top 50 or perhaps with the group as a whole - not sure what would be better. Kind of a similar idea as pairs trading I guess? Except I only want to go long on each holding still.

Hi Curtis,

Exactly!!! Something to emulate in a practical way wherever possible:

I’ll move this to another thread if it’s too long or off-topic, but I genuinely think this is close to optimal when limited to just Python, P123’s current tools, and maybe a spreadsheet. In fact, this might be the most practical outline of an algorithm posted so far (and feel free to tweak it) for accomplishing what Curtis wants—and it’s doable enough that I might try it myself, at least until P123 automates something similar (if they ever decide to).
—

Note:

This method works particularly well when all the stocks have the same rank—for example, Zacks Rank #1 or a Fidelity “Equity Summary Score” of 10. In those cases, correlation-based selection adds real value because traditional ranking no longer differentiates among the picks.

—

Algorithm (Simple Outline):

  • Rebalance: Sell stocks with RankPos below your cutoff (e.g., 120), or that no longer have a Zacks Rank of 1 or a Fidelity Equity Summary Score of 10.
  • Select candidates: Take your top 100 (or all with the same “best” rank as with Zacks Rank) and build a correlation matrix.
  • Pair selection: Find the pair with the lowest correlation. Beta-weight these and add them (and their weights) to a CSV for further analysis (e.g., in Python).
  • Iterate: Keep adding the next least correlated stock (relative to those already selected) until you have enough to replace what was sold.
  • Automate: Automate the download of the price data and have Python do the heavy lifting—including calculating the final weights for each ticker pair.
  • (Optional, for the extra detail-oriented): Adding hierarchical risk parity or equal risk contribution for the pairs could provide another layer of risk control—mainly for those who have too much time on their hands! Personally, that would make it no longer simple enough for me to implement—especially when you consider transaction costs with each rebalance.

—

Of course, this is just a starting point. Real-world implementation will need to address practical issues like transaction costs, turnover management, and whether to always keep or sell both stocks from each pair at rebalance when only one has dropped out of the top-ranked group.

Why do this?

Correlations between holdings often spike at the worst times, especially in long-short or hedged portfolios. Even a “market-neutral” portfolio can get hit hard if the long and short baskets become highly correlated during market stress. As Joel Greenblatt has pointed out, a naive long-short “magic formula” strategy would have blown up in past market reversals due to this exact risk. Picking holdings to minimize internal correlation helps address this—even when all the picks are top-ranked (or have high and low ranks in a long-short hedged portfolio).

—

FWIW: With a few tweaks, this could be a highly practical approach. I might just give it a try myself. If anyone’s done something similar or has ideas to refine it, I’d love to hear your thoughts.

Thank you Curtis for getting me to think about the most practical way to run a paris-traiding-like strategy with the tools we have.

@marco I understand you’re about to buy an expensive risk management tool! Very cool—especially if an enterprise customer is footing the bill! I’m looking forward to seeing what it can do, and I’m sure it will introduce some new ideas I haven’t considered. But will it really outperform a refined version of this free method? And will it be more—or less—practical for day-to-day use by P123 members—especially those who don’t focus on ETFs and want to keep high rank as a top priority? This approach keeps the emphasis on ranking for stock selection, rather than shifting toward ETF-heavy portfolios or diluting the role of rank just for diversification.

You could use MaxCorrel() to avoid adding stocks that move too similarly to your existing holdings. By setting a correlation threshold, you can ensure that each new stock you add brings unique price movement characteristics to the portfolio, potentially reducing overall portfolio risk.

https://www.portfolio123.com/doc/doc_detail.jsp?factor=MaxCorrel

2 Likes

Massive

1 Like

That’s a great suggestion—thanks for posting it! I actually gave it a try, using MaxCorrel() in the buy rules of my funded port’s SIM, but didn’t see much benefit. My theory is that most holdings are already so correlated to the market that filtering on raw correlation doesn’t really add diversification; it just reduces the number of holdings, without improving risk or return.

For my approach, I generally have to use excess returns (stripping out the market noise) before correlation filtering really makes a difference. That’s when it becomes useful for me.

Maybe this is just a function of my strategy, universe, or how I used MaxCorrel()? Has anyone else found MaxCorrel() to work well—in a different context, maybe? I’d love to see some before-and-after examples (with and without MaxCorrel()), if anyone’s willing to share. (I’d share mine, but honestly, the results would be entirely negative.)

Thanks again for the tip. I might try using a P123 custom data series to check the correlation of excess or relative returns . My guess is it’ll work better in that context for me—or maybe I’ll spot something I was missing. Either way, it’s a great idea, and I suspect it can be made to work with a different port or a small modification!

—

On a related note—just something I’ve noticed with multiple tests of autocorrelation (and the literature supports this): Even the autocorrelation (serial correlation) of returns for a single stock is typically close to zero!

That means if a stock’s own past returns barely predict its future returns, it’s not surprising that pairwise correlations (going forward) between stocks—at least on raw, short-term returns—are also quite low. That’s why, even in pairs trading, you often have to go to extremes—finding closely related stocks in the same subindustry (like Coke and Pepsi or 2 airline stocks) and using cointegration rather than simple correlation at that. And even then, you need a large pool of pairs to get a few that really work. So maybe I’m not alone in seeing these limitations.

I’m still agnostic about what truly works within a port—there’s probably something I’ve missed—but genuinely effective hedging (i.e., preventing correlation spikes between longs and shorts, or with options, during drawdowns) is just a bit too complex for me to implement. Even seasoned pairs traders face real, practical problems with it.