# How I won \$6,000 in the M6 Forecasting Competition

--

Spoiler: not with deep learning

The M6 Forecasting Competition involved two tasks: given 100 assets, you had to

1. forecast a probability distribution for the quintile in which the log returns of each asset would be at the end of each month;
2. determine how you would invest a hypothetical unit of money.

The competition went on for 12 whole entire months, with prizes each quarter. I was lucky enough to land 2nd in Q1, and 10th overall, out of 163 participants. The competition is finally over, so I can now share what I did.

# My approach: forecasting

## General idea

My workflow was:

• for each asset, take the last 200 values of its adjusted close price;
• estimate the covariance between their returns, using a covariance estimator from the `precise` Python package (https://github.com/microprediction/precise)
• sample from the covariance matrix, and count how often each asset appears in each quintile.

One difficulty lies in how to choose which covariance estimator to use. My answer is: cross-validation, cross-validation, cross-validation (this also happens to also my answer to virtually any question about Data Science…).

## Cross-validation strategy

Suppose we’re forecasting for the period 2022–03–07 — 2022–04–01. Then, for each covariance estimator in `precise`, I would:

• train on data strictly before 2022–02–07, forecast for the period 2022–02–07–2022–03–04;
• train on data strictly before 2022–01–10, forecast for the period 2022–01–10–2022–02–04;
• train on data strictly before 2021–12–13, forecast for the period 2021–12–13–2022–01–07.

Then, calculate the RPS score for each, take the best-performing covariance estimators, and average them.

With this approach I was able to beat the benchmark — though, full disclaimer, I did not beat it for every single month (just in aggregate). Only 3 participants managed to beat the benchmark every single month, and I’m looking forwards to reading their solutions.

# My approach: investing

Honestly, my result here was 50% luck and 50% luck. I really don’t know anything about investing and stocks. So here’s what I did:

• estimate a covariance matrix using the technique described above;
• put that through the portfolio constructors of `precise` .

Then, I would cross-validate (same setup as above), and choose the portfolio constructors which would beat the benchmark for each of the 3 last months. If I could find no such portfolio constructors, I would just use the benchmark.

# Magic

I received a question about how, in the last quarter, I was able to “achieve” a IR score of exactly 1.000. The answer lies in the asset `DRE` , which stopped being publicly traded around Q7 and so its price stayed constant thereafter. At the end of Q8 I noticed that my IR score was barely positive, so I decided to invest everything in DRE for the final quarter, thus “locking in” my IR score until the end of the competition (in fact, guaranteeing it would ever-so-slightly rise).

In the end, my investing score would’ve been higher if I’d just used the benchmark each time, so more fool me.

# OK, where’s the code? Where can I read more?

Here you go: https://github.com/MarcoGorelli/wound-ignite.

Other resources:

# Closing remarks

When I entered the competition, I had a gut feeling that a simple solution would have a good chance of ending up in the top 10% because most participants would end up over-fitting anyway. Pretty sure this is exactly what ended up happening: only about 23% of participants beat the benchmark in the forecasting track. If there’s one lesson you take away from this, it’s that cross-validation is fundamental to Data Science.

Finally, a note on the team name: for some reason, a Ruscist propagandist started commenting on virtually all LinkedIn posts about the competition, so I thought it’d be apt to piss him off by including “Glory to Ukraine” in my team name and getting it close to the top of the leaderboard.