Daily-return correlation vs price-level correlation, five familiar pairs (2024-2025)
Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-08-13, from Pairs Trading and Cointegration Explained.
| pair | return_corr | price_corr |
|---|---|---|
| HD / LOW | 0.868 | 0.849 |
| V / MA | 0.862 | 0.954 |
| XOM / CVX | 0.795 | 0.512 |
| KO / PEP | 0.576 | -0.493 |
| AAPL / MSFT | 0.479 | 0.508 |
- Rows × columns
- 5 × 3
- Computed
- Completeness
- No missing values
- Source
- US exchange, SIP and OPRA market data
- Licence
- Strasmore terms · free, no signup
What each column holds
| Column | Type | Range | Notes |
|---|---|---|---|
pair |
text | 5 distinct values (AAPL / MSFT, HD / LOW, KO / PEP…) | |
return_corr |
number | 0.479 to 0.868 | |
price_corr |
number | -0.493 to 0.954 | US dollars |
Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.
the exact SQL behind every number
WITH
px AS (
SELECT
ticker,
date,
toFloat64(any(close)) AS close_px
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('KO', 'PEP', 'HD', 'LOW', 'XOM', 'CVX', 'V', 'MA', 'AAPL', 'MSFT')
AND date BETWEEN '2024-01-01' AND '2025-12-31'
GROUP BY ticker, date
),
rets AS (
SELECT
ticker,
date,
close_px,
close_px / lagInFrame(close_px) OVER (
PARTITION BY ticker ORDER BY date
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
) - 1 AS ret
FROM px
)
SELECT
p.pair AS pair,
round(corr(a.ret, b.ret), 3) AS return_corr,
round(corr(a.close_px, b.close_px), 3) AS price_corr
FROM
(
SELECT
tupleElement(t, 1) AS leg_a,
tupleElement(t, 2) AS leg_b,
tupleElement(t, 3) AS pair
FROM
(
SELECT arrayJoin([
('KO', 'PEP', 'KO / PEP'),
('HD', 'LOW', 'HD / LOW'),
('XOM', 'CVX', 'XOM / CVX'),
('V', 'MA', 'V / MA'),
('AAPL', 'MSFT', 'AAPL / MSFT')
]) AS t
)
) AS p
INNER JOIN rets AS a ON a.ticker = p.leg_a
INNER JOIN rets AS b ON b.ticker = p.leg_b AND b.date = a.date
WHERE isFinite(a.ret) AND isFinite(b.ret)
GROUP BY pair
ORDER BY return_corr DESC
Run your own version of this
The same 22 years of US equities and 12 years of options data are queryable in SQL or plain English. A free account runs 100 queries a day and takes no card.
More from this analysisPairs Trading and Cointegration Explained
Hedge ratio refitted each calendar year, two sector pairs
ranking 7×3
→
Where the KO/PEP spread sat twenty sessions later, by starting z score (2019-2025)
ranking 6×4
→
Weekly z score of the KO/PEP spread, hedge ratio fitted on 2023 only
series 105×2
→
Variance ratio by block length: does SPY variance scale like independent draws?
ranking 7×3
→
Lag-one autocorrelation: signed returns against absolute returns, 2016 to 2025
ranking 6×4
→
One position, one year at a time: SPY annualized Sharpe by calendar year
table 14×5
→
See all 2,170 queries →