Canto I: Momentum Basics
Preamble
The first post where I explore market inefficiencies in the style of epic poems.
Momentum
In the flux of market tides, where shadows stretch and prices churn, the swift ascend, borne on invisible winds, while the laggards drown in time’s relentless undertow. Momentum, the unseen force, propels the chosen few to peaks uncharted, a silent gale, fierce yet intangible, guiding each ascent with whispered promise of ascent anew. Not in still waters do fortunes burgeon, but in the pulse, the surge, the ceaseless flow, where only the fleet-footed dare to thrive, and in their wake, the gains, like echoes, rise.
Logistics & Benchmark & Data
To make things simple, I'll be using this mixture of large cap tech stocks throughout:
aapl, msft, goog, amzn, tsla, nflx, meta, spy
Our benchmark that we compare our performance against is a buy and hold, long only strategy applied to the S&P 500.
Our backtesting framework will be bt. This package also grabs the data for us.
Here is the function that I'm using to run the strategies:
Once we have our strategies, we can run them like so:
Simple Momentum
Strategy
This stratagem rides the crest of price waves, measuring momentum—price shifts over chosen intervals. It selects equities that surge ahead, casting aside the laggards.
-
Momentum:
- Gauge the price flux over set days.
-
Selection:
- Rank, retain the top echelon.
-
Rebalance:
- Equal stakes, realigned monthly.
-
Benchmark:
- Compare the temporal arcs — week, fortnight, month — against the S&P’s steady course.
The aim: to harness the force of those whose ascent foretells further climb.
Results
| Stat | 5_day | 10_day | 21_day | 42_day | S&P 500 |
|---|---|---|---|---|---|
| Start | 2020-01-01 | 2020-01-01 | 2020-01-01 | 2020-01-01 | 2020-01-01 |
| End | 2024-09-06 | 2024-09-06 | 2024-09-06 | 2024-09-06 | 2024-09-06 |
| Risk-free rate | 0.00% | 0.00% | 0.00% | 0.00% | 0.00% |
| Total Return | 960.80% | 818.12% | 566.24% | 400.63% | 78.24% |
| Daily Sharpe | 1.26 | 1.20 | 1.07 | 0.94 | 0.68 |
| Daily Sortino | 2.26 | 2.14 | 1.76 | 1.57 | 1.06 |
| CAGR | 65.60% | 60.57% | 49.94% | 41.06% | 13.14% |
| Max Drawdown | -52.41% | -56.25% | -56.88% | -47.45% | -33.71% |
| Calmar Ratio | 1.25 | 1.08 | 0.88 | 0.87 | 0.39 |
| MTD | -8.00% | -8.94% | -5.07% | -4.52% | -4.14% |
| 3m | 24.23% | 22.83% | -1.06% | -2.77% | 1.39% |
| 6m | 44.10% | 13.51% | 11.96% | 12.04% | 6.68% |
| YTD | 51.85% | 19.98% | 34.45% | 20.63% | 14.40% |
| 1Y | 49.09% | 34.66% | 41.57% | 12.38% | 22.79% |
| 3Y (ann.) | 38.20% | 27.73% | 24.23% | 24.07% | 7.76% |
| 5Y (ann.) | 65.60% | 60.57% | 49.94% | 41.06% | 13.14% |
| Since Incep. (ann.) | 65.60% | 60.57% | 49.94% | 41.06% | 13.14% |
| Daily Sharpe | 1.26 | 1.20 | 1.07 | 0.94 | 0.68 |
| Daily Sortino | 2.26 | 2.14 | 1.76 | 1.57 | 1.06 |
| Daily Mean (ann | 62.85% | 59.64% | 53.04% | 46.99% | 14.68% |
| Daily Vol (ann. | 49.77% | 49.53% | 49.74% | 50.03% | 21.46% |
| Daily Skew | 0.45 | 0.41 | -0.24 | 0.11 | -0.53 |
| Daily Kurt | 5.22 | 4.88 | 5.01 | 7.69 | 11.14 |
| Best Day | 19.89% | 19.89% | 13.48% | 23.28% | 9.06% |
| Worst Day | -17.18% | -17.18% | -21.06% | -21.06% | -10.94% |
| Monthly Sharpe | 1.04 | 1.06 | 1.11 | 0.86 | 0.77 |
| Monthly Sortino | 2.69 | 2.78 | 2.55 | 2.08 | 1.40 |
| Monthly Mean (ann.) | 59.42% | 55.27% | 51.26% | 49.66% | 14.39% |
| Monthly Vol (ann.) | 56.93% | 52.24% | 45.99% | 57.51% | 18.75% |
| Monthly Skew | 1.16 | 0.83 | 0.26 | 1.25 | -0.36 |
| Monthly Kurt | 2.59 | 0.97 | -0.20 | 5.06 | -0.22 |
| Best Month | 60.18% | 49.13% | 32.50% | 74.14% | 12.69% |
| Worst Month | -29.95% | -25.25% | -24.70% | -38.59% | -12.48% |
| Yearly Sharpe | 1.04 | 0.56 | 0.65 | 0.89 | 0.59 |
| Yearly Sortino | 4.87 | 1.90 | 1.83 | 4.96 | 1.41 |
| Yearly Mean | 37.84% | 43.12% | 34.25% | 22.15% | 12.78% |
| Yearly Vol | 36.28% | 76.53% | 52.89% | 24.92% | 21.56% |
| Yearly Skew | -1.77 | 0.21 | -0.93 | -0.15 | -1.54 |
| Yearly Kurt | 3.36 | 0.20 | 1.52 | 1.36 | 2.16 |
| Best Year | 65.53% | 137.47% | 88.43% | 51.93% | 28.72% |
| Worst Year | -15.54% | -45.39% | -37.53% | -8.93% | -18.17% |
| Avg. Drawdown | -8.27% | -10.38% | -9.24% | -10.44% | -1.99% |
| Avg. Drawdown Days | 53.13 | 51.39 | 41.00 | 49.84 | 18.76 |
| Avg. Up Month | 14.22% | 14.22% | 13.71% | 14.74% | 4.55% |
| Avg. Down Month | -7.41% | -7.31% | -6.62% | -8.10% | -4.83% |
| Win Year % | 75.00% | 75.00% | 75.00% | 75.00% | 75.00% |
| Win 12m % | 82.61% | 76.09% | 76.09% | 82.61% | 76.09% |
Volatility-Weighted Momentum
Strategy
The same as above, but we divide the momentum factor by rolling volatility. In this case we use 21 days for volatility. We could do all combinations as well pretty easily (exercise for the reader perhaps).
| Stat | 5_day | 10_day | 21_day | 42_day | S&P 500 |
|---|---|---|---|---|---|
| Start | 2020-01-01 | 2020-01-01 | 2020-01-01 | 2020-01-01 | 2020-01-01 |
| End | 2024-09-06 | 2024-09-06 | 2024-09-06 | 2024-09-06 | 2024-09-06 |
| Risk-free rate | 0.00% | 0.00% | 0.00% | 0.00% | 0.00% |
| Total Return | 381.27% | 190.81% | 262.58% | 163.80% | 78.24% |
| Daily Sharpe | 0.97 | 0.73 | 0.82 | 0.69 | 0.68 |
| Daily Sortino | 1.69 | 1.20 | 1.36 | 1.14 | 1.06 |
| CAGR | 39.88% | 25.61% | 31.67% | 23.02% | 13.14% |
| Max Drawdown | -49.71% | -60.95% | -59.13% | -52.05% | -33.71% |
| Calmar Ratio | 0.80 | 0.42 | 0.54 | 0.44 | 0.39 |
| MTD | -8.00% | -8.94% | -5.07% | -4.52% | -4.14% |
| 3m | -2.30% | 24.82% | -14.06% | 9.98% | 1.39% |
| 6m | 34.06% | 50.71% | -5.82% | 24.59% | 6.68% |
| YTD | 33.88% | 45.54% | 28.21% | 59.63% | 14.40% |
| 1Y | 32.25% | 59.57% | 20.35% | 72.00% | 22.79% |
| 3Y (ann.) | 26.01% | 11.82% | 27.23% | 37.24% | 7.76% |
| 5Y (ann.) | 39.88% | 25.61% | 31.67% | 23.02% | 13.14% |
| Since Incep. (ann.) | 39.88% | 25.61% | 31.67% | 23.02% | 13.14% |
| Daily Sharpe | 0.97 | 0.73 | 0.82 | 0.69 | 0.68 |
| Daily Sortino | 1.69 | 1.20 | 1.36 | 1.14 | 1.06 |
| Daily Mean (ann.) | 43.81% | 33.16% | 38.63% | 30.72% | 14.68% |
| Daily Vol (ann.) | 45.24% | 45.38% | 47.16% | 44.77% | 21.46% |
| Daily Skew | 0.35 | 0.00 | 0.38 | 0.49 | -0.53 |
| Daily Kurt | 6.36 | 5.71 | 8.34 | 11.55 | 11.14 |
| Best Day | 16.85% | 15.31% | 23.28% | 23.28% | 9.06% |
| Worst Day | -17.18% | -17.18% | -17.18% | -18.58% | -10.94% |
| Monthly Sharpe | 0.91 | 0.74 | 0.81 | 0.69 | 0.77 |
| Monthly Sortino | 1.98 | 1.55 | 1.73 | 1.22 | 1.40 |
| Monthly Mean (ann.) | 46.21% | 31.96% | 39.01% | 33.27% | 14.39% |
| Monthly Vol (ann.) | 50.53% | 43.31% | 48.43% | 48.48% | 18.75% |
| Monthly Skew | 0.34 | 0.47 | 0.42 | -0.32 | -0.36 |
| Monthly Kurt | 0.61 | 1.35 | 1.06 | 3.17 | -0.22 |
| Best Month | 37.89% | 40.42% | 38.95% | 38.27% | 12.69% |
| Worst Month | -33.03% | -26.98% | -35.41% | -49.06% | -12.48% |
| Yearly Sharpe | 0.84 | 0.54 | 0.67 | 0.95 | 0.59 |
| Yearly Sortino | 3.17 | 1.15 | 2.26 | 3.46 | 1.41 |
| Yearly Mean | 34.05% | 30.89% | 40.42% | 40.98% | 12.78% |
| Yearly Vol | 40.60% | 57.55% | 60.43% | 43.32% | 21.56% |
| Yearly Skew | -1.02 | -1.78 | -0.38 | -1.94 | -1.54 |
| Yearly Kurt | 1.47 | 3.29 | 0.20 | 3.82 | 2.16 |
| Best Year | 74.38% | 72.47% | 108.07% | 68.56% | 28.72% |
| Worst Year | -21.47% | -53.85% | -35.74% | -23.69% | -18.17% |
| Avg. Drawdown | -8.34% | -9.12% | -7.51% | -7.49% | -1.99% |
| Avg. Drawdown Days | 52.63 | 59.15 | 37.54 | 46.91 | 18.76 |
| Avg. Up Month | 13.44% | 10.33% | 12.08% | 11.06% | 4.55% |
| Avg. Down Month | -7.21% | -7.56% | -7.69% | -8.28% | -4.83% |
| Win Year % | 75.00% | 75.00% | 75.00% | 75.00% | 75.00% |
| Win 12m % | 80.43% | 73.91% | 78.26% | 76.09% | 76.09% |
Results
If we look just at total return:
Simple Momentum:
| Stat | 5_day | 10_day | 21_day | 42_day | S&P 500 |
|---|---|---|---|---|---|
| Total Return | 960.80% | 818.12% | 566.24% | 400.63% | 78.24% |
Volatility-Adjusted Momentum:
| Stat | 5_day | 10_day | 21_day | 42_day | S&P 500 |
|---|---|---|---|---|---|
| Total Return | 381.27% | 190.81% | 262.58% | 163.80% | 78.24% |
It makes sense that Volatility-Adjusted momentum would have lesser returns. My intuition is that momentum thrives off of volatility, and in our case we were dampening the momentum signal by dividing by volatility.
If we go back and change the division to a multiplication, having volatility amplify momentum, we get much different results:
| Stat | 5_day | 10_day | 21_day | 42_day | S&P 500 |
|---|---|---|---|---|---|
| Total Return | 743.87% | 576.43% | 1221.59% | 430.94% | 78.24% |