00 · AbstractWhy seven charts became one matrix
On October 10, 2025, every coin in this set sold off, but BTC's 7.28% loss and SUI's 23.68% loss are very different outcomes for what was plainly a shared event. Seven tickers can look like seven separate positions until their worst bar of the day arrives together, and we wanted to know how much risk those positions actually shared and what was left to account for a gap that large.
We took four-hour returns for BTC, ETH, SOL, BNB, HYPE, XRP, and SUI from Hyperliquid's public API, giving us 318 returns per coin from September 1 through October 24. If the seven returns mostly share one movement, there should be one direction through the data that carries much more variation than the others. That is what the calculation finds: one direction carries 76.6% of the sample's standardised return variance, meaning variation after each coin is put on its own volatility scale.
Every coin loads positively on that direction, and when we project the October 10 returns onto it, the worst four-hour bar stands out immediately. The common direction captures much of the selloff, but it does not give BTC and SUI the same loss, so the differences between their returns remain part of the question throughout.
We start with the seven losses a reader would have seen that day, then use the matrix to ask how much of the scene was one market move and what the remaining differences might mean. The equations show where the numbers come from, while the solver and code are at the end for anyone who wants to take the calculation apart.
01 · DataSeven coins, public tape
The universe. BTC, ETH, SOL, BNB, HYPE, XRP, and SUI perpetuals on Hyperliquid give us two exchange tokens and a mix of larger and more volatile names, with enough coins to see co-movement and few enough to keep the whole matrix on one screen.
The tape. Four-hour candles, 2025-09-01 00:00 UTC to 2025-10-24 00:00 UTC: 319 candles per coin and 318 log returns from Hyperliquid's public API. You can fetch these without a subscription or an API key.
The public candle history is depth-limited, so the one-hour series does not reach this event window; four-hour closes do, giving 318 observations for a first pass at seven assets. The last week of September has mean pairwise correlation around , while October is closer to ; we wanted both periods in the sample, though their difference means the fitted matrix averages over two regimes.
The event. October 10, 2025 was a mass-liquidation day. The daily (candle-open to candle-close) moves in this sample:
| Coin | 2025-10-10 |
|---|---|
| BTC | |
| ETH | |
| SOL | |
| BNB | |
| HYPE | |
| XRP | |
| SUI |
The 20:00 UTC bar is the worst of the day for every coin, which makes the shared move easy to see; the gap between BTC and SUI is what keeps this from being just a story about seven coins falling together. Before looking at that bar in isolation, we want a baseline for how these coins moved together across the rest of the window.
02 · CorrelationPutting the returns on the same scale
First, turn closes into log returns, which measure the change from one four-hour close to the next on a scale that can be added across bars. For coin at bar :
That gives us a return matrix. Correlation then asks whether two coins tend to be above or below their own average on the same bars, with meaning they move together perfectly, meaning no consistent linear relationship, and meaning they move in opposite directions:
with . The result, with stronger positive pairs shaded more brightly:
| BTC | ETH | SOL | BNB | HYPE | XRP | SUI | |
|---|---|---|---|---|---|---|---|
| BTC | 1.000 | 0.832 | 0.779 | 0.642 | 0.623 | 0.755 | 0.715 |
| ETH | 0.832 | 1.000 | 0.835 | 0.648 | 0.668 | 0.764 | 0.745 |
| SOL | 0.779 | 0.835 | 1.000 | 0.645 | 0.731 | 0.798 | 0.803 |
| BNB | 0.642 | 0.648 | 0.645 | 1.000 | 0.599 | 0.667 | 0.664 |
| HYPE | 0.623 | 0.668 | 0.731 | 0.599 | 1.000 | 0.693 | 0.734 |
| XRP | 0.755 | 0.764 | 0.798 | 0.667 | 0.693 | 1.000 | 0.869 |
| SUI | 0.715 | 0.745 | 0.803 | 0.664 | 0.734 | 0.869 | 1.000 |
The smallest off-diagonal entry is and the mean is , so these books move together quite a lot on four-hour bars, and none of the 21 distinct pairs is negatively correlated in this sample. That makes a shared October 10 move less surprising, but pairwise correlations do not tell us whether there is one direction running through all seven returns or several overlapping groups, which is the distinction we need before we can read the event chart.
Why correlation instead of covariance? SUI's raw volatility is roughly twice BTC's in this window, so a covariance matrix would pick up that difference in scale before telling us much about the structure. Standardising the return series puts ones on the diagonal and makes the trace , which lets us read an eigenvalue divided by as its share of total standardised variance. It also means that a coin's share of variance on a factor is a different question from how far its raw price fell on October 10, a distinction that will matter when we get back to SUI. For portfolio sizing, we would put the volatilities back in.
03 · EVDFinding the shared direction
To find out whether the co-movement in that matrix has one dominant direction, we use principal component analysis (PCA). It rotates the seven return columns into new directions whose scores are uncorrelated in this sample, so the largest direction tells us how much of their variation can be described by one shared move. The correlation matrix is symmetric, so we can write
The columns of give the new directions, and each , or eigenvalue, measures how much standardised variance its direction carries. We used a small cyclic Jacobi solver and checked its result against the original matrix; the rotations and checks are in the code appendix. The eigenvalues are:
| k | λₖ | explained % |
|---|---|---|
| 1 | 5.3593 | 76.56% |
| 2 | 0.4357 | 6.22% |
| 3 | 0.4286 | 6.12% |
| 4 | 0.3155 | 4.51% |
| 5 | 0.1948 | 2.78% |
| 6 | 0.1426 | 2.04% |
| 7 | 0.1236 | 1.77% |
That is a remarkably lopsided answer to the question the correlation table left open, but we cannot call it a market direction until we know which way the eigenvector points: the same large eigenvalue could describe one group of coins moving against another.
04 · FactorsOne direction does most of the work
The first eigenvector settles that point. Its loadings are
in (BTC, ETH, SOL, BNB, HYPE, XRP, SUI) order. Every entry is positive and near . An equal-weight move in all seven standardised returns looks almost exactly like this, so we will call F1 the market mode. Nothing here points to a coin that reliably moves against the rest; the difference between coins is in how much each move follows this direction and what happens outside it.
The smaller eigenvalues are where we have to be more careful:
F2 and F3 carry nearly the same variance, which means their individual axes can rotate when the sample changes even if the plane they span stays roughly where it was. That is why we think of this as one factor and a half: the first direction is clear, while the soft pair is worth studying without trusting its exact coordinates too much.
In a quieter window we would expect several overlapping groups of books, while a large shared move can pull their returns toward one diagonal. That is the geometry behind this first direction: most of the variation lies along it, and after we take it out, F2 and F3 are the near-tied directions left to inspect. A shared move in a selloff is the part we expected; the more useful question for October 10 is which differences between coins survived it.
If October 10 was largely a market-wide move, its worst bar should land far out on this first direction; whatever keeps the coins from falling by the same amount should show up outside it. The event projection is where that interpretation meets the actual returns.
05 · EventWhere October 10 lands
Now we can ask whether the direction that dominates the whole window is also where the October 10 selloff sits. For the event chart, we project each bar's raw return vector onto the correlation eigenvectors, which gives a score for how far that bar moved along each direction:
This leaves the vertical axis in log-return units; the eigenvalue shares, by comparison, come from standardised returns. The event day is shaded:
A fairly quiet four-hour bar in this chart has . On October 10:
- At 12:00 UTC, .
- At 20:00 UTC, , the largest absolute common-direction reading in the 318-bar window. That is about eighteen times the quiet reference magnitude.
- The second direction also moved, with at 20:00. The selloff was shared, but it wasn't a perfectly equal-weight one.
- On October 12, , the largest positive reading in the window.
This answers the first half of what bothered us about the daily table: the worst losses arrived together and the 20:00 bar is an extreme move along the direction that the whole sample shares. It also leaves the second half intact, because a single common score cannot by itself turn a BTC day into a SUI day.
We fitted the eigenvectors on the whole window, including October 10, so that day's returns helped define the axis on which we are measuring them. The chart shows where the event sits in the fitted space; it says nothing about what an earlier fit would have predicted. We can now ask which coins usually stay close to that common direction and which have more movement outside it, while keeping in mind that a full-window variance share is not a breakdown of this one day's loss.
06 · AttributionWhere each coin differs
F1 carries 76.6% of variance across the seven standardised return series, but it does not carry the same share for each coin. That difference will not tell us what triggered a particular liquidation, but it will show whether the unequal October 10 losses happened among coins that usually follow the common direction or among coins that usually move more independently.
The table below answers a question about the whole sample, not a question about how to divide up a single crash bar. Here we switch to standardised returns, , so the PCA decomposition and its truncated version are
The retained directions sit in ; is the projection onto the remaining directions. Their sample covariances are zero, so for coin the variance accounting is exact:
Each term is a share of that coin's standardised variance, with the second sum carrying everything left out of the truncated PCA, so there is no extra residual to add. The top four directions give:
| Coin | F1 (market) | F2 | F3 | F4 | Total |
|---|---|---|---|---|---|
| BTC | 10.3% | 2.6% | 1.0% | 90.4% | |
| ETH | 7.6% | 0.5% | 2.0% | 91.0% | |
| SOL | 1.5% | 0.9% | 0.3% | 86.7% | |
| BNB | 13.9% | 23.7% | 0.1% | 99.8% | |
| HYPE | 9.3% | 12.2% | 9.7% | 98.7% | |
| XRP | 0.0% | 0.6% | 10.2% | 93.4% | |
| SUI | 1.0% | 2.5% | 8.2% | 93.7% |
SOL, XRP, and SUI each put more than 80% of their standardised variance on F1, whereas BNB puts 62.1% there and HYPE puts 67.6%. SUI is the useful check on what this table means: it had the largest raw loss on October 10 and still has an 82.1% market share across the window, because these percentages describe variation relative to each coin's own volatility, which for SUI is roughly twice BTC's. A high share on F1 can therefore coexist with a much larger fall in raw return units; the table gives the usual structure, while the event chart shows how far this particular bar traveled along and away from it.
BNB and HYPE are different puzzles, since more of their variation sits outside F1 even before we single out October 10, so we looked at their F2 and F3 loadings:
| F2 | F3 | |
|---|---|---|
| BTC | ||
| ETH | ||
| SOL | ||
| BNB | ||
| HYPE | ||
| XRP | ||
| SUI |
Both axes involve BNB and HYPE, but in different ways: in the full-window fit F2 puts them together on one side against BTC and ETH, whereas F3 puts BNB and HYPE on opposite sides. Their shared F2 loading makes an "exchange-token factor" a tempting name, but and are almost tied, and the exact split between their axes depends on the fit. Before treating either axis as an explanation of why coins diverged during the selloff, we want to know whether it survives when we change the fitting window.
The factor-space panel
We refitted the correlation on a rolling 30-day window, or 180 four-hour bars, advancing one bar at a time, and plotted each coin's F1 and F2 loadings for every fit. That gives 138 positions per coin, with an ellipse drawn from each cloud's two-dimensional sample covariance; its half-axes are
where . These Gaussian reference ellipses are calculated from the rolling loadings rather than built to enclose the points, and because the windows overlap so heavily, their 95% contours are not coverage guarantees for the observed trail.
The F1 loadings stay close to across the rolling fits, whereas F2 wanders much more, especially for BNB and HYPE, because near-tied eigenvalues can make the solver rotate or swap the F2 and F3 axes as the window changes. The filled dots mark the last fitted window.
The common direction holds up reasonably well in this check, but the coordinates of the soft directions do not. That leaves us comfortable calling the October 10 move broadly shared, while making us reluctant to say a particular F2 loading explains a particular coin's loss; we would need a longer history and a way to align the soft plane across windows before using one of those ellipses to make a trading decision.
07 · Named factorsTrying to name the leftovers
The soft axes move around enough that their loadings alone do not give us a convincing story for the differences in the October 10 losses, so we tried asking whether observable characteristics account for any of what the market direction leaves behind. The Q-7 framework of Babayev and Aliyev (Crypto has Fundamentals) motivates that list, although this small public-tape exercise is not a replication of their seven-factor model.
We can test whether four characteristics built from exchange data add anything to each coin's four-hour return fit after F1.
What's computable from public tape
We can construct four backward-looking characteristics from the exchange tape without using a bar's future data:
| Factor | Definition (per coin, per 4h bar) |
|---|---|
| Size | of trailing 30-day average dollar volume, cross-section centred |
| Funding | mean of the hour-1 funding rates accrued during the bar, cross-section centred |
| Residual vol | EWMA std (15-day half-life) of the coin's return residualized on the equal-weight market (market beta, then the residual's vol) |
| Reversal | prior 4h log return |
Value needs network fundamentals that are absent from this exchange tape, while quality and turnover need additional history, including open interest, so this exercise stops at four Q-7-inspired proxies rather than attempting the full model.
The nested decomposition
For each coin, we use the part of the sample left after a 30-day warm-up, then fit the return series in stages:
Here is that coin's return vector, the common-direction score, and its four-characteristic design matrix. We fit the market term first and then add , reporting each stage's incremental drop in residual sum of squares as a share of the total; the order matters, because a characteristic correlated with the market only gets credit for what it adds after the market term. This is a time-series regression on a short subsample, so the percentages tell us about these particular proxies rather than settling anything about characteristic models in general.
| Coin | Market | Four proxies | Remaining |
|---|---|---|---|
| BTC | 73.8% | 0.26% | 25.9% |
| ETH | 80.1% | 0.89% | 19.0% |
| SOL | 87.2% | 0.63% | 12.2% |
| BNB | 66.7% | 1.13% | 32.1% |
| HYPE | 80.4% | 1.53% | 18.1% |
| XRP | 87.6% | 0.82% | 11.5% |
| SUI | 85.9% | 0.31% | 13.8% |
What the answer actually is
After the market term, the proxy block adds 0.26% to 1.53% of each coin's return variance, with HYPE at the top of that range, and the largest time-series correlation between a PCA score and one of these characteristics is . On the event bar, the largest fitted named contribution is in log-return units (BNB, through the size proxy), beside reported market components of to and SUI's excess drawdown of outside those fitted terms. The common move is large, but these four names do little to account for SUI's excess loss on that bar.
We had hoped "funding" or "size" might give one of the soft directions a name, but nothing in this short-window regression supports either label. That tells us very little about Q-7 itself, which studies return premia across many assets and much longer periods while this PCA describes co-movement every four hours. A characteristic can matter for one question and contribute very little to the other.
On these seven coins the four tape-derived proxies add little after F1, so we still have a measured difference between the coins without a defensible name for much of it; testing Q-7 itself would take the missing characteristics, a wider universe, and a longer history.
08 · ScopeWhere the evidence stops
The October 10 event is inside the fitting window, so its large projection onto F1 describes the event in a space that the event helped define; it is an in-sample result. There are also only 318 four-hour returns, seven chosen coins, and one venue, with different average correlations in September and October.
Within this sample, F1 carries 76.6% of total standardised variance and the October 10 selloff projects strongly onto it, which shows how the seven losses look like one event in the tape. It does not erase their differences: SUI's much larger raw loss is compatible with its high market share once its higher volatility is put back in, while the soft loadings and four characteristics we tested give us little basis for a firm account of the remaining event-bar gap.
Four-hour closes show when the shared move arrived and how the returns differed; they cannot tell us which positions were liquidated first or what set off the selling. They also cannot establish that stress itself compressed the market into one direction, or that a soft factor led the crash. For those questions we would want a fit made before the event, more than one stressed period, and finer data that can resolve which moves came first.
That is the public-data answer we can defend. What the same test would say about today's market, whether any useful hedge remains when all 21 pairs in this sample are positively correlated, and whether the unnamed differences survive at finer resolution are exactly the questions we would want to take up next. If you like the part of a problem where the neat first answer stops being enough, we would like to hear from you.
09 · CodeThe calculation in code
If the case for a shared October 10 move depends on a seven-by-seven
matrix, the matrix should be easy to check. The first listing fetches
the public candles and works through the correlation matrix, Jacobi
solver, and per-coin attribution using ureq and serde_json, with no
linear-algebra dependency. The second shows the rolling loading clouds,
but leaves jacobi_in_place as the rotation routine from the first
listing, so it is an extension sketch rather than a standalone
program; the Q-7-inspired regression in §07 is not included in these
snippets.
The eigensolver check
A numerical library would diagonalise this matrix in one call, but at the cyclic Jacobi method is short enough to inspect. It works through every off-diagonal pair , rotating that plane until becomes zero; the angle obeys , and the matrix update is , where is the identity apart from that two-dimensional rotation. We keep sweeping until the off-diagonal entries are negligible, applying the same rotations to so that its columns end up holding the eigenvectors.
Before printing a result, we check both and . If either check fails, the code stops; a plausible-looking spectrum from a broken rotation is worse than an obvious failure.
Core pipeline: fetch, correlation, Jacobi EVD, attribution
//! pca7: PCA + attribution on public Hyperliquid 4h candles, 7 perps.
//! Window: 2025-09-01 .. 2025-10-24 UTC (contains the 2025-10-10 mass
//! liquidation). HTTP/JSON via ureq and serde_json; EVD by cyclic Jacobi; no
//! linear-algebra crate, which is the point.
use ;
const COINS: = ;
const START_MS: i64 = 1_756_684_800_000; // 2025-09-01 00:00 UTC
const END_MS: i64 = 1_761_264_000_000; // 2025-10-24 00:00 UTC
The rolling-window re-fit and two-dimensional ellipse calculation from
§06 can go below that program. Calling main_addition(&r, &eig) at the
end of main prints the ellipse summaries:
Addition: rolling loadings + covariance ellipses
// ADDITION (extend the core): rolling 30-day loadings + 95% covariance ellipses.
// Needs the return matrix `r` and eigenpairs `eig` from the core listing.
const WIN: usize = 180; // 30 days of 4h bars
// Re-fit the correlation in a rolling window; signs aligned to the
// full-window fit so the factor identities don't flip between windows.
The eigensolver asserts reconstruction and orthonormality before printing the spectrum, because if we break a rotation we want the program to stop instead of handing us a plausible wrong answer. The matrix is small enough to inspect and the inputs are public, so you can take apart the calculation behind the market direction and the coin-level differences yourself.
Cite as
BibTeX@misc{tristan2026pca,
author = {Tristan Britt},
title = {{Many coins, one factor: PCA and attribution on public perp tape}},
howpublished = {Uriel Research},
note = {Notes from the desk, UR-RSCH-01},
year = {2026},
month = oct,
url = {https://uriel.xyz/research/pca-market-structure}
}